mysql 死鎖解決

查看鎖記錄等待時間:
SHOW VARIABLES LIKE 'innodb_lock_wait_timeout';
把超時等待時間修改成5秒: SET innodb_lock_wait_timeout=5;
 
注意行鎖和表鎖:mysql innodb存儲引擎支持行鎖
select 不會鎖表,已經產生鎖的表也不影響查詢,除非select xxx for update;由於 for update會請求加鎖
update xxx 不帶where條件,鎖表(已驗證)
update xxx where 帶條件,鎖指定行( 必須知足where條件只要有一個條件用上索引,不然行鎖變成表鎖)
update xxx where id in ( select id from xxx ) 帶條件複雜查詢,鎖表( 一、即便select子查詢用到了索引,也會鎖表;二、update連帶select子查詢的全部表都會加鎖,加鎖規則同上)
測試方法:
打開查詢編輯器:
set autocommit = 0;只針對當前鏈接
相關測試語句
commit;
新開鏈接,打開查詢編輯器:
相關語句
 
結論:不帶where 條件鎖表,帶where條件不帶索引鎖表,嵌套子查詢連帶加鎖
鎖表主要針對insert update remove,基本上不影響select除非,手動加for update請求加鎖
 
查看事務提交模式:
show session variables like 'autocommit';
show global variables like 'autocommit';
Value的值爲ON,表示autocommit開啓。OFF表示autocommit關閉。
 
查看mysql存儲引擎模式:
SHOW ENGINES;
InnoDB DEFAULT Supports transactions, row-level locking, and foreign keys
 
 
死鎖1:
高併發狀況下,insert 使用 where 會死鎖,列如:
insert into aut_sign_heartbeat
(
?
)
SELECT
?
FROM DUAL
WHERE NOT EXISTS(
SELECT id FROM aut_sign_heartbeat WHERE CRIMINAL_ID = #{criminalId} AND DEVICE_TYPE=#{deviceType} AND create_time = #{createTime}
)
 
死鎖解決:
SELECT * FROM information_schema.INNODB_TRX;
trx_rows_locked: 事務鎖定行數
trx_rows_modified: 事務修改行數
#首先查詢是否鎖表
SHOW OPEN TABLES WHERE In_use > 0;
#查詢進程,保證擁有超級管理員權限
SHOW PROCESSLIST;
#殺死進程
KILL 4503;
#查看正在鎖的事務
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
#查看等待鎖的事務
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
相關文章
相關標籤/搜索