查看鎖記錄等待時間:
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 ) 帶條件復雜查詢,鎖表(
1、即使select子查詢用到了索引,也會鎖表;2、update連帶select子查詢的所有表都會加鎖,加鎖規則同上)
update 鎖表之后,如果insert是會受影響的(
唯一不受影響的是select 不帶for update語句)
測試方法:
打開查詢編輯器:
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;