SHOW ENGINE INNODB STATUS;來查看死鎖日志:
SHOW PROCESSLIST;查看進(jìn)程
MySQL的InnoDB引擎事務(wù)有4種隔離級(jí)別,主要是為了保證數(shù)據(jù)的一致性。
InnoDB引擎提供了行級(jí)鎖,表鎖。MyISAM提供了表鎖,如題,MySQL會(huì)發(fā)生死鎖嗎?
會(huì),在InnoDB引擎下,RR(REPEATABLE-READ)級(jí)別,如果多個(gè)事務(wù)爭(zhēng)搶同一個(gè)資源,會(huì)發(fā)生死鎖。在RR級(jí)別下,MySQL提供了next-key lock。假如一個(gè)索引的行有10,11,13,20
那么可能的next-key lock的包括:
(無窮小, 10]
(10,11]
(11,13]
(13,20]
(20, 無窮大)
即:當(dāng)你查詢12時(shí),如果數(shù)據(jù)未查到,那么將對(duì)(12,13]范圍內(nèi)的數(shù)據(jù)進(jìn)行鎖定。next-key lock的定義可以到官方具體查看,這里做個(gè)演示。
CREATE TABLE `user` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(200) DEFAULT NULL, `age` int(11) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1111 DEFAULT CHARSET=utf8;
//查看隔離級(jí)別,show variables like '%tx_isolation%';// 設(shè)置隔離界別SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}// 不設(shè)置自動(dòng)提交SET autocommit = 0;
首先將隔離級(jí)別都設(shè)置為RR級(jí)別的,并且不讓事務(wù)自動(dòng)提交
根據(jù)上面的數(shù)據(jù),在事務(wù)1中查詢
// 得到空結(jié)果集,此時(shí)鎖定的范圍是(33,100]select * FROM user where id=33 for update;
在事務(wù)2中也進(jìn)行查詢
// 查詢到空的結(jié)果,在事務(wù)2中鎖定的范圍是(34,100]select * FROM user where id=34 for update
在事務(wù)1中插入數(shù)據(jù)
// 雖然事務(wù)1鎖定了范圍,事務(wù)2也鎖定了范圍insert into user values(35,'ac',10);
在事務(wù)2中也插入數(shù)據(jù)
insert into user values(34,'ac',10)
可以發(fā)現(xiàn)已經(jīng)發(fā)生了死鎖
設(shè)置死鎖的超時(shí)時(shí)長(zhǎng)
innodb_lock_wait_timeout=500
查詢到當(dāng)前正在鎖定的事務(wù)線程,將其殺死
// 可以看到正在運(yùn)行的事務(wù)線程,還有運(yùn)行狀態(tài)SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;//trx_mysql_thread_id為上一條命令獲取的結(jié)果,將具體的數(shù)字替換一下即可。kill trx_mysql_thread_id
聯(lián)系客服