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

Invalid keys may get locked #28073

Closed
zyguan opened this issue Sep 15, 2021 · 6 comments · Fixed by #35732
Closed

Invalid keys may get locked #28073

zyguan opened this issue Sep 15, 2021 · 6 comments · Fixed by #35732
Assignees
Labels
affects-6.0 affects-6.1 This bug affects the 6.1.x(LTS) versions. component/tablepartition This issue is related to Table Partition of TiDB. severity/moderate sig/transaction SIG:Transaction type/bug The issue is confirmed as a bug.

Comments

@zyguan
Copy link
Contributor

zyguan commented Sep 15, 2021

Bug Report

Please answer these questions before submitting your issue. Thanks!

1. Minimal reproduce step (Required)

Execute the following SQL, then query the MVCC of an invalid key 7480000000000000005F728000000000000000.

/* test */ drop table if exists t1, t2;
/* test */ create table t1  (c_int int, c_str varchar(40), primary key (c_int, c_str) , key(c_int)) partition by hash (c_int) partitions 4;
/* test */ create table t2  like t1 ;
/* test */ insert into t1 values (1, 'flamboyant mcclintock');
/* test */ insert into t2 select * from t1 ;
/* test */ begin;
/* test */ insert into t2 (c_int, c_str) values (2, 'romantic grothendieck');
/* test */ select * from t2 left join t1 on t1.c_int = t2.c_int for update;
/* test */ commit;

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

The MVCC info should be empty.

3. What did you see instead (Required)

The key was locked unexpectedly. It seems the partition id column (used as the physical id) is actually null (thus row.GetInt64(offset) returns 0) in this case.

2021-09-16_000640

4. What is your TiDB version? (Required)

master

@zyguan zyguan added type/bug The issue is confirmed as a bug. sig/execution SIG execution sig/transaction SIG:Transaction labels Sep 15, 2021
@cfzjywxk
Copy link
Contributor

From the debug log added in #28060.

[executor.go:957] ["[for debug] the physicalID or handle value is unexpected"] [conn=875] [ts=427743752351907842] [id=4568] [physicalID=0] [handle=10] [sql="/* tp-test:q:1631712899.f924863c-d083-4c81-913d-4b4618deffb1:69 */ select * from t1 join t2 on t1.c_int = t2.c_int and t1.c_enum <= t2.c_enum for update"] [tblIDs="[4568,4487]"] [partTblLen=2] [tblID2PIDColIdxMapKeys="[4487,4568]"] [tblid2ColIdxMapVals="[8,16]"]

Seems the calculation for the physical id is unexpected, possibly the tblID2PIDColumnIndex is set incorrectly.

@tiancaiamao
PTAL

@tiancaiamao tiancaiamao self-assigned this Sep 23, 2021
@tiancaiamao
Copy link
Contributor

Caused by #26373 and related to #28292

When partition table need to handle lock(write the lock key), it add an extra partition ID column to the chunk.
The bug is, the write operation does not recognize the extra partition ID column and write it back to the TiKV.

@mjonss
Copy link
Contributor

mjonss commented Nov 30, 2021

/component tablepartition

@mjonss
Copy link
Contributor

mjonss commented Mar 3, 2022

Fixed by #31634.

@zyguan
Copy link
Contributor Author

zyguan commented Jun 23, 2022

Here is an another case, @mjonss @tiancaiamao PTAL.

drop table if exists t1, t2;
create table t1  (c_int int, c_str varchar(40), primary key (c_int, c_str));
create table t2  (c_int int, c_str varchar(40), primary key (c_int)) partition by hash (c_int) partitions 4;
insert into t1 (`c_int`, `c_str`) values (1, 'upbeat solomon'), (5, 'sharp rubin');
insert into t2 (`c_int`, `c_str`) values (1, 'clever haibt'), (4, 'kind margulis');
begin;
select * from t1 left join t2 on t1.c_int = t2.c_int for update;
-- curl http://$tidb_host:10080/mvcc/hex/7480000000000000005F728000000000000000

2022-06-23_205451

@zyguan zyguan reopened this Jun 23, 2022
@tiancaiamao
Copy link
Contributor

tiancaiamao commented Jun 24, 2022

I find the root cause and will file a PR to fix.

select * from t1 left join t2 on t1.c_int = t2.c_int for update;

The join right side is NULL, added by the left join.
So there is no physical ID column... and we get the physical ID as 0, and construct the wrong key.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affects-6.0 affects-6.1 This bug affects the 6.1.x(LTS) versions. component/tablepartition This issue is related to Table Partition of TiDB. severity/moderate sig/transaction SIG:Transaction type/bug The issue is confirmed as a bug.
Projects
None yet
6 participants