-
Notifications
You must be signed in to change notification settings - Fork 5.8k
-
Notifications
You must be signed in to change notification settings - Fork 5.8k
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
Rename table may cause duplicate auto_increment assignment, leading to error #46904
Comments
I wonder if we should ever change the AutoID DatabaseID + tableID? By keeping them disconnected from DatabaseID and TableID (just a reference in the TableInfo to the AutoID 'id') it would solve this issue, as well as simplify ADD/REMOVE Partitioning, where the DatabaseID and/or TableID can change and opens up for similar or worse issues. EXCHANGE Partition probably needs extra handling, like double writing to two sets of AutoIDs. |
I think all the behaviour is expected.
Going on well here
The last step, transaction conflict between tidb1 and tidb3, blocking behaviour is expected by the pessimistic lock.
test2.t2 and test1.t1 are the same table, although the meta info differs.
When tidb1 insert values (null, "t1 second insert, will hang due to autoid collision with tidb3!") |
tidb1 and tidb3 both writing the a=3 record ... and there is a unique index (primary key) for that, thus transaction conflict on it. |
@tiancaiamao the issue here is not the conflict inserting a = 3 twice, it is that tidb3 uses a different AutoID, disconnected from tidb1. Without the rename (or only rename the table, not also changing its database/schema) tidb3 would update the AutoID and it would be seen by tidb1 (even if both are still in active, non-committed transactions), resulting in tidb1 would not generate the auto_increment id 3, but 5 instead and not resulting in a conflict. I would expect that AutoID is handled for each statement (not spanning client transactions). |
I believe the issue is that the databaseID (together with tableID) is used to identify the AutoID, see here. If it was only tableID (or even better, an own ID, that would be referenced/stored in the TableInfo) this issue would be solved. The reason for not reusing databaseID or tableID, but instead an own ID, would be that when a logical table needs to change its tableID (like when changing the primary key or moving between partitioned and non-partitioned table) it could keep the same AutoID. |
I debug the code and see they both insert a=3 ... and then transaction conflict.
What I mean is the last step of this bug ... not the trigger of it.
Yes, it's databaseID + tableID ==> AutoID |
Follow the reproduce steps, here
You can change 3 to 5 and see what happens, there should be no "hang". @mjonss
|
@tiancaiamao I would expect that any I think the issue here is that when inserting in tidb3 it will use a new AutoID, while tidb1 is still using the old AutoID, resulting in tidb3 does not update the AutoID used in tidb1, which leads to the duplicated key. Auto_increment should always generate a new non-conflicting auto_increment value (1) Here is another test case, basically only using auto-assigned auto_increment, which will also give unexpected 'ERROR 1146 (42S02): table doesn't exist': # Use first client session, tidb1
create schema if not exists test1;
create schema if not exists test2;
use test1;
drop table if exists t1, test2.t2;
create table t1 (a int auto_increment primary key nonclustered, b varchar(255), key (b));
begin;
insert into t1 values (null, "t1 first null");
select _tidb_rowid, a, b from t1;
# Switch to a new client (tidb2)
use test1;
rename table test1.t1 to test2.t2; -- will wait for tidb1
# Switch to new client (tidb3)
use test1;
begin;
insert into test2.t2 values (null, "t2 first insert null");
select _tidb_rowid, a, b from test2.t2;
# Switch back to tidb1
insert into t1 values (29996, "t1 explicit 29996"); -- instead of generating 30k inserts with null
insert into t1 values (null, "t1 second null");
insert into t1 values (null, "t1 third null"); -- will give: ERROR 1146 (42S02): table doesn't exist. Due to AutoID does no-longer exists? |
> I think the issue here is that when inserting in tidb3 it will use a new AutoID, while tidb1 is still using the old AutoID, resulting in tidb3 does not update the AutoID used in tidb1, which leads to the duplicated key. Exactly! |
In the "rename table" DDL operation, the old auto id meta key had been deleted and the new auto id meta key was generated.
Maybe a possible fix for "rename t1 to t2" is to make t2 not visible until the blocking transaction finish. |
Bug Report
Please answer these questions before submitting your issue. Thanks!
1. Minimal reproduce step (Required)
2. What did you expect to see? (Required)
Generating an auto_increment id will always work and not wait on any other session.
3. What did you see instead (Required)
insert into t1 values (null, "...") hangs, due to auto_increment generation?
4. What is your TiDB version? (Required)
The text was updated successfully, but these errors were encountered: