Rechercher dans le manuel MySQL
23.3.3 Exchanging Partitions and Subpartitions with Tables
In MySQL 8.0, it is possible to exchange a table
partition or subpartition with a table using ALTER
TABLE
, where
pt
EXCHANGE PARTITION
p
WITH TABLE
nt
pt
is the partitioned table and
p
is the partition or subpartition of
pt
to be exchanged with unpartitioned
table nt
, provided that the following
statements are true:
Table
nt
is not itself partitioned.Table
nt
is not a temporary table.The structures of tables
pt
andnt
are otherwise identical.Table
nt
contains no foreign key references, and no other table has any foreign keys that refer tont
.There are no rows in
nt
that lie outside the boundaries of the partition definition forp
. This condition does not apply ifWITHOUT VALIDATION
is used.For
InnoDB
tables, both tables use the same row format. To determine the row format of anInnoDB
table, queryINFORMATION_SCHEMA.INNODB_TABLES
.nt
does not have any partitions that use theDATA DIRECTORY
option. This restriction is lifted forInnoDB
tables in MySQL 8.0.14 and later.
In addition to the ALTER
,
INSERT
, and
CREATE
privileges usually
required for ALTER TABLE
statements, you must have the
DROP
privilege to perform
ALTER TABLE ...
EXCHANGE PARTITION
.
You should also be aware of the following effects of
ALTER TABLE ...
EXCHANGE PARTITION
:
Executing
ALTER TABLE ... EXCHANGE PARTITION
does not invoke any triggers on either the partitioned table or the table to be exchanged.Any
AUTO_INCREMENT
columns in the exchanged table are reset.The
IGNORE
keyword has no effect when used withALTER TABLE ... EXCHANGE PARTITION
.
The syntax for
ALTER TABLE ...
EXCHANGE PARTITION
is shown here, where
pt
is the partitioned table,
p
is the partition (or subpartition)
to be exchanged, and nt
is the
nonpartitioned table to be exchanged with
p
:
Optionally, you can append WITH VALIDATION
or
WITHOUT VALIDATION
. When WITHOUT
VALIDATION
is specified, the
ALTER TABLE ...
EXCHANGE PARTITION
operation does not perform any
row-by-row validation when exchanging a partition a
nonpartitioned table, allowing database administrators to assume
responsibility for ensuring that rows are within the boundaries
of the partition definition. WITH VALIDATION
is the default.
One and only one partition or subpartition may be exchanged with
one and only one nonpartitioned table in a single
ALTER TABLE
EXCHANGE PARTITION
statement. To exchange multiple
partitions or subpartitions, use multiple
ALTER TABLE
EXCHANGE PARTITION
statements. EXCHANGE
PARTITION
may not be combined with other
ALTER TABLE
options. The
partitioning and (if applicable) subpartitioning used by the
partitioned table may be of any type or types supported in MySQL
8.0.
Exchanging a Partition with a Nonpartitioned Table
Suppose that a partitioned table e
has been
created and populated using the following SQL statements:
- )
- );
- (1669, "Jim", "Smith"),
- (337, "Mary", "Jones"),
- (16, "Frank", "White"),
- (2005, "Linda", "Black");
Now we create a nonpartitioned copy of e
named e2
. This can be done using the
mysql client as shown here:
- Query OK, 0 rows affected (0.04 sec)
- Query OK, 0 rows affected (0.07 sec)
You can see which partitions in table e
contain rows by querying the
INFORMATION_SCHEMA.PARTITIONS
table, like this:
- FROM INFORMATION_SCHEMA.PARTITIONS
- +----------------+------------+
- | PARTITION_NAME | TABLE_ROWS |
- +----------------+------------+
- | p0 | 1 |
- | p1 | 0 |
- | p2 | 0 |
- | p3 | 3 |
- +----------------+------------+
For partitioned InnoDB
tables, the row
count given in the TABLE_ROWS
column of the
INFORMATION_SCHEMA.PARTITIONS
table is only an estimated value used in SQL optimization, and
is not always exact.
To exchange partition p0
in table
e
with table e2
, you can
use
ALTER
TABLE
, as shown here:
More precisely, the statement just issued causes any rows found
in the partition to be swapped with those found in the table.
You can observe how this has happened by querying the
INFORMATION_SCHEMA.PARTITIONS
table, as before. The table row that was previously found in
partition p0
is no longer present:
- FROM INFORMATION_SCHEMA.PARTITIONS
- +----------------+------------+
- | PARTITION_NAME | TABLE_ROWS |
- +----------------+------------+
- | p0 | 0 |
- | p1 | 0 |
- | p2 | 0 |
- | p3 | 3 |
- +----------------+------------+
If you query table e2
, you can see that the
“missing” row can now be found there:
- +----+-------+-------+
- | id | fname | lname |
- +----+-------+-------+
- | 16 | Frank | White |
- +----+-------+-------+
The table to be exchanged with the partition does not
necessarily have to be empty. To demonstrate this, we first
insert a new row into table e
, making sure
that this row is stored in partition p0
by
choosing an id
column value that is less than
50, and verifying this afterward by querying the
PARTITIONS
table:
- Query OK, 1 row affected (0.05 sec)
- FROM INFORMATION_SCHEMA.PARTITIONS
- +----------------+------------+
- | PARTITION_NAME | TABLE_ROWS |
- +----------------+------------+
- | p0 | 1 |
- | p1 | 0 |
- | p2 | 0 |
- | p3 | 3 |
- +----------------+------------+
Now we once again exchange partition p0
with
table e2
using the same
ALTER
TABLE
statement as previously:
The output of the following queries shows that the table row
that was stored in partition p0
and the table
row that was stored in table e2
, prior to
issuing the
ALTER
TABLE
statement, have now switched places:
- +------+-------+-------+
- | id | fname | lname |
- +------+-------+-------+
- | 16 | Frank | White |
- | 1669 | Jim | Smith |
- | 337 | Mary | Jones |
- | 2005 | Linda | Black |
- +------+-------+-------+
- FROM INFORMATION_SCHEMA.PARTITIONS
- +----------------+------------+
- | PARTITION_NAME | TABLE_ROWS |
- +----------------+------------+
- | p0 | 1 |
- | p1 | 0 |
- | p2 | 0 |
- | p3 | 3 |
- +----------------+------------+
- +----+---------+-------+
- | id | fname | lname |
- +----+---------+-------+
- | 41 | Michael | Green |
- +----+---------+-------+
Nonmatching Rows
You should keep in mind that any rows found in the
nonpartitioned table prior to issuing the
ALTER TABLE ...
EXCHANGE PARTITION
statement must meet the conditions
required for them to be stored in the target partition;
otherwise, the statement fails. To see how this occurs, first
insert a row into e2
that is outside the
boundaries of the partition definition for partition
p0
of table e
. For
example, insert a row with an id
column value
that is too large; then, try to exchange the table with the
partition again:
- Query OK, 1 row affected (0.08 sec)
Only the WITHOUT VALIDATION
option would
permit this operation to succeed:
- Query OK, 0 rows affected (0.02 sec)
When a partition is exchanged with a table that contains rows
that do not match the partition definition, it is the
responsibility of the database administrator to fix the
non-matching rows, which can be performed using
REPAIR TABLE
or
ALTER
TABLE ... REPAIR PARTITION
.
Exchanging Partitions Without Row-By-Row Validation
To avoid time consuming validation when exchanging a partition
with a table that has many rows, it is possible to skip the
row-by-row validation step by appending WITHOUT
VALIDATION
to the
ALTER
TABLE ... EXCHANGE PARTITION
statement.
The following example compares the difference between execution
times when exchanging a partition with a nonpartitioned table,
with and without validation. The partitioned table (table
e
) contains two partitions of 1 million rows
each. The rows in p0 of table e are removed and p0 is exchanged
with a nonpartitioned table of 1 million rows. The WITH
VALIDATION
operation takes 0.74 seconds. By
comparison, the WITHOUT VALIDATION
operation
takes 0.01 seconds.
- # Create a partitioned table with 1 million rows in each partition
- )
- );
- +----------+
- | 2000000 |
- +----------+
- # View the rows in each partition
- +----------------+-------------+
- | PARTITION_NAME | TABLE_ROWS |
- +----------------+-------------+
- | p0 | 1000000 |
- | p1 | 1000000 |
- +----------------+-------------+
- # Create a nonpartitioned table of the same structure and populate it with 1 million rows
- );
- +----------+
- +----------+
- | 1000000 |
- +----------+
- # Create another nonpartitioned table of the same structure and populate it with 1 million rows
- );
- +----------+
- +----------+
- | 1000000 |
- +----------+
- # Drop the rows from p0 of table e
- Query OK, 1000000 rows affected (5.55 sec)
- # Confirm that there are no rows in partition p0
- +----------------+------------+
- | PARTITION_NAME | TABLE_ROWS |
- +----------------+------------+
- | p0 | 0 |
- | p1 | 1000000 |
- +----------------+------------+
- # Exchange partition p0 of table e with the table e2 'WITH VALIDATION'
- Query OK, 0 rows affected (0.74 sec)
- # Confirm that the partition was exchanged with table e2
- +----------------+------------+
- | PARTITION_NAME | TABLE_ROWS |
- +----------------+------------+
- | p0 | 1000000 |
- | p1 | 1000000 |
- +----------------+------------+
- # Once again, drop the rows from p0 of table e
- Query OK, 1000000 rows affected (5.55 sec)
- # Confirm that there are no rows in partition p0
- +----------------+------------+
- | PARTITION_NAME | TABLE_ROWS |
- +----------------+------------+
- | p0 | 0 |
- | p1 | 1000000 |
- +----------------+------------+
- # Exchange partition p0 of table e with the table e3 'WITHOUT VALIDATION'
- Query OK, 0 rows affected (0.01 sec)
- # Confirm that the partition was exchanged with table e3
- +----------------+------------+
- | PARTITION_NAME | TABLE_ROWS |
- +----------------+------------+
- | p0 | 1000000 |
- | p1 | 1000000 |
- +----------------+------------+
If a partition is exchanged with a table that contains rows that
do not match the partition definition, it is the responsibility
of the database administrator to fix the non-matching rows,
which can be performed using REPAIR
TABLE
or
ALTER
TABLE ... REPAIR PARTITION
.
Exchanging a Subpartition with a Nonpartitioned Table
You can also exchange a subpartition of a subpartitioned table
(see Section 23.2.6, “Subpartitioning”) with a
nonpartitioned table using an
ALTER TABLE ...
EXCHANGE PARTITION
statement. In the following
example, we first create a table es
that is
partitioned by RANGE
and subpartitioned by
KEY
, populate this table as we did table
e
, and then create an empty, nonpartitioned
copy es2
of the table, as shown here:
- -> )
- -> SUBPARTITIONS 2 (
- -> );
- Query OK, 0 rows affected (2.76 sec)
- -> (1669, "Jim", "Smith"),
- -> (337, "Mary", "Jones"),
- -> (16, "Frank", "White"),
- -> (2005, "Linda", "Black");
- Query OK, 4 rows affected (0.04 sec)
- Query OK, 0 rows affected (1.27 sec)
- Query OK, 0 rows affected (0.70 sec)
Although we did not explicitly name any of the subpartitions
when creating table es
, we can obtain
generated names for these by including the
SUBPARTITION_NAME
column of the
PARTITIONS
table from
INFORMATION_SCHEMA
when selecting from that
table, as shown here:
- -> FROM INFORMATION_SCHEMA.PARTITIONS
- +----------------+-------------------+------------+
- | PARTITION_NAME | SUBPARTITION_NAME | TABLE_ROWS |
- +----------------+-------------------+------------+
- | p0 | p0sp0 | 1 |
- | p0 | p0sp1 | 0 |
- | p1 | p1sp0 | 0 |
- | p1 | p1sp1 | 0 |
- | p2 | p2sp0 | 0 |
- | p2 | p2sp1 | 0 |
- | p3 | p3sp0 | 3 |
- | p3 | p3sp1 | 0 |
- +----------------+-------------------+------------+
The following
ALTER
TABLE
statement exchanges subpartition
p3sp0
in table es
with the
nonpartitioned table es2
:
You can verify that the rows were exchanged by issuing the following queries:
- -> FROM INFORMATION_SCHEMA.PARTITIONS
- +----------------+-------------------+------------+
- | PARTITION_NAME | SUBPARTITION_NAME | TABLE_ROWS |
- +----------------+-------------------+------------+
- | p0 | p0sp0 | 1 |
- | p0 | p0sp1 | 0 |
- | p1 | p1sp0 | 0 |
- | p1 | p1sp1 | 0 |
- | p2 | p2sp0 | 0 |
- | p2 | p2sp1 | 0 |
- | p3 | p3sp0 | 0 |
- | p3 | p3sp1 | 0 |
- +----------------+-------------------+------------+
- +------+-------+-------+
- | id | fname | lname |
- +------+-------+-------+
- | 1669 | Jim | Smith |
- | 337 | Mary | Jones |
- | 2005 | Linda | Black |
- +------+-------+-------+
If a table is subpartitioned, you can exchange only a subpartition of the table—not an entire partition—with an unpartitioned table, as shown here:
Table structures are compared in a strict fashion; the number, order, names, and types of columns and indexes of the partitioned table and the nonpartitioned table must match exactly. In addition, both tables must use the same storage engine:
- Query OK, 0 rows affected (1.31 sec)
- Query OK, 0 rows affected (0.53 sec)
- *************************** 1. row ***************************
- Table: es3
- Query OK, 0 rows affected (0.15 sec)
Document created the 26/06/2006, last modified the 26/10/2018
Source of the printed document:https://www.gaudry.be/en/mysql-rf-partitioning-management-exchange.html
The infobrol is a personal site whose content is my sole responsibility. The text is available under CreativeCommons license (BY-NC-SA). More info on the terms of use and the author.
References
These references and links indicate documents consulted during the writing of this page, or which may provide additional information, but the authors of these sources can not be held responsible for the content of this page.
The author This site is solely responsible for the way in which the various concepts, and the freedoms that are taken with the reference works, are presented here. Remember that you must cross multiple source information to reduce the risk of errors.