Mysql index failure under the InnoDB engine row-level lock change table lock case

I found a giant artificial intelligence learning website a few days ago, which is easy to understand and humorous. I can’t help but share it with everyone. Click to jump to the tutorial.
Get ready first, create the InnoDB engine data table, and add the corresponding index

DROP TABLE IF EXISTS `innodb_lock`;
CREATE TABLE `innodb_lock` (
  `a` int(10) NOT NULL,
  `b` varchar(255) NOT NULL DEFAULT '',
  KEY `index_a` (`a`),
  KEY `index_b` (`b`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


-- ----------------------------
-- Records of innodb_lock
-- ----------------------------
INSERT INTO `innodb_lock` VALUES ('1', 'b2');
INSERT INTO `innodb_lock` VALUES ('3', '3');
INSERT INTO `innodb_lock` VALUES ('4', '4000');
INSERT INTO `innodb_lock` VALUES ('5', '5000');
INSERT INTO `innodb_lock` VALUES ('6', '6000');
INSERT INTO `innodb_lock` VALUES ('7', '7000');
INSERT INTO `innodb_lock` VALUES ('8', '8000');
INSERT INTO `innodb_lock` VALUES ('9', '9000');
INSERT INTO `innodb_lock` VALUES ('1', 'b1');

Then open two Mysql terminals respectively, set autocommit to 0, that is, turn off the auto-commit function, and the transaction isolation level is in a repeatable read state; check the table data.

MySQL [test_db]> set autocommit = 0;
MySQL [test_db]> select * from innodb_lock;
+---+------+
| a | b    |
+---+------+
| 1 | b2   |
| 3 | 3    |
| 4 | 4000 |
| 5 | 5000 |
| 6 | 6000 |
| 7 | 7000 |
| 8 | 8000 |
| 9 | 9000 |
| 1 | b1   |
+---+------+

Next execute the update statement in the first terminal

MySQL [test_db]> update innodb_lock set b ='4001' where a = 4;

Then the second terminal executes the update statement

MySQL [test_db]> update innodb_lock set b = '4004' where a = 4;

It is found that the second terminal is in a blocked state, because the same row of data is modified here. Only after the first terminal submits, the lock is released, the second terminal finishes executing SQL, and finally the second terminal also commits the data after submitting the data. Will change, the value of b is '4004'.

We continue

Execute the update statement in the first terminal

MySQL [test_db]> update innodb_lock set b='4005' where a = 4;

Then the second terminal executes the update statement

MySQL [test_db]> update innodb_lock set b = '9001' where a = 9;

Found that both statements were executed successfully. Because the modification is not the same row of data. Then commit them separately, and then check the data, and find that both rows of data have changed.

MySQL [test_db]> select * from innodb_lock;
+---+------+
| a | b    |
+---+------+
| 1 | b2   |
| 3 | 3    |
| 4 | 4005 |
| 5 | 5000 |
| 6 | 6000 |
| 7 | 7000 |
| 8 | 8000 |
| 9 | 9001 |
| 1 | b1   |
+---+------+

The following is the key point, the two terminals still operate different lines separately.

Perform the update operation in the first terminal

MySQL [test_db]> update innodb_lock set a = 41 where b =4005;  

Note the where condition b=4005 here. Remember that the b field of the current table is a string type, and an index is added. After the index is added, if the query condition is not quoted, it will cause failure

Then perform the update operation in the second terminal

MySQL [test_db]> update innodb_lock set b='9002' where a = 9; 

Found to be blocked, row locks changed to table locks.
Be sure to pay attention to the rational use of indexes! ~~

The content is transferred from https://www.cnblogs.com/wt645631686/p/8323963.html

Guess you like

Origin blog.csdn.net/huangbaokang/article/details/113582528