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

Row written into wrong new partition during add/coalesce hash/key partition #43892

Closed
mjonss opened this issue May 16, 2023 · 0 comments · Fixed by #43891
Closed

Row written into wrong new partition during add/coalesce hash/key partition #43892

mjonss opened this issue May 16, 2023 · 0 comments · Fixed by #43891
Assignees
Labels
affects-7.1 component/tablepartition This issue is related to Table Partition of TiDB. severity/critical sig/sql-infra SIG: SQL Infra type/bug The issue is confirmed as a bug.

Comments

@mjonss
Copy link
Contributor

mjonss commented May 16, 2023

Bug Report

Please answer these questions before submitting your issue. Thanks!

1. Minimal reproduce step (Required)

Easiest with this golang test:

func TestAddKeyPartitionStates(t *testing.T) {
	store := testkit.CreateMockStore(t)
	tk := testkit.NewTestKit(t, store)
	dbName := "partSchemaVer"
	tk.MustExec("create database " + dbName)
	tk.MustExec("use " + dbName)
	tk.MustExec(`set @@global.tidb_enable_metadata_lock = ON`)
	tk2 := testkit.NewTestKit(t, store)
	tk2.MustExec("use " + dbName)
	tk3 := testkit.NewTestKit(t, store)
	tk3.MustExec("use " + dbName)
	tk4 := testkit.NewTestKit(t, store)
	tk4.MustExec("use " + dbName)
	tk.MustExec(`create table t (a int primary key, b varchar(255), key (b)) partition by hash (a) partitions 3`)
	tk.MustExec(`insert into t values (1, "1")`)
	tk.MustExec(`analyze table t`)
	tk.MustExec("BEGIN")
	tk.MustQuery(`select * from t`).Check(testkit.Rows("1 1"))
	tk.MustExec(`insert into t values (2, "2")`)
	syncChan := make(chan bool)
	go func() {
		tk2.MustExec(`alter table t add partition partitions 1`)
		syncChan <- true
	}()
	waitFor := func(i int, s string) {
		for true {
			res := tk4.MustQuery(`admin show ddl jobs where db_name = '` + strings.ToLower(dbName) + `' and table_name = 't' and job_type like 'alter table%'`).Rows()
			if len(res) == 1 && res[0][i] == s {
				break
			} else {
				gotime.Sleep(10 * gotime.Millisecond)
			}
		}
	}
	waitFor(4, "delete only")
	tk3.MustExec(`BEGIN`)
	tk3.MustQuery(`select * from t`).Sort().Check(testkit.Rows("1 1"))
	tk3.MustExec(`insert into t values (3,"3")`)

	tk.MustExec(`COMMIT`)
	waitFor(4, "write only")
	tk.MustExec(`BEGIN`)
	tk.MustQuery(`select * from t`).Sort().Check(testkit.Rows("1 1", "2 2"))
	tk.MustExec(`insert into t values (4,"4")`)

	tk3.MustExec(`COMMIT`)
	waitFor(4, "write reorganization")
	tk3.MustExec(`BEGIN`)
	tk3.MustQuery(`show create table t`).Check(testkit.Rows("" +
		"t CREATE TABLE `t` (\n" +
		"  `a` int(11) NOT NULL,\n" +
		"  `b` varchar(255) DEFAULT NULL,\n" +
		"  PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */,\n" +
		"  KEY `b` (`b`)\n" +
		") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
		"PARTITION BY HASH (`a`) PARTITIONS 3"))
	tk3.MustQuery(`select * from t`).Sort().Check(testkit.Rows("1 1", "2 2", "3 3"))
	tk3.MustExec(`insert into t values (5,"5")`)

	tk.MustExec(`COMMIT`)
	waitFor(4, "delete reorganization")
	tk.MustExec(`BEGIN`)
	tk.MustQuery(`show create table t`).Check(testkit.Rows("" +
		"t CREATE TABLE `t` (\n" +
		"  `a` int(11) NOT NULL,\n" +
		"  `b` varchar(255) DEFAULT NULL,\n" +
		"  PRIMARY KEY (`a`) /*T![clustered_index] CLUSTERED */,\n" +
		"  KEY `b` (`b`)\n" +
		") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
		"PARTITION BY HASH (`a`) PARTITIONS 4"))
	tk.MustQuery(`select * from t`).Sort().Check(testkit.Rows("1 1", "2 2", "3 3", "4 4"))
	tk.MustExec(`insert into t values (6,"6")`)

	tk3.MustExec(`COMMIT`)
	tk.MustExec(`COMMIT`)
	<-syncChan
	tk.MustQuery(`select * from t`).Sort().Check(testkit.Rows("1 1", "2 2", "3 3", "4 4", "5 5", "6 6"))
}

2. What did you expect to see? (Required)

Test passing

3. What did you see instead (Required)

Error:

        	Error:      	Not equal: 
        	            	expected: "[1 1]\n[2 2]\n[3 3]\n[4 4]\n"
        	            	actual  : "[1 1]\n[2 2]\n[3 3]\n[4 4]\n[4 4]\n"
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -4,2 +4,3 @@
        	            	 [4 4]
        	            	+[4 4]

I.e. duplicated row, since during double write, before the reorganization has copied all existing rows, the record has been written to the wrong new partition (based on the old number of partitions), resulting in a misplaced row in the new partition p1 which is not matching the reorg which will read the same row from the old partition p1 and write to the new partition p0, resulting in a duplicated row (including duplicated pk value!).

4. What is your TiDB version? (Required)

tidb_version(): Release Version: v7.2.0-alpha-187-g44222226d0
Edition: Community
Git Commit Hash: 44222226d0161bb97afdcb474367b9a57b711bbc
Git Branch: master
UTC Build Time: 2023-05-16 22:10:05
GoVersion: go1.20.4
Race Enabled: false
TiKV Min Version: 6.2.0-alpha
Check Table Before Drop: false
Store: unistore
1 row in set (0.00 sec)
@mjonss mjonss added the type/bug The issue is confirmed as a bug. label May 16, 2023
@mjonss mjonss self-assigned this May 16, 2023
@mjonss mjonss added sig/sql-infra SIG: SQL Infra severity/critical component/tablepartition This issue is related to Table Partition of TiDB. labels May 17, 2023
@ti-chi-bot ti-chi-bot bot added may-affects-5.1 This bug maybe affects 5.1.x versions. may-affects-5.2 This bug maybe affects 5.2.x versions. may-affects-5.3 This bug maybe affects 5.3.x versions. may-affects-5.4 This bug maybe affects 5.4.x versions. may-affects-6.1 may-affects-6.5 may-affects-7.1 labels May 17, 2023
@mjonss mjonss added affects-7.1 and removed may-affects-5.1 This bug maybe affects 5.1.x versions. may-affects-5.2 This bug maybe affects 5.2.x versions. may-affects-5.3 This bug maybe affects 5.3.x versions. may-affects-5.4 This bug maybe affects 5.4.x versions. may-affects-6.1 may-affects-6.5 may-affects-7.1 labels May 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affects-7.1 component/tablepartition This issue is related to Table Partition of TiDB. severity/critical sig/sql-infra SIG: SQL Infra type/bug The issue is confirmed as a bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant