可知上一篇【死锁分析】,又重新表达了一些图片,图画更了
【使用电脑阅读更佳】
事务1 | 事务2 |
- | 开始 |
开始 | 删除id=1;(1)id加锁、(2)A加锁 |
删除id=2;(3)id加锁、(4)A加锁 | - |
- | 更新 ?用户ID=?和租户ID=?没有=?;
- | 如果先走无索引,已经持有B锁,再去持D锁时等待更新?用户ID=?和租户ID=?没有=?;| - 先走无索引,持B锁时等待;死锁 |-
更新 ?用户ID=?和租户ID=?and no=?如果先走(tenantid ,user id);这个日志一
先走不,日志二
索引,常用日志三
最近的事情,习了部分数据库的理论知识,后面又有温时间再整理。现在的程序员也真得难得知天文,下地理;这应该是DBA的,作为开发者的长,作为开发者深研,真难
在追查死锁的过程中,对照组的理论有一些做法,总结一下:
查看自动提交事务选项
show session variables like 'autocommit'; show global variables like 'autocommit’; set session autocommit=0; set global autocommit=0;
查看事务隔离等级
select @@tx_isolation
查看锁信息,想查看一条sql使用锁,需要打开锁监听
show session variables like '%output%'; #开启InnoDB锁监控 set global innodb_status_output_locks=on; set global innodb_status_output=on; #上面的语句可定期写入到标准错误输出(stderr,即error log,大概每15s写一次),你也可以使用 SHOW ENGINE INNODB STATUS 语句直接在客户端获取innodb信息 show session variables like '%output%';
要启用 InnoDB 锁定的 SHOW ENGINE INNODB STATUS 输出,立即启用 innodb状态output_locks
打开监控开关后,在mysql日志文件中会出现
===================================== 2020-06-30 15:44:46 7fdc8a76e700 INNODB MONITOR OUTPUT ===================================== ---------------------------- END OF INNODB MONITOR OUTPUT ============================
打开监控,可以确定一下常用锁的语句信息
执行完一条SQL,使用SHOW ENGINE INNODB STATUS打印出锁信息
delete from invoice_collection_info where id=1275244823997059072 TABLE LOCK table `assist`.`invoice_collection_info` trx id 1636893 lock mode IX RECORD LOCKS space id 18491 page no 211 n bits 104 index `PRIMARY` of table `assist`.`invoice_collection_info` trx id 1636893 lock_mode X locks rec but not gap
删除语句,根据主键操作;可以显示删除表锁IX模型,还有一个主键索引锁
就是如果有一段索引,所以会有第二次索引锁,但那是显示隐式的,后面没有显示锁式,后面会有试验让隐式锁化
使用第一索引删除操作
delete FROM invoice_item WHERE ( collection_id = 1275244823997059072 ); TABLE LOCK table `assist`.`invoice_item` trx id 1636964 lock mode IX RECORD LOCKS space id 18493 page no 4 n bits 784 index `idx_collection_id` of table `assist`.`invoice_item` trx id 1636964 lock_mode X locks rec but not gap Record lock, heap no 563 PHYSICAL RECORD: n_fields 2; compact format; info bits 0 0: len 8; hex 91b2946930001000; asc i0 ;; 1: len 8; hex 91b2ae5d61401000; asc ]a@ ;; RECORD LOCKS space id 18493 page no 12 n bits 96 index `PRIMARY` of table `assist`.`invoice_item` trx id 1636964 lock_mode X locks rec but not gap Record lock, heap no 28 PHYSICAL RECORD: n_fields 23; compact format; info bits 0
先在第一索引上加锁,再在的主键索引上加锁
使用第一索引查询
select * from invoice_collection_info where invoice_uiq_flag = '031001900104-62079412' for update TABLE LOCK table `assist`.`invoice_collection_info` trx id 1636947 lock mode IX RECORD LOCKS space id 18491 page no 642 n bits 344 index `idx_uniflag` of table `assist`.`invoice_collection_info` trx id 1636947 lock_mode X locks rec but not gap RECORD LOCKS space id 18491 page no 496 n bits 96 index `PRIMARY` of table `assist`.`invoice_collection_info` trx id 1636947 lock_mode X locks rec but not gap
从日志中,先在invoice_uiq_flg索引上加锁,再在主键加锁
使用主键更新操作
update invoice_collection_info set invoice_uiq_flag = '031200190010-62079412' WHERE ( id = 1275244823997059072 ); TABLE LOCK table `assist`.`invoice_collection_info` trx id 1636958 lock mode IX RECORD LOCKS space id 18491 page no 741 n bits 88 index `PRIMARY` of table `assist`.`invoice_collection_info` trx id 1636958 lock_mode X locks rec but not gap
这会在但主键加X,同时在同一索引上显示也加X,有一次没有出来;这里跟删除,其实也是个式锁
模拟测试,操作主键,更新索引列表删除,另一条使用记录类似死锁,把更新中的一段代码显示出来了
在RC等级下进行的操作,对于选择操作,读取结果都不会加锁,也不会加理论与理论