Mysql series article home page
===============
Tips: Before reading this article, it is best to read this (Mysql lock mechanism -- row lock) article~
In the last article, we saw that the default row lock of InnoDB can make the operation of different rows without mutual influence and without blocking, thus solving the problem of multi-transaction and concurrency very well. However, that must be based on a premise that the index is used in the Where condition; on the contrary, if the index is not used, it is a full table scan and all blocking. This article demonstrates this scenario with a practical example.
1 Prepare data
1.1 Create a table
DROP TABLE IF EXISTS employee; CREATE TABLE IF NOT EXISTS employee ( id INT PRIMARY KEY auto_increment, name VARCHAR(40), money INT )ENGINE INNODB;
Note: ENGINE is INNODB (because InnoDB only supports row locks)
1.2 Insert data
INSERT INTO employee(name, money) VALUES('1001', 10000); INSERT INTO employee(name, money) VALUES('1002', 10000);
Hint: '1001' & '1002' are both strings and numbers (will be used later)
2 without indexing
So far, the Employee table has not been explicitly indexed.
2.1 Preparation
Or the old rule, two sessions (terminals), with a white background on the left and a black background on the right, and both set autocommit = 0
2.2 Testing
2.2.1 Perform an update in the left session
Sql statement:
UPDATE employee SET money = money + 10000 WHERE name = '1001';
result:
2.2.2 Perform an update in the right session
Sql statement:
UPDATE employee SET money = money + 5000 WHERE name = '1002';
Result: As shown in the figure below, the update operation is blocked!
2.2.3 Execute the COMMIT command on the left
Tip: When executing, pay attention to the changes in the execution of the Sql statement on the right
2.2.4 The Sql statement on the right was executed normally, and it took 18.19 seconds
2.2.5 Also perform a commit on the right side
2.2.6 Check the data on the left
2.2.7 Check the data on the right
Both results are the same and correct.
But the problem is, the left side operates on the name = '1001' record and the right side operates on the name = '1002' record, the right side is still blocked, indicating that the update operation on the left side locks the entire table! The reason for this is because there is no index on the name field!
2.3 Conclusion
When the field in the Where query condition has no index, the update operation will lock the whole table!
3 Situations where the index fails
Now let's demonstrate the case of index failure; if the index is to be invalid, the premise is that there is an index; therefore, the index is established first.
3.1 Create an index
CREATE INDEX idx_name ON employee(name);
3.2 Row lock demonstration with index
Tip: still the old rules, two sessions (terminals), the left is a white background, the right is a black background, and both set autocommit = 0
3.2.1 Perform an update in the left session
Sql statement:
UPDATE employee SET money = money + 10000 WHERE name = '1001';
result:
3.2.2 Perform an update in the right session
Sql statement:
UPDATE employee SET money = money + 5000 WHERE name = '1002';
result:
Executes immediately, not blocked!
3.2.3 Execute the submission on the left and right sides respectively
3.2.4 View results on the left
3.2.5 View the results on the right
The results on both sides are the same and correct.
3.2.6 Conclusion
It can be seen that in the case of an index, when updating different rows, InnoDB's default row lock will not block.
3.3 Row lock demonstration in case of index failure
Tip: still the old rules, two sessions (terminals), the left is a white background, the right is a black background, and both set autocommit = 0
3.3.1 Perform an update in the left session
Sql statement: (Note: there are no single quotes around 1001 of name = 1001)
UPDATE employee SET money = money + 10000 WHERE name = 1001;
result:
3.3.2 Perform an update in the right session
Sql statement:
UPDATE employee SET money = money + 5000 WHERE name = '1002';
result:
blocked! It means that the session on the left locks the entire table!
3.3.3 Execute the commit on the left (note the changes in the execution of Sql in the session on the right)
3.3.4 View the session on the right
The update operation in the session on the right was executed and took 20.68 seconds
3.3.5 The right side is also submitted
3.3.6 View results on the left
3.3.7 View results on the right
Both results are the same and correct.
3.3.8 Conclusion
Although the query field in the Where condition has an index, when the index is invalid (in this example, the string is not enclosed in single quotes), InnoDB's default row lock update operation becomes a table lock.
4 Conclusion
When there is no index or the index is invalid, the row lock of InnoDB becomes the table lock
Reason: Mysql's row locks are implemented through indexes!