Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ddl: Coalesce partition | tidb-test=pr/2111 #42476

Merged
merged 17 commits into from
Apr 17, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
260 changes: 255 additions & 5 deletions ddl/db_partition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3462,8 +3462,9 @@ func TestPartitionErrorCode(t *testing.T) {
)
partition by hash(store_id)
partitions 4;`)
tk.MustGetDBError("alter table employees add partition partitions 8;", dbterror.ErrUnsupportedAddPartition)
tk.MustGetDBError("alter table employees add partition (partition p5 values less than (42));", dbterror.ErrUnsupportedAddPartition)
tk.MustExec("alter table employees add partition partitions 8")
tk.MustGetDBError("alter table employees add partition (partition pNew values less than (42))", ast.ErrPartitionWrongValues)
tk.MustGetDBError("alter table employees add partition (partition pNew values in (42))", ast.ErrPartitionWrongValues)

// coalesce partition
tk.MustExec(`create table clients (
Expand All @@ -3473,8 +3474,8 @@ func TestPartitionErrorCode(t *testing.T) {
signed date
)
partition by hash( month(signed) )
partitions 12;`)
tk.MustGetDBError("alter table clients coalesce partition 4;", dbterror.ErrUnsupportedCoalescePartition)
partitions 12`)
tk.MustContainErrMsg("alter table clients coalesce partition 12", "[ddl:1508]Cannot remove all partitions, use DROP TABLE instead")

tk.MustExec(`create table t_part (a int key)
partition by range(a) (
Expand Down Expand Up @@ -3505,6 +3506,255 @@ func TestPartitionErrorCode(t *testing.T) {
tk1.MustExec("commit")
}

func TestCoalescePartition(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
// coalesce partition
tk.MustExec(`create schema coalescePart`)
tk.MustExec(`use coalescePart`)
tk.MustExec(`create table t (
id int,
fname varchar(30),
lname varchar(30),
signed date
)
partition by hash( month(signed) )
partitions 12`)
for i := 0; i < 200; i++ {
tk.MustExec(`insert into t values (?, "Joe", "Doe", from_days(738974 + ?))`, i, i*3)
}
tk.MustExec("alter table t coalesce partition 4")
tk.MustQuery(`show create table t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `id` int(11) DEFAULT NULL,\n" +
" `fname` varchar(30) DEFAULT NULL,\n" +
" `lname` varchar(30) DEFAULT NULL,\n" +
" `signed` date DEFAULT NULL\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY HASH (MONTH(`signed`)) PARTITIONS 8"))
tk.MustExec(`analyze table t`)
tk.MustQuery(`select partition_name, table_rows from information_schema.partitions where table_name = 't' and table_schema = 'coalescePart'`).Sort().Check(testkit.Rows(""+
crazycs520 marked this conversation as resolved.
Show resolved Hide resolved
"p0 20",
"p1 30",
"p2 30",
"p3 27",
"p4 31",
"p5 20",
"p6 20",
"p7 22"))
tk.MustExec(`drop table t`)
tk.MustExec(`create table t (
id int,
fname varchar(30),
lname varchar(30),
signed date
)
partition by key(signed,fname)
partitions 12`)
for i := 0; i < 200; i++ {
tk.MustExec(`insert into t values (?, "Joe", "Doe", from_days(738974 + ?))`, i, i*3)
}
tk.MustExec("alter table t coalesce partition 4")
tk.MustQuery(`show create table t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `id` int(11) DEFAULT NULL,\n" +
" `fname` varchar(30) DEFAULT NULL,\n" +
" `lname` varchar(30) DEFAULT NULL,\n" +
" `signed` date DEFAULT NULL\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY KEY (`signed`,`fname`) PARTITIONS 8"))
tk.MustExec(`analyze table t`)
tk.MustQuery(`select partition_name, table_rows from information_schema.partitions where table_name = 't' and table_schema = 'coalescePart'`).Sort().Check(testkit.Rows(""+
crazycs520 marked this conversation as resolved.
Show resolved Hide resolved
"p0 26",
"p1 28",
"p2 22",
"p3 24",
"p4 30",
"p5 27",
"p6 22",
"p7 21"))
}

func TestAddHashPartition(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
// add partition
tk.MustExec("create database addHash")
tk.MustExec("use addHash")
tk.MustExec(`create table t (
id int not null,
fname varchar(30),
lname varchar(30),
hired date not null default '1970-01-01',
separated date,
job_code int,
store_id int
)
partition by hash(store_id)
partitions 4`)
// TiDB does not support system versioned tables / SYSTEM_TIME
// also the error is slightly wrong with 'VALUES HISTORY'
// instead of just 'HISTORY'
tk.MustContainErrMsg(`alter table t add partition (partition pHist history)`, "[ddl:1480]Only SYSTEM_TIME PARTITIONING can use VALUES HISTORY in partition definition")
tk.MustContainErrMsg(`alter table t add partition (partition pList values in (22))`, "[ddl:1480]Only LIST PARTITIONING can use VALUES IN in partition definition")
tk.MustContainErrMsg(`alter table t add partition (partition pRange values less than (22))`, "[ddl:1480]Only RANGE PARTITIONING can use VALUES LESS THAN in partition definition")
tk.MustExec(`insert into t values (20, "Joe", "Doe", '2020-01-05', null, 1,1), (21, "Jane", "Doe", '2021-07-05', null, 2,1)`)
tk.MustExec("alter table t add partition partitions 8")
tk.MustQuery(`show create table t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `id` int(11) NOT NULL,\n" +
" `fname` varchar(30) DEFAULT NULL,\n" +
" `lname` varchar(30) DEFAULT NULL,\n" +
" `hired` date NOT NULL DEFAULT '1970-01-01',\n" +
" `separated` date DEFAULT NULL,\n" +
" `job_code` int(11) DEFAULT NULL,\n" +
" `store_id` int(11) DEFAULT NULL\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY HASH (`store_id`) PARTITIONS 12"))
tk.MustContainErrMsg(`alter table t coalesce partition 0`,
"[ddl:1515]At least one partition must be coalesced")
tk.MustContainErrMsg(`alter table t coalesce partition 12`,
"[ddl:1508]Cannot remove all partitions, use DROP TABLE instead")
tk.MustExec(`create placement policy tworeplicas followers=1`)
tk.MustExec(`create placement policy threereplicas followers=2`)
tk.MustExec(`create placement policy fourreplicas followers=3`)
tk.MustExec("alter table t add partition (partition p13 comment 'p13' placement policy tworeplicas, partition p14 comment 'p14' placement policy threereplicas, partition p15 comment 'p15' placement policy fourreplicas)")
tk.MustQuery(`show create table t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `id` int(11) NOT NULL,\n" +
" `fname` varchar(30) DEFAULT NULL,\n" +
" `lname` varchar(30) DEFAULT NULL,\n" +
" `hired` date NOT NULL DEFAULT '1970-01-01',\n" +
" `separated` date DEFAULT NULL,\n" +
" `job_code` int(11) DEFAULT NULL,\n" +
" `store_id` int(11) DEFAULT NULL\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY HASH (`store_id`)\n" +
"(PARTITION `p0`,\n" +
" PARTITION `p1`,\n" +
" PARTITION `p2`,\n" +
" PARTITION `p3`,\n" +
" PARTITION `p4`,\n" +
" PARTITION `p5`,\n" +
" PARTITION `p6`,\n" +
" PARTITION `p7`,\n" +
" PARTITION `p8`,\n" +
" PARTITION `p9`,\n" +
" PARTITION `p10`,\n" +
" PARTITION `p11`,\n" +
" PARTITION `p13` COMMENT 'p13' /*T![placement] PLACEMENT POLICY=`tworeplicas` */,\n" +
" PARTITION `p14` COMMENT 'p14' /*T![placement] PLACEMENT POLICY=`threereplicas` */,\n" +
" PARTITION `p15` COMMENT 'p15' /*T![placement] PLACEMENT POLICY=`fourreplicas` */)"))
// MySQL keeps the comments, so we should keep all options connected to the remaining partitions too!
// So once you added any partition option,
// it will never go back to just a number of partitions in MySQL!
tk.MustExec("alter table t coalesce partition 2")
tk.MustQuery(`show create table t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `id` int(11) NOT NULL,\n" +
" `fname` varchar(30) DEFAULT NULL,\n" +
" `lname` varchar(30) DEFAULT NULL,\n" +
" `hired` date NOT NULL DEFAULT '1970-01-01',\n" +
" `separated` date DEFAULT NULL,\n" +
" `job_code` int(11) DEFAULT NULL,\n" +
" `store_id` int(11) DEFAULT NULL\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY HASH (`store_id`)\n" +
"(PARTITION `p0`,\n" +
" PARTITION `p1`,\n" +
" PARTITION `p2`,\n" +
" PARTITION `p3`,\n" +
" PARTITION `p4`,\n" +
" PARTITION `p5`,\n" +
" PARTITION `p6`,\n" +
" PARTITION `p7`,\n" +
" PARTITION `p8`,\n" +
" PARTITION `p9`,\n" +
" PARTITION `p10`,\n" +
" PARTITION `p11`,\n" +
" PARTITION `p13` COMMENT 'p13' /*T![placement] PLACEMENT POLICY=`tworeplicas` */)"))
// If no extra options, it will go back to just numbers in TiDB:
tk.MustExec("alter table t coalesce partition 1")
tk.MustQuery(`show create table t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `id` int(11) NOT NULL,\n" +
" `fname` varchar(30) DEFAULT NULL,\n" +
" `lname` varchar(30) DEFAULT NULL,\n" +
" `hired` date NOT NULL DEFAULT '1970-01-01',\n" +
" `separated` date DEFAULT NULL,\n" +
" `job_code` int(11) DEFAULT NULL,\n" +
" `store_id` int(11) DEFAULT NULL\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY HASH (`store_id`) PARTITIONS 12"))
tk.MustExec(`drop placement policy tworeplicas`)
tk.MustExec(`drop placement policy threereplicas`)
tk.MustExec(`drop placement policy fourreplicas`)
tk.MustExec(`drop table t`)

tk.MustExec(`create table t (
id int not null,
fname varchar(30),
lname varchar(30),
hired date not null default '1970-01-01',
separated date,
job_code int,
store_id int
)
partition by key (hired)
partitions 4`)
tk.MustExec(`insert into t values (20, "Joe", "Doe", '2020-01-05', null, 1,1), (21, "Jane", "Doe", '2021-07-05', null, 2,1)`)
tk.MustExec("alter table t add partition partitions 8")
tk.MustQuery(`show create table t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `id` int(11) NOT NULL,\n" +
" `fname` varchar(30) DEFAULT NULL,\n" +
" `lname` varchar(30) DEFAULT NULL,\n" +
" `hired` date NOT NULL DEFAULT '1970-01-01',\n" +
" `separated` date DEFAULT NULL,\n" +
" `job_code` int(11) DEFAULT NULL,\n" +
" `store_id` int(11) DEFAULT NULL\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY KEY (`hired`) PARTITIONS 12"))
tk.MustExec("alter table t add partition (partition p13)")
tk.MustQuery(`show create table t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `id` int(11) NOT NULL,\n" +
" `fname` varchar(30) DEFAULT NULL,\n" +
" `lname` varchar(30) DEFAULT NULL,\n" +
" `hired` date NOT NULL DEFAULT '1970-01-01',\n" +
" `separated` date DEFAULT NULL,\n" +
" `job_code` int(11) DEFAULT NULL,\n" +
" `store_id` int(11) DEFAULT NULL\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY KEY (`hired`)\n" +
"(PARTITION `p0`,\n" +
" PARTITION `p1`,\n" +
" PARTITION `p2`,\n" +
" PARTITION `p3`,\n" +
" PARTITION `p4`,\n" +
" PARTITION `p5`,\n" +
" PARTITION `p6`,\n" +
" PARTITION `p7`,\n" +
" PARTITION `p8`,\n" +
" PARTITION `p9`,\n" +
" PARTITION `p10`,\n" +
" PARTITION `p11`,\n" +
" PARTITION `p13`)"))
// Note: MySQL does not remove all names when coalesce partitions is back to defaults
tk.MustExec("alter table t coalesce partition 2")
tk.MustQuery(`show create table t`).Check(testkit.Rows("" +
"t CREATE TABLE `t` (\n" +
" `id` int(11) NOT NULL,\n" +
" `fname` varchar(30) DEFAULT NULL,\n" +
" `lname` varchar(30) DEFAULT NULL,\n" +
" `hired` date NOT NULL DEFAULT '1970-01-01',\n" +
" `separated` date DEFAULT NULL,\n" +
" `job_code` int(11) DEFAULT NULL,\n" +
" `store_id` int(11) DEFAULT NULL\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY KEY (`hired`) PARTITIONS 11"))
}

func TestConstAndTimezoneDepent(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
Expand Down Expand Up @@ -4505,7 +4755,7 @@ func TestCreateAndAlterIntervalPartition(t *testing.T) {
require.Equal(t, "[ddl:8200]Unsupported FIRST PARTITION, does not seem like an INTERVAL partitioned table", err.Error())
err = tk.ExecToErr(`ALTER TABLE t LAST PARTITION LESS THAN (10)`)
require.Error(t, err)
require.Equal(t, "[ddl:8200]Unsupported add partitions", err.Error())
require.Equal(t, "[ddl:8200]Unsupported LAST PARTITION of HASH/KEY partitioned table", err.Error())
tk.MustExec(`drop table t`)

tk.MustExec(`create table t (a int, b varchar(255)) partition by list (a) (partition p0 values in (1,2,3), partition p1 values in (22,23,24))`)
Expand Down
Loading