[MDEV-13157] Specifying DATA DIRECTORY in tables leads to failing EXCHANGE PARTITION Created: 2017-06-22  Updated: 2020-08-25  Resolved: 2017-09-18

Status: Closed
Project: MariaDB Server
Component/s: Partitioning
Affects Version/s: 10.1, 10.1.24, 10.2
Fix Version/s: 10.1.27, 10.2.9

Type: Bug Priority: Major
Reporter: Chris Calender (Inactive) Assignee: Sergei Golubchik
Resolution: Fixed Votes: 1
Labels: upstream
Environment:

Windows, Linux


Issue Links:
Relates
relates to MDEV-14611 ALTER TABLE EXCHANGE PARTITION does n... Closed

 Description   

Inconsistency with slashes when specifying DATA DIRECTORY in tables with and without partitions leads to failing EXCHANGE PARTITION

1. Create directory to be used (with correct permissions), in this example, C:/mariadb

2. Test case:

use test;
 
CREATE TABLE t1 (
id1 INT(11) NOT NULL,
id2 INT(11) NOT NULL
) ENGINE=INNODB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY RANGE (id2)
(PARTITION p0 VALUES LESS THAN (6) DATA DIRECTORY = 'C:/mariadb' ENGINE = InnoDB,
PARTITION p1 VALUES LESS THAN (11) DATA DIRECTORY = 'C:/mariadb' ENGINE = InnoDB,
PARTITION p2 VALUES LESS THAN (16) DATA DIRECTORY = 'C:/mariadb' ENGINE = InnoDB,
PARTITION p3 VALUES LESS THAN MAXVALUE DATA DIRECTORY = 'C:/mariadb' ENGINE = InnoDB) */;
 
CREATE TABLE t2 (
id1 INT(11) NOT NULL,
id2 INT(11) NOT NULL
) ENGINE=INNODB DEFAULT CHARSET=latin1 DATA DIRECTORY='C:/mariadb';
 
ALTER TABLE t1 EXCHANGE PARTITION p0 WITH TABLE t2;

ERROR 1731 (HY000): Non matching attribute 'DATA DIRECTORY' between partition and table

If we examine the SHOW CREATE TABLE outputs, we see that in t2, DATA DIRECTORY appended an extra slash at the end, whereas that of t1 did not:

mysql> show create table t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `id1` int(11) NOT NULL,
  `id2` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY RANGE (id2)
(PARTITION p0 VALUES LESS THAN (6) DATA DIRECTORY = 'C:/mariadb' ENGINE = InnoDB,
 PARTITION p1 VALUES LESS THAN (11) DATA DIRECTORY = 'C:/mariadb' ENGINE = InnoDB,
 PARTITION p2 VALUES LESS THAN (16) DATA DIRECTORY = 'C:/mariadb' ENGINE = InnoDB,
 PARTITION p3 VALUES LESS THAN MAXVALUE DATA DIRECTORY = 'C:/mariadb' ENGINE = InnoDB) */
1 row in set (0.01 sec)
 
mysql> show create table t2\G
*************************** 1. row ***************************
       Table: t2
Create Table: CREATE TABLE `t2` (
  `id1` int(11) NOT NULL,
  `id2` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 DATA DIRECTORY='C:/mariadb/'
1 row in set (0.00 sec)

In the above, note how t2 appended a slash to the end of the value for DATA DIRECTORY, but t1 did not. Both were created without the extra slash.

If you do not specify DATA DIRECTORY, this all works fine:

drop schema test;
create schema test;
use test;
 
CREATE TABLE t1 (
id1 INT(11) NOT NULL,
id2 INT(11) NOT NULL
) ENGINE=INNODB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY RANGE (id2)
(PARTITION p0 VALUES LESS THAN (6) ENGINE = InnoDB,
PARTITION p1 VALUES LESS THAN (11) ENGINE = InnoDB,
PARTITION p2 VALUES LESS THAN (16) ENGINE = InnoDB,
PARTITION p3 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */;
 
CREATE TABLE t2 (
id1 INT(11) NOT NULL,
id2 INT(11) NOT NULL
) ENGINE=INNODB DEFAULT CHARSET=latin1;
 
mysql> ALTER TABLE t1 EXCHANGE PARTITION p0 WITH TABLE t2;
Query OK, 0 rows affected (0.04 sec)

You cannot ALTER t2 to remove the extra slash:

mysql> ALTER TABLE t2 DATA DIRECTORY='C:/mariadb';
Query OK, 0 rows affected, 1 warning (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 1
 
mysql> show warnings;
+---------+------+---------------------------------+
| Level   | Code | Message                         |
+---------+------+---------------------------------+
| Warning | 1618 | <DATA DIRECTORY> option ignored |
+---------+------+---------------------------------+
1 row in set (0.00 sec)

Similarly, you cannot ALTER t1 to add the extra slashes:

CREATE TABLE t1 (
id1 INT(11) NOT NULL,
id2 INT(11) NOT NULL
) ENGINE=INNODB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY RANGE (id2)
(PARTITION p0 VALUES LESS THAN (6) DATA DIRECTORY = 'C:/mariadb/' ENGINE = InnoDB,
PARTITION p1 VALUES LESS THAN (11) DATA DIRECTORY = 'C:/mariadb/' ENGINE = InnoDB,
PARTITION p2 VALUES LESS THAN (16) DATA DIRECTORY = 'C:/mariadb/' ENGINE = InnoDB,
PARTITION p3 VALUES LESS THAN MAXVALUE DATA DIRECTORY = 'C:/mariadb/' ENGINE = InnoDB) */;
 
mysql> show create table t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `id1` int(11) NOT NULL,
  `id2` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY RANGE (id2)
(PARTITION p0 VALUES LESS THAN (6) DATA DIRECTORY = 'C:/mariadb' ENGINE = InnoDB,
 PARTITION p1 VALUES LESS THAN (11) DATA DIRECTORY = 'C:/mariadb' ENGINE = InnoDB,
 PARTITION p2 VALUES LESS THAN (16) DATA DIRECTORY = 'C:/mariadb' ENGINE = InnoDB,
 PARTITION p3 VALUES LESS THAN MAXVALUE DATA DIRECTORY = 'C:/mariadb' ENGINE = InnoDB) */
1 row in set (0.01 sec)

Note it ignores/removes them.



 Comments   
Comment by Alice Sherepa [ 2017-06-23 ]

Reproduced on 10.2.7-debug, Ubuntu 16.04

CREATE TABLE t1 (i INT) /*! DATA DIRECTORY='/data'*/;
CREATE TABLE t2 (i INT) DATA DIRECTORY='/data';
CREATE TABLE t3 (i INT) 
/*! PARTITION BY RANGE (i) (PARTITION p0 VALUES LESS THAN (6) DATA DIRECTORY = '/data')*/;

*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `i` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 DATA DIRECTORY='/data/'
1 row in set (0.00 sec)
 
*************************** 1. row ***************************
       Table: t2
Create Table: CREATE TABLE `t2` (
  `i` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 DATA DIRECTORY='/data/'
1 row in set (0.01 sec)
 
*************************** 1. row ***************************
       Table: t3
Create Table: CREATE TABLE `t3` (
  `i` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
 PARTITION BY RANGE (i)
(PARTITION p0 VALUES LESS THAN (6) DATA DIRECTORY = '/data' ENGINE = InnoDB)
1 row in set (0.00 sec)

Comment by Elena Stepanova [ 2017-06-23 ]

I don't think trailing slashes make any difference here. Let's see an example where they do match:

DROP TABLE IF EXISTS t1, t2;
CREATE TABLE t1 ( id2 INT(11) NOT NULL ) ENGINE=INNODB
/*!50100 PARTITION BY RANGE (id2) (
  PARTITION p0 VALUES LESS THAN (6) DATA DIRECTORY = '/tmp/mdev13157/' ENGINE = InnoDB, 
  PARTITION pmax VALUES LESS THAN MAXVALUE DATA DIRECTORY = '/tmp/mdev13157/' ENGINE = InnoDB
) */;
CREATE TABLE t2 ( id2 INT(11) NOT NULL ) ENGINE=INNODB DATA DIRECTORY='/tmp/mdev13157/';
SHOW CREATE TABLE t1 \G
SHOW CREATE TABLE t2 \G

MySQL [test]> SHOW CREATE TABLE t1 \G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `id2` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY RANGE (id2)
(PARTITION p0 VALUES LESS THAN (6) DATA DIRECTORY = '/tmp/mdev13157/' ENGINE = InnoDB,
 PARTITION pmax VALUES LESS THAN MAXVALUE DATA DIRECTORY = '/tmp/mdev13157/' ENGINE = InnoDB) */
1 row in set (0.00 sec)
 
MySQL [test]> SHOW CREATE TABLE t2 \G
*************************** 1. row ***************************
       Table: t2
Create Table: CREATE TABLE `t2` (
  `id2` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 DATA DIRECTORY='/tmp/mdev13157/'
1 row in set (0.00 sec)

So, all of them have the trailing slash there. Still, you can't do EXCHANGE:

MySQL [test]> ALTER TABLE t1 EXCHANGE PARTITION p0 WITH TABLE t2;
ERROR 1731 (HY000): Non matching attribute 'DATA DIRECTORY' between partition and table
 
MySQL [test]> SELECT @@version, @@version_comment;
+--------------+---------------------+
| @@version    | @@version_comment   |
+--------------+---------------------+
| 5.7.18-debug | Source distribution |
+--------------+---------------------+
1 row in set (0.00 sec)

There is an upstream bug about it, https://bugs.mysql.com/bug.php?id=73084 . It has been categorized as feature request.

Comment by Elena Stepanova [ 2017-06-23 ]

I'm setting Fix Version to 10.1 for now, but if it's impossibly/too risky to do in 10.1, apparently 10.2 should be enough.

Generated at Thu Feb 08 08:03:21 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.