|
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; image-20190304142624761//查看隔離級(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); image-20190304143355381在事務(wù)2中也插入數(shù)據(jù)
insert into user values(34,'ac',10) image-20190304143707234可以發(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
來源:http://www./content-2-132051.html
|