最近在MYSQL菜鸟群有群友提问,说他看了某个公众号里面文章说 "MYSQL RR隔离级别下无索引更新会导致表锁! " 他表示疑惑,而且不仅是他,还有很多个她在不同的群里同样表示疑惑! 下面是群友的截图 是啊%20MYSQL%20以及进化到了8.3.0版本了,普遍都使用5.7和8.0版本.而且还听说%20INNODB引擎会把不符合条件的记录给释放锁. 原理大概是这样的,一个表有100行记录,一条UPDATE语句需要更新10行记录.%20而这10行记录分散在这100行里,%20从第一个符合条件的行到最后一个不符合条件的行%20大约是30行. 好吧!%2030行和100行差不多. 开始之处不管三七二十一,见行就上X锁.然后把行回传给MYSQL%20SERVER层,进行过滤处理.%20需要的请留下,不需要的通知给INNODB,好让引擎把行锁个释放掉了.从这个优化理论来说,%20RR下应该会把不需要的记录给释放掉,那么RR下的表锁就不可能出现.套用某人的话说,%20我以上都是胡说八道!%20我们试验一把,先看下真正表锁是什么样子! 先上个表读锁
SESSION 2MySQL 14:52:19 root@192.168.0.221 [dba]>lock tables dba.personal_identity_info read; Query OK, 0 rows affected (0.01 sec)
我们SESSION%202是主决 SESSION3%20负责查看监控,%20SESSION%201负责打酱油的.
SESSION 3 [sys]>select * from performance_schema.table_handles; +-------------+---------------+----------------------------+-----------------------+-----------------+----------------+---------------+---------------+ | OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | OBJECT_INSTANCE_BEGIN | OWNER_THREAD_ID | OWNER_EVENT_ID | INTERNAL_LOCK | EXTERNAL_LOCK | +-------------+---------------+----------------------------+-----------------------+-----------------+----------------+---------------+---------------+ | TABLE | sys | sys_config | 140317340487016 | NULL | NULL | NULL | NULL | | TABLE | dba | personal_identity_info | 140317120949096 | 101 | 29 | NULL | READ EXTERNAL | +-------------+---------------+----------------------------+-----------------------+-----------------+----------------+---------------+---------------+ 235 rows in set (0.01 sec) MySQL 15:41:03 root@192.168.0.221 [sys]>select * from performance_schema.metadata_locks; +-------------+--------------------+------------------------+-------------+-----------------------+------------------+---------------+-------------+-------------------+-----------------+----------------+ | OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | COLUMN_NAME | OBJECT_INSTANCE_BEGIN | LOCK_TYPE | LOCK_DURATION | LOCK_STATUS | SOURCE | OWNER_THREAD_ID | OWNER_EVENT_ID | +-------------+--------------------+------------------------+-------------+-----------------------+------------------+---------------+-------------+-------------------+-----------------+----------------+ | TABLE | dba | personal_identity_info | NULL | 140316984440272 | SHARED_READ_ONLY | TRANSACTION | GRANTED | sql_parse.cc:5768 | 105 | 29 | | TABLE | performance_schema | metadata_locks | NULL | 140316917412768 | SHARED_READ | TRANSACTION | GRANTED | sql_parse.cc:5768 | 104 | 48 | +-------------+--------------------+------------------------+-------------+-----------------------+------------------+---------------+-------------+-------------------+-----------------+----------------+ 2 rows in set (0.00 sec)
从TABLE_HANDLES说personal_identity_info是外部锁%20READ%20EXTERNAL. 从metadata_locks%20表看SHARED_READ_ONLY%20共享只读锁 下面更新其它行,打酱油的试图更新且等待中
SESSION 1 MySQL 15:00:22 root@192.168.0.221 [dba]>update dba.personal_identity_info set surname='曾' where surname='曾君'; ERROR 4031 (HY000): The client was disconnected by the server because of inactivity. See wait_timeout and interactive_timeout for configuring this behavior. No connection. Trying to reconnect... Connection id: 60 Current database: dba
SESSION 3 MySQL 15:41:23 root@192.168.0.221 [sys]>SELECT PROCESSLIST_ID,THREAD_OS_ID,THREAD_ID,PROCESSLIST_INFO FROM performance_schema.threads where TYPE='FOREGROUND'; +----------------+--------------+-----------+-----------------------------------------------------------------------------------------------------------------------+ | PROCESSLIST_ID | THREAD_OS_ID | THREAD_ID | PROCESSLIST_INFO | +----------------+--------------+-----------+-----------------------------------------------------------------------------------------------------------------------+ | 5 | 6440 | 45 | NULL | | 7 | 6444 | 49 | NULL | | 34 | 6480 | 80 | NULL | | 35 | 6566 | 81 | NULL | | 49 | 6607 | 95 | NULL | | 57 | 7822 | 103 | NULL | | 58 | 6454 | 104 | SELECT PROCESSLIST_ID,THREAD_OS_ID,THREAD_ID,PROCESSLIST_INFO FROM performance_schema.threads where TYPE='FOREGROUND' | | 59 | 6479 | 105 | NULL | | 60 | 7823 | 106 | update dba.personal_identity_info set surname='曾' where surname='曾君' | +----------------+--------------+-----------+-----------------------------------------------------------------------------------------------------------------------+ 9 rows in set (0.00 sec) MySQL 15:44:41 root@192.168.0.221 [sys]> select * from performance_schema.metadata_locks where owner_thread_Id != sys.ps_thread_id(connection_id()); +-------------+---------------+------------------------+-------------+-----------------------+---------------------+---------------+-------------+-------------------+-----------------+----------------+ | OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | COLUMN_NAME | OBJECT_INSTANCE_BEGIN | LOCK_TYPE | LOCK_DURATION | LOCK_STATUS | SOURCE | OWNER_THREAD_ID | OWNER_EVENT_ID | +-------------+---------------+------------------------+-------------+-----------------------+---------------------+---------------+-------------+-------------------+-----------------+----------------+ | TABLE | dba | personal_identity_info | NULL | 140316984440272 | SHARED_READ_ONLY | TRANSACTION | GRANTED | sql_parse.cc:5768 | 105 | 29 | | GLOBAL | NULL | NULL | NULL | 140317857342752 | INTENTION_EXCLUSIVE | STATEMENT | GRANTED | sql_base.cc:3038 | 106 | 23 | | TABLE | dba | personal_identity_info | NULL | 140317856664544 | SHARED_WRITE | TRANSACTION | PENDING | sql_parse.cc:5768 | 106 | 23 | +-------------+---------------+------------------------+-------------+-----------------------+---------------------+---------------+-------------+-------------------+-----------------+----------------+ 3 rows in set, 1 warning (0.00 sec)
表要上共享写,确被共享度给阻塞了
SESSION 2 UNLOCK TABLES MySQL 15:58:46 root@192.168.0.221 [sys]>select * from performance_schema.table_handles; +-------------+---------------+----------------------------+-----------------------+-----------------+----------------+---------------+----------------+ | OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | OBJECT_INSTANCE_BEGIN | OWNER_THREAD_ID | OWNER_EVENT_ID | INTERNAL_LOCK | EXTERNAL_LOCK | +-------------+---------------+----------------------------+-----------------------+-----------------+----------------+---------------+----------------+ | TABLE | sqle | workflows | 140317118649272 | NULL | NULL | NULL | NULL | | TABLE | dba | personal_identity_info | 140316984445496 | 105 | 177468 | NULL | WRITE EXTERNAL | +-------------+---------------+----------------------------+-----------------------+-----------------+----------------+---------------+----------------+ 238 rows in set (0.00 sec) MySQL 16:01:57 root@192.168.0.221 [sys]>select * from performance_schema.metadata_locks where owner_thread_Id != sys.ps_thread_id(connection_id()); +-------------+---------------+----------------------------+-------------+-----------------------+----------------------+---------------+-------------+-------------------+-----------------+----------------+ | OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | COLUMN_NAME | OBJECT_INSTANCE_BEGIN | LOCK_TYPE | LOCK_DURATION | LOCK_STATUS | SOURCE | OWNER_THREAD_ID | OWNER_EVENT_ID | +-------------+---------------+----------------------------+-------------+-----------------------+----------------------+---------------+-------------+-------------------+-----------------+----------------+ | GLOBAL | NULL | NULL | NULL | 140316984580720 | INTENTION_EXCLUSIVE | STATEMENT | GRANTED | sql_base.cc:5436 | 105 | 176218 | | SCHEMA | dba | NULL | NULL | 140316988086032 | INTENTION_EXCLUSIVE | TRANSACTION | GRANTED | sql_base.cc:5423 | 105 | 176218 | | TABLE | dba | personal_identity_info | NULL | 140316984440272 | SHARED_NO_READ_WRITE | TRANSACTION | GRANTED | sql_parse.cc:5768 | 105 | 176219 | | TABLESPACE | NULL | dba/personal_identity_info | NULL | 140316987539760 | INTENTION_EXCLUSIVE | TRANSACTION | GRANTED | lock.cc:802 | 105 | 177465 | +-------------+---------------+----------------------------+-------------+-----------------------+----------------------+---------------+-------------+-------------------+-----------------+----------------+ 4 rows in set (0.00 sec)
释放掉共享读,再上表写锁%20出现%20WRITE%20EXTERNAL%20 SHARED_NO_READ_WRITE;
接下来我们看看RR模式下无索更新是否会出现上面的情况?%20这次让SESSION%201当主角,先看执行计划,走主键索引
MySQL 16:04:15 root@192.168.0.221 [dba]>explain update dba.personal_identity_info set surname='王X' where surname='张'; +----+-------------+------------------------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------------------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ | 1 | UPDATE | personal_identity_info | NULL | index | NULL | PRIMARY | 8 | NULL | 1001 | 100.00 | Using where | +----+-------------+------------------------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ 1 row in set, 1 warning (0.01 sec)
然后开始SESSION%201%20的表演
SESSION 1: MySQL 14:05:00 root@192.168.0.221 [dba]>show session variables like '%iso%'; +-----------------------+-----------------+ | Variable_name | Value | +-----------------------+-----------------+ | transaction_isolation | REPEATABLE-READ | +-----------------------+-----------------+ 1 row in set (0.01 sec) MySQL 14:05:56 root@192.168.0.221 [dba]>show global variables like '%iso%'; +-----------------------+-----------------+ | Variable_name | Value | +-----------------------+-----------------+ | transaction_isolation | REPEATABLE-READ | +-----------------------+-----------------+ 1 row in set (0.02 sec) MySQL 14:06:17 root@192.168.0.221 [dba]>set session sql_safe_updates=off; Query OK, 0 rows affected (0.00 sec) MySQL 14:06:37 root@192.168.0.221 [dba]>BEGIN; Query OK, 0 rows affected (0.00 sec) MySQL 14:16:58 root@192.168.0.221 [dba]>select * from dba.personal_identity_info where surname='张'; +-----+--------------------+---------+-----------+-------------+-----+---------------------+-----+---------------+-------------+----------------------------+----------------------------+ | id | identity_number | surname | name | mobile | sex | birthday | age | top_education | income_year | create_time | update_time | +-----+--------------------+---------+-----------+-------------+-----+---------------------+-----+---------------+-------------+----------------------------+----------------------------+ | 551 | 13.544431931846246 | 张 | 梦冰师 | 13552049405 | 男 | 1970-05-18 00:00:00 | 33 | 初中 | 56482 | 2023-05-18 15:32:12.735522 | 2023-05-18 15:32:12.735522 | | 800 | 133777832243384635 | 张 | 栋家恩 | 14899421941 | 男 | 1971-05-18 00:00:00 | 49 | 文盲 | 27376 | 2023-05-18 15:32:19.409945 | 2023-05-18 15:32:19.409945 | | 912 | 13.393129107908466 | 张 | 顺水娜 | 13317756125 | 男 | 1965-05-18 00:00:00 | 127 | 文盲 | 77904 | 2023-05-18 15:32:21.144088 | 2023-05-18 15:32:21.144088 | +-----+--------------------+---------+-----------+-------------+-----+---------------------+-----+---------------+-------------+----------------------------+----------------------------+ 3 rows in set (0.01 sec) MySQL 14:17:09 root@192.168.0.221 [dba]>update dba.personal_identity_info set surname='王X' where surname='张'; Query OK, 3 rows affected (0.06 sec) Rows matched: 3 Changed: 3 Warnings: 0
监控SESSION%203%20看了它上了好多X索还有%20SUPREMUM%20PSEUNDO-RECORD
SESSION 3 MySQL 14:17:02 root@192.168.0.221 [dba]>SELECT LOCK_TYPE,LOCK_MODE,LOCK_DATA FROM performance_schema.data_locks; +-----------+-----------+------------------------+ | LOCK_TYPE | LOCK_MODE | LOCK_DATA | +-----------+-----------+------------------------+ | TABLE | IX | NULL | | RECORD | X | supremum pseudo-record | | RECORD | X | 1 | | RECORD | X | 2 | | RECORD | X | 3 | | RECORD | X | 4 | | RECORD | X | 5 | | RECORD | X | 6 | | RECORD | X | 7 | | RECORD | X | 8 | | RECORD | X | 9 | | RECORD | X | 10 | | RECORD | X | 1000 | | RECORD | X | 1005 | | RECORD | X | 1009 | | RECORD | X | 1008 | | RECORD | X | 1010 | | RECORD | X | 1011 | | RECORD | X | 1012 | | RECORD | X | 937 | | RECORD | X | 964 | | RECORD | X | 969 | | RECORD | X | 1001 | | RECORD | X | 912 | +-----------+-----------+------------------------+ 1018 rows in set (0.03 sec)
AI%203.5%20说得差不多 在MySQL中,DATA_LOCK表用于存储由各种锁机制创建的锁信息。LOCK_DATA列中的SUPREMUM%20PSEUDO-RECORD表示的是一个伪记录,它在内部用于表示一个范围的锁。 具体来说,SUPREMUM%20PSEUDO-RECORD表示的是一个最大值或者上限,它在锁定范围的最顶部。这种伪记录通常用于表示一个范围锁的起始点或终止点,以便清晰地表示锁定的范围。 在MySQL中,范围锁可以用于锁定一个范围内的数据,而不仅仅是单个行或表。这种锁机制可以在多个会话之间提供更灵活的锁定策略,以确保数据的一致性和完整性。 打酱油的出场....... %20舔狗舔到一无所有,直到被拒绝!
SESSION 2 MySQL 14:22:12 root@192.168.0.221 [dba]>set session sql_safe_updates=off; Query OK, 0 rows affected (0.00 sec) MySQL 14:22:29 root@192.168.0.221 [dba]>update dba.personal_identity_info set surname='曾君' where surname='曾'; ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction MySQL 14:24:43 root@192.168.0.221 [dba]>INSERT INTO dba.personal_identity_info (IDENTITY_NUMBER,SURNAME,NAME,MOBILE,SEX,BIRTHDAY,AGE,TOP_EDUCATION,INCOME_YEAR) VALUES(135478728875032375,'燕','燕太杰','13984280466','男','2001-05-18 00:00:00','100','博士','27701'); ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
没有出现表锁的字样!
SESSION 3 MySQL 15:53:59 root@192.168.0.221 [sys]>select * from performance_schema.table_handles WHERE OBJECT_NAME='personal_identity_info'; +-------------+---------------+------------------------+-----------------------+-----------------+----------------+---------------+---------------+ | OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | OBJECT_INSTANCE_BEGIN | OWNER_THREAD_ID | OWNER_EVENT_ID | INTERNAL_LOCK | EXTERNAL_LOCK | +-------------+---------------+------------------------+-----------------------+-----------------+----------------+---------------+---------------+ | TABLE | dba | personal_identity_info | 140317187639336 | NULL | NULL | NULL | NULL | | TABLE | dba | personal_identity_info | 140317320812936 | NULL | NULL | NULL | NULL | | TABLE | dba | personal_identity_info | 140317320824264 | NULL | NULL | NULL | NULL | | TABLE | dba | personal_identity_info | 140317340006888 | NULL | NULL | NULL | NULL | | TABLE | dba | personal_identity_info | 140316917541176 | NULL | NULL | NULL | NULL | | TABLE | dba | personal_identity_info | 140316986582840 | NULL | NULL | NULL | NULL | | TABLE | dba | personal_identity_info | 140317120949096 | NULL | NULL | NULL | NULL | | TABLE | dba | personal_identity_info | 140316984445496 | NULL | NULL | NULL | NULL | +-------------+---------------+------------------------+-----------------------+-----------------+----------------+---------------+---------------+ 8 rows in set (0.00 sec) MySQL 15:54:06 root@192.168.0.221 [sys]>select * from performance_schema.metadata_locks where owner_thread_Id != sys.ps_thread_id(connection_id()); +-------------+---------------+------------------------+-------------+-----------------------+--------------+---------------+-------------+-------------------+-----------------+----------------+ | OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | COLUMN_NAME | OBJECT_INSTANCE_BEGIN | LOCK_TYPE | LOCK_DURATION | LOCK_STATUS | SOURCE | OWNER_THREAD_ID | OWNER_EVENT_ID | +-------------+---------------+------------------------+-------------+-----------------------+--------------+---------------+-------------+-------------------+-----------------+----------------+ | TABLE | dba | personal_identity_info | NULL | 140316984580720 | SHARED_WRITE | TRANSACTION | GRANTED | sql_parse.cc:5768 | 105 | 849 | +-------------+---------------+------------------------+-------------+-----------------------+--------------+---------------+-------------+-------------------+-----------------+----------------+ 1 row in set (0.00 sec)
小结
RR%20模式下%20无索引更新%20INNODB%20表%20走的是主键聚集索引 对所有行加X锁,以及行之间的GAP锁,%20且事务提交会被回滚才释放锁.%20其实行锁X+GAP锁就是NEXT-KEY锁
再来一张图,会更加让人记忆深刻
RC 模式下
SESSION 1: set session transaction isolation level read committed; MySQL 14:39:17 root@192.168.0.221 [dba]>show session variables like '%iso%'; +-----------------------+----------------+ | Variable_name | Value | +-----------------------+----------------+ | transaction_isolation | READ-COMMITTED | +-----------------------+----------------+ 1 row in set (0.01 sec) MySQL 14:39:46 root@192.168.0.221 [dba]>show global variables like '%iso%'; +-----------------------+-----------------+ | Variable_name | Value | +-----------------------+-----------------+ | transaction_isolation | REPEATABLE-READ | +-----------------------+-----------------+ 1 row in set (0.00 sec) MySQL 14:39:53 root@192.168.0.221 [dba]>BEGIN; Query OK, 0 rows affected (0.01 sec) MySQL 14:40:44 root@192.168.0.221 [dba]>update dba.personal_identity_info set surname='王X' where surname='张'; Query OK, 3 rows affected (0.37 sec) Rows matched: 3 Changed: 3 Warnings: 0
上的锁真少
SESSION 3: MySQL 14:35:09 root@192.168.0.221 [sys]>SELECT LOCK_TYPE,LOCK_MODE,LOCK_DATA FROM performance_schema.data_locks; +-----------+---------------+-----------+ | LOCK_TYPE | LOCK_MODE | LOCK_DATA | +-----------+---------------+-----------+ | TABLE | IX | NULL | | RECORD | X,REC_NOT_GAP | 551 | | RECORD | X,REC_NOT_GAP | 800 | | RECORD | X,REC_NOT_GAP | 912 | +-----------+---------------+-----------+ 4 rows in set (0.01 sec)
酱油会话 可颜可甜
ESSION 2: set session transaction isolation level read committed; set session sql_safe_updates=off; MySQL 14:42:13 root@192.168.0.221 [dba]>set session transaction isolation level read committed; Query OK, 0 rows affected (0.00 sec) MySQL 14:42:16 root@192.168.0.221 [dba]>set session sql_safe_updates=off; Query OK, 0 rows affected (0.00 sec) MySQL 14:42:29 root@192.168.0.221 [dba]>update dba.personal_identity_info set surname='曾君' where surname='曾'; Query OK, 26 rows affected (0.12 sec) Rows matched: 26 Changed: 26 Warnings: 0 MySQL 14:42:55 root@192.168.0.221 [dba]>INSERT INTO dba.personal_identity_info (IDENTITY_NUMBER,SURNAME,NAME,MOBILE,SEX,BIRTHDAY,AGE,TOP_EDUCATION,INCOME_YEAR) VALUES(135478728875032375,'燕','燕太杰','13984280466','男','2001-05-18 00:00:00','100','博士','27701'); Query OK, 1 row affected (0.37 sec)
没有表锁!
SESSION 3 MySQL 14:44:55 root@192.168.0.221 [sys]>select THREAD_ID,EVENT_NAME,STATE,TRX_ID,ISOLATION_LEVEL,AUTOCOMMIT FROM performance_schema.events_transactions_current; +-----------+-------------+-----------+-----------------+-----------------+------------+ | THREAD_ID | EVENT_NAME | STATE | TRX_ID | ISOLATION_LEVEL | AUTOCOMMIT | +-----------+-------------+-----------+-----------------+-----------------+------------+ | 1 | transaction | COMMITTED | 421796018412648 | REPEATABLE READ | YES | | 36 | transaction | COMMITTED | 421796018411608 | REPEATABLE READ | YES | | 46 | transaction | COMMITTED | 421796018413688 | REPEATABLE READ | YES | | 49 | transaction | COMMITTED | 421796018412648 | REPEATABLE READ | YES | | 80 | transaction | COMMITTED | 421796018415768 | REPEATABLE READ | YES | | 81 | transaction | COMMITTED | 421796018416808 | REPEATABLE READ | YES | | 92 | transaction | COMMITTED | 421796018413688 | REPEATABLE READ | YES | | 95 | transaction | COMMITTED | 421796018418888 | REPEATABLE READ | YES | | 99 | transaction | ACTIVE | NULL | READ COMMITTED | NO | | 100 | transaction | COMMITTED | 421796018417848 | READ COMMITTED | YES | +-----------+-------------+-----------+-----------------+-----------------+------------+ 10 rows in set (0.00 sec) MySQL 14:47:06 root@192.168.0.221 [sys]>select * from performance_schema.metadata_locks ; +-------------------+--------------------+------------------------+-----------------------+-----------------------+---------------------+---------------+-------------+-------------------+-----------------+----------------+ | OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | COLUMN_NAME | OBJECT_INSTANCE_BEGIN | LOCK_TYPE | LOCK_DURATION | LOCK_STATUS | SOURCE | OWNER_THREAD_ID | OWNER_EVENT_ID | +-------------------+--------------------+------------------------+-----------------------+-----------------------+---------------------+---------------+-------------+-------------------+-----------------+----------------+ | TABLE | performance_schema | metadata_locks | NULL | 140317723039376 | SHARED_READ | TRANSACTION | GRANTED | sql_parse.cc:5768 | 98 | 101 | | SCHEMA | performance_schema | NULL | NULL | 140317724590224 | INTENTION_EXCLUSIVE | TRANSACTION | GRANTED | dd_schema.cc:108 | 98 | 101 | | COLUMN STATISTICS | performance_schema | metadata_locks | column_name | 140317725246048 | SHARED_READ | STATEMENT | GRANTED | sql_base.cc:576 | 98 | 102 | | COLUMN STATISTICS | performance_schema | metadata_locks | lock_duration | 140317725390880 | SHARED_READ | STATEMENT | GRANTED | sql_base.cc:576 | 98 | 102 | | COLUMN STATISTICS | performance_schema | metadata_locks | lock_status | 140317722479760 | SHARED_READ | STATEMENT | GRANTED | sql_base.cc:576 | 98 | 102 | | COLUMN STATISTICS | performance_schema | metadata_locks | lock_type | 140317722480144 | SHARED_READ | STATEMENT | GRANTED | sql_base.cc:576 | 98 | 102 | | COLUMN STATISTICS | performance_schema | metadata_locks | object_instance_begin | 140317722479968 | SHARED_READ | STATEMENT | GRANTED | sql_base.cc:576 | 98 | 102 | | COLUMN STATISTICS | performance_schema | metadata_locks | object_name | 140317725245648 | SHARED_READ | STATEMENT | GRANTED | sql_base.cc:576 | 98 | 102 | | COLUMN STATISTICS | performance_schema | metadata_locks | object_schema | 140317725245808 | SHARED_READ | STATEMENT | GRANTED | sql_base.cc:576 | 98 | 102 | | COLUMN STATISTICS | performance_schema | metadata_locks | object_type | 140317722784752 | SHARED_READ | STATEMENT | GRANTED | sql_base.cc:576 | 98 | 102 | | COLUMN STATISTICS | performance_schema | metadata_locks | owner_event_id | 140317724827824 | SHARED_READ | STATEMENT | GRANTED | sql_base.cc:576 | 98 | 102 | | COLUMN STATISTICS | performance_schema | metadata_locks | owner_thread_id | 140317724827456 | SHARED_READ | STATEMENT | GRANTED | sql_base.cc:576 | 98 | 102 | | COLUMN STATISTICS | performance_schema | metadata_locks | source | 140317722490432 | SHARED_READ | STATEMENT | GRANTED | sql_base.cc:576 | 98 | 102 | | TABLE | dba | personal_identity_info | NULL | 140316917486288 | SHARED_WRITE | TRANSACTION | GRANTED | sql_parse.cc:5768 | 99 | 60 | +-------------------+--------------------+------------------------+-----------------------+-----------------------+---------------------+---------------+-------------+-------------------+-----------------+----------------+ 14 rows in set (0.02 sec) MySQL 14:50:12 root@192.168.0.221 [sys]>select * from performance_schema.table_handles; +-------------+---------------+----------------------------+-----------------------+-----------------+----------------+---------------+---------------+ | OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | OBJECT_INSTANCE_BEGIN | OWNER_THREAD_ID | OWNER_EVENT_ID | INTERNAL_LOCK | EXTERNAL_LOCK | +-------------+---------------+----------------------------+-----------------------+-----------------+----------------+---------------+---------------+ | TABLE | sys | sys_config | 140317340487016 | NULL | NULL | NULL | NULL | | TABLE | dba | personal_identity_info | 140317340006888 | NULL | NULL | NULL | NULL | | TABLE | dba | personal_identity_info | 140316917541176 | NULL | NULL | NULL | NULL | | TABLE | dba | personal_identity_info | 140316986582840 | NULL | NULL | NULL | NULL | +-------------+---------------+----------------------------+-----------------------+-----------------+----------------+---------------+---------------+
RC 模式下 无表锁,且在事务提交前就释放掉了不符合条件的记录锁
总的来说 RR下无索引更新INNODB引擎的表, 确实是达到表锁的效果.
不过这么说会显得不那么专业,当然忽悠小白,或者是不懂MYSQL的开发人员,还是可以可以的!
如果面对DBA说的话,套用某人的话来说 简直是胡说八道!
思考题:
RC隔离级别下,这种无索引更新,最后还是会释放掉那些不符合条件的记录.那么在它上锁到释放锁的过程里,时间里,高并发下,或许会阻塞并发.
那么引擎和服务层是怎么交互的? 按文章头部列子说, 100行,扫描了30行,需要的是10行.
方式 一
扫描一行,就返回一行给服务层,然后服务层判断,下达通知,引擎INNODB根据通知判断是继续保持锁,还是释放锁; 然后继续扫描下一行.
方式二
扫描,扫描,把30行全扫描完后,一次性提交给服务层进行判断,然后再释放锁.
思考题2
如果是两表关联更新,这时候JOIN_BUFFER参与关联会采用方式一还是方式二?
这些只能有空的时候调试源码可知一二.
其实大家学会调试源码,就知道真实的情况,就不会被肤浅的人给忽悠了!
最后作为DBA 需要开启 安全更新参数,就是防止无主键,无索引,无LIMIT下DML操作
set global sql_safe_updates=on;
编辑推荐:
相关推荐
-
雷神推出 MIX PRO II 迷你主机:基于 Ultra 200H,玻璃上盖 + ARGB 灯效
2 月 9 日消息,雷神 (THUNDEROBOT) 现已宣布推出基于英
-
制造商 Musnap 推出彩色墨水屏电纸书 Ocean C:支持手写笔、第三方安卓应用
2 月 10 日消息,制造商 Musnap 现已在海外推出一款 Oce
