Interviewer: Must the MySQL auto-increment primary key be continuous? Most people will get it wrong!

test environment:

MySQL version: 8.0

Database table: T (primary key id, unique index c, common field d)

If your business design relies on the continuity of the auto-increment key, this design assumes that the auto-increment key is continuous. But in fact, such an assumption is wrong, because the auto-increment primary key cannot guarantee continuous increment.

Recommend an open source and free Spring Boot practical project:

https://github.com/javastacks/spring-boot-best-practice

1. The attribute characteristics of self-increment:

1. Where is the auto-increment primary key value stored?

MySQL5.7 version

In MySQL 5.7 and earlier, auto-increment values ​​were stored in memory and not persisted. After each restart, when the table is opened for the first time, it will find the maximum value of the self-increment value max(id), and then use max(id)+1it as the current self-increment value of the table.

Versions after MySQL8.0

In version 8.0 of MySQL, the self-incremental changes are recorded redo login , and redo logthe value before restarting is relied on to restore.

You can view the current self-increment value by looking at the table details, and view the detailed value of the table parameter AUTO_INCREMENT( AUTO_INCREMENTthat is, the self-increment value of the current data table)

2. What is the modification mechanism of the auto-increment primary key value?

In table t, I defined the primary key id as self-increment value. When inserting a row of data, the behavior of self-increment value is as follows:

  1. If the id field is specified as 0, null or unspecified value when inserting data, then fill the current AUTO_INCREMENTvalue into the auto-increment field;
  2. If the id field specifies a specific value when inserting data, use the value specified in the statement directly.

According to the size relationship between the value to be inserted and the current auto-increment value, the change result of auto-increment value will also be different. Assume that the value to be inserted is X, and the current auto-increment value is Y.

  1. If X<Y, then the self-increment value of this table remains unchanged;
  2. If X≥Y, it is necessary to modify the current self-increment value to a new self-increment value.

2. How does the self-incrementing primary key of the new statement change:

We execute the following SQL statement to observe how the auto-increment primary key changes

insert into t values(null, 1, 1);

The flow chart is as follows

Process steps:

  • AUTO_INCREMENT=1 (Indicates that when inserting data next time, if the self-increment value needs to be automatically generated, id=1 will be generated.)
  • insert into t values(null, 1, 1) (the executor calls the InnoDB engine interface to write a row, and the value of the row passed in is (0,1,1))
  • get AUTO_INCREMENT=1 (InnoDB finds that the user has not specified the value of auto-increment id, and obtains the current auto-increment value 1 of table t)
  • AUTO_INCREMENT=2 insert into t values(1, 1, 1) (change the value of the incoming row to (1,1,1), and change the self-increment value to 2)
  • insert (1, 1, 1) executes the insert operation, and the process ends

You can find that in this process, the self-incremented +1 is performed first, and then the new statement is executed. You can find that this operation does not perform atomic operations. If the execution of the SQL statement fails, will the self-increment be continuous?

3. Discontinuous auto-increment primary key value: (unique primary key conflict)

When I execute the following SQL statement

insert into t values(null, 1, 1);

For the first time, we can add successfully, according to the modification mechanism of self-increment. If the id field is specified as 0, null or unspecified value when inserting data, then fill the current AUTO_INCREMENTvalue into the auto-increment field;

When we execute the following SQL statement for the second time, an error occurs. Because the c field in our table is a unique index, Duplicate key erroran error will occur and the new addition will fail.

For example:

  • AUTO_INCREMENT=2 (Indicates that when inserting data next time, if the self-increment value needs to be automatically generated, id=2 will be generated.)
  • insert into t values(null, 1, 1) (the executor calls the InnoDB engine interface to write a row, and the value of the row passed in is (0,1,1))
  • get AUTO_INCREMENT=2 (InnoDB finds that the user has not specified the value of auto-increment id, and obtains the current auto-increment value 2 of table t)
  • AUTO_INCREMENT=3 insert into t values(2, 1, 1) (change the value of the incoming row to (2,1,1), and change the self-increment value to 3)
  • insert (2, 1, 1) executes the insert operation, since there is already a record of c=1, so report Duplicate key error, the statement returns.

It can be seen that the self-increment value of this table is changed to 3, before the actual operation of inserting data is performed. When this statement is actually executed, because of a conflict with the unique key c, the row id=2 is not inserted successfully, but the self-increment value is not changed back either. Therefore, after that, when inserting a new data row, the auto-increment id obtained is 3. That is to say, there is a situation where the auto-increment primary key is discontinuous.

4. Discontinuity of self-incrementing primary key values: (transaction rollback)

In fact, the principle of transaction rollback is the same as above. It is all due to exceptions that cause new additions to fail, but the self-increment value does not roll back.

5. Discontinuity of self-incrementing primary key values: (batch insertion)

For the statement of batch inserting data, MySQL has a strategy of auto-incrementing id for batch application:

  1. During the execution of the statement, the first application for auto-increment id will allocate 1;
  2. After 1 is used up, this statement applies for the second self-increment id, and 2 will be allocated;
  3. After the 2 are used up, the statement is still the same, and the third application for auto-increment id will allocate 4;
  4. By analogy, the same statement applies for auto-increment ids, and the number of self-increment ids applied for each time is twice that of the previous one.

Execute the following SQL statement (add 4 pieces of data in table t first, and add the data of table t in batches after creating table tt)

insert into t values(null, 1,1);
insert into t values(null, 2,2);
insert into t values(null, 3,3);
insert into t values(null, 4,4);
create table tt like t;
insert into tt(c,d) select c,d from t;

insert into tt values(null, 5,5);

The first application got id=1, the second time it was assigned id=2 and id=3, and the third time it was assigned id=4 to id=7. When we execute it again insert into t2 values(null, 5,5), the actually inserted data is (8,5,5), and the auto-increment primary key is discontinuous.

6. Optimization of self-incrementing primary key values

1. What is self-increasing lock

Self-increasing lock is a special table-level lock. And when the transaction adds data to the table containing AUTO_INCREMENTthe column it will hold the self-increasing lock. If transaction A is doing this operation, if another transaction B tries to execute the INSERT statement, transaction B will be blocked until the transaction A releases the self-increasing lock.

2. What are the optimizations of self-increasing locks?

In MySQL version 5.0, the scope of self-increasing locking is at the statement level. That is to say, if a statement applies for a table self-increasing lock, the lock will not be released until the statement is executed. Obviously, this design will affect the degree of concurrency. A new strategy is introduced in MySQL 5.1.22 version, and a new parameter is added innodb_autoinc_lock_mode, the default value is 1.

Traditional mode (Traditional)

When the value of this parameter is set to 0, it means that the strategy of the previous MySQL 5.0 version is adopted, that is, the lock is released after the execution of the statement is completed;

The traditional mode can guarantee data consistency, but if there are multiple transactions executing INSERT operations concurrently, the AUTO-INCexistence of MySQL will slightly reduce the performance of MySQL, because only one INSERT statement can be executed at the same time.

Intermittent mode (Consecutive)

When the value of this parameter is set to 1: for ordinary insert statements, the self-increasing lock will be released immediately after the application; for statements like insert … selectthis , the self-increasing lock will not be released until the statement ends;

Discontinuous mode can guarantee data consistency, but if there are multiple transactions executing INSERT batch operations concurrently, the lock waiting state will be performed. If our business inserts a large amount of data, the performance of MySQL will drop greatly at this time.

Interleaved mode (Interleaved)

When the value of this parameter is set to 2, all the actions of applying for the auto-increment primary key are to release the lock after the application.

In the interspersed mode, he did not perform any locking settings. Under certain circumstances, the performance of MySQL is guaranteed, but it cannot guarantee the consistency of data. If we perform master-slave replication in interspersed mode, if your binlog format is not row format, the master-slave replication will be inconsistent.

7. What optimizations have been made in MySQL8.0

In versions after MySQL8.0, it has been set to innodb_autoinc_lock_mode=2, by default binlog_format=row.. This is more beneficial for insert … selectus to improve concurrency without data consistency problems when we insert data in batches.

Copyright statement: This article is an original article by CSDN blogger "You owe", following the CC 4.0 BY-SA copyright agreement, please attach the original source link and this statement for reprinting. Original link: https://blog.csdn.net/qq_48157004/article/details/128356734

Recent hot article recommendation:

1. 1,000+ Java interview questions and answers (2022 latest version)

2. Brilliant! Java coroutines are coming. . .

3. Spring Boot 2.x tutorial, too comprehensive!

4. Don't fill the screen with explosions and explosions, try the decorator mode, this is the elegant way! !

5. The latest release of "Java Development Manual (Songshan Edition)", download quickly!

Feel good, don't forget to like + forward!

Guess you like

Origin blog.csdn.net/youanyyou/article/details/130931052