在表和分区间交换数据
mysql5.6开始支持alter table..exchange partition语法,该语句允许分区或子分区中的数据与另一个非分区的表中的数据进行交换,如果非分区表中的数据为空,那么相当于将分区中的数据移动到非分区表中,若分区表中的数据为空,则相当于将外部表中的数据导入到分区中,即,哪边不为空,哪边就是被移出的,哪边为空,哪边就是装数据的。
要使用alter table…exchange partition语句,必须满足下面的条件:
A:要交换的表需要和分区表有着完全相同的表结构,但是要交换的表不能含有分区
B:在非分区表中的数据必须在交换的分区定义内(即要对上分区列的定义范围)
C:被交换的表中不能含有外键,或者其他的表含有对该表的外键引用
D:用户除了需要alter,insert,create权限外,还需要drop权限,此外,还有两个小的细节需要注意:
a:使用该语句时,不会触发交换表和被交换表上的触发器
b:auto_increment列将被重置
示例:
创建分区表:
mysql> create table e(
-> id int not null,
-> fname varchar(30),
-> lname varchar(30))
-> partition by range(id)(
-> partition p0 values less than(50),
-> partition p1 values less than(100),
-> partition p2 values less than(150),
-> partition p3 values less than maxvalue);
Query OK, 0 rows affected (1.20 sec)
插入数据:
mysql> insert into e values(1669,‘jim‘,‘smith‘),(337,‘mary‘,‘jones‘),(16,‘frank‘,‘withe‘),(2005,‘linda‘,‘black‘);
Query OK, 4 rows affected (0.03 sec)
Records: 4 Duplicates: 0 Warnings: 0
创建非分区表:
mysql> create table e2 like e;
Query OK, 0 rows affected (0.15 sec)
mysql> alter table e2 remove partitioning;
Query OK, 0 rows affected (0.30 sec)
Records: 0 Duplicates: 0 Warnings: 0
使用下面的语句观察分区表中的数据:
mysql> select partition_name,table_rows from information_schema.partitions where table_name=‘e‘;
+----------------+------------+
| partition_name | table_rows |
+----------------+------------+
| p0 | 1 |
| p1 | 0 |
| p2 | 0 |
| p3 | 3 |
+----------------+------------+
4 rows in set (0.16 sec)
使用下面的语句把表e的分区p0中的数据移动到e2表中:
mysql> alter table e exchange partition p0 with table e2;
Query OK, 0 rows affected (0.01 sec)
再次查看p0分区的数据行数:
mysql> select partition_name,table_rows from information_schema.partitions where table_name=‘e‘;
+----------------+------------+
| partition_name | table_rows |
+----------------+------------+
| p0 | 0 |
| p1 | 0 |
| p2 | 0 |
| p3 | 3 |
+----------------+------------+
发现p0分区的数据行数为0了,这时查看e2表中的数据:
mysql> select * from e2;
+----+-------+-------+
| id | fname | lname |
+----+-------+-------+
| 16 | frank | withe |
+----+-------+-------+
1 row in set (0.00 sec)
发现p0分区中的数据被转移到了e2表中,再次执行交换语句:
mysql> alter table e exchange partition p0 with table e2;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from e2;
Empty set (0.00 sec)
mysql> select * from e;
+------+-------+-------+
| id | fname | lname |
+------+-------+-------+
| 16 | frank | withe |
| 1669 | jim | smith |
| 337 | mary | jones |
| 2005 | linda | black |
+------+-------+-------+
4 rows in set (0.00 sec)
发现表e2数据又被转移到了分区表e的p0分区中,注意,再把数据转回去的时候,可能select partition_name,table_rows from information_schema.partitions where table_name=‘e‘;这句无法实时查出在分区中行数的变化。
注:本帖参考《innodb技术内幕 innodb存储引擎第二版》