背景: 希望通过exchange partition的操作,将一个非分区表改造成分区表,但是在操作时候,发现exchange partition操作会报失败,同时会影响非分区表的写入。报错内容是ERROR 1736 (HY000): Tables have different definitions,之后往非分区表插入超过对应分区定义的数据时候,就会报错ERROR 1748 (HY000): Found a row not matching the given partition set。
操作日志如下,可稳定复现:
mysql>
mysql> CREATE TABLE `t1` (
-> `date` date NOT NULL ,
-> `name` varchar(10) NOT NULL,
-> UNIQUE KEY `uk_1` (`date`,`name`)
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
Query OK, 0 rows affected (0.51 sec)
mysql> CREATE TABLE `t1_partition` (
-> `date` date NOT NULL ,
-> `name` varchar(10) NOT NULL,
-> UNIQUE KEY `uk_1` (`date`,`name`)
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
-> PARTITION BY RANGE COLUMNS(`date`)
-> (PARTITION `p202307` VALUES LESS THAN ('2023-08-01'),
-> PARTITION `p202308` VALUES LESS THAN ('2023-09-01'),
-> PARTITION `p202309` VALUES LESS THAN ('2023-10-01'),
-> PARTITION `p202310` VALUES LESS THAN ('2023-11-01'),
-> PARTITION `p202311` VALUES LESS THAN ('2023-12-01'),
-> PARTITION `p202312` VALUES LESS THAN ('2024-01-01'),
-> PARTITION `pfuture` VALUES LESS THAN (MAXVALUE));
Query OK, 0 rows affected (0.52 sec)
mysql> insert into t1(date, name) values ("2023-07-02","0000"), ("2023-07-03","0000"), ("2023-07-04","0000"), ("2023-07-05","0000");
Query OK, 4 rows affected (0.01 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> alter table t1_partition exchange partition p202307 with table t1;
ERROR 1736 (HY000): Tables have different definitions
mysql> insert into t1(date, name) values ("2023-07-06","0000");
Query OK, 1 row affected (0.01 sec)
mysql> insert into t1(date, name) values ("2023-08-06","0000");
ERROR 1748 (HY000): Found a row not matching the given partition set
mysql> insert into t1(date, name) values ("2023-07-07","0000");
Query OK, 1 row affected (0.00 sec)
CREATE TABLE `t1` (
`date` date NOT NULL ,
`name` varchar(10) NOT NULL,
UNIQUE KEY `uk_1` (`date`,`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
CREATE TABLE `t1_partition` (
`date` date NOT NULL ,
`name` varchar(10) NOT NULL,
UNIQUE KEY `uk_1` (`date`,`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY RANGE COLUMNS(`date`)
(PARTITION `p202307` VALUES LESS THAN ('2023-08-01'),
PARTITION `p202308` VALUES LESS THAN ('2023-09-01'),
PARTITION `p202309` VALUES LESS THAN ('2023-10-01'),
PARTITION `p202310` VALUES LESS THAN ('2023-11-01'),
PARTITION `p202311` VALUES LESS THAN ('2023-12-01'),
PARTITION `p202312` VALUES LESS THAN ('2024-01-01'),
PARTITION `pfuture` VALUES LESS THAN (MAXVALUE));
insert into t1(date, name) values ("2023-07-02","0000"), ("2023-07-03","0000"), ("2023-07-04","0000"), ("2023-07-05","0000");
-- 此处报错了
alter table t1_partition exchange partition p202307 with table t1;
insert into t1(date, name) values ("2023-07-06","0000");
insert into t1(date, name) values ("2023-08-06","0000");
-- 以下没有执行
rename table t1 to t1_bak;
rename table t1_partition to t1;
CREATE PLACEMENT POLICY rule1 FOLLOWERS=4;
CREATE TABLE `t1` (
`date` date NOT NULL ,
`name` varchar(10) NOT NULL,
UNIQUE KEY `uk_1` (`date`,`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin PLACEMENT POLICY=`rule1`;
CREATE TABLE `t1_partition` (
`date` date NOT NULL ,
`name` varchar(10) NOT NULL,
UNIQUE KEY `uk_1` (`date`,`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin PLACEMENT POLICY=`rule1`
PARTITION BY RANGE COLUMNS(`date`)
(PARTITION `p202307` VALUES LESS THAN ('2023-08-01'),
PARTITION `p202308` VALUES LESS THAN ('2023-09-01'),
PARTITION `p202309` VALUES LESS THAN ('2023-10-01'),
PARTITION `p202310` VALUES LESS THAN ('2023-11-01'),
PARTITION `p202311` VALUES LESS THAN ('2023-12-01'),
PARTITION `p202312` VALUES LESS THAN ('2024-01-01'),
PARTITION `pfuture` VALUES LESS THAN (MAXVALUE));
insert into t1(date, name) values ("2023-07-02","0000"), ("2023-07-03","0000"), ("2023-07-04","0000"), ("2023-07-05","0000");
-- 此处报错了
alter table t1_partition exchange partition p202307 with table t1;
insert into t1(date, name) values ("2023-07-06","0000");
insert into t1(date, name) values ("2023-08-06","0000");