3 回答

TA貢獻(xiàn)1830條經(jīng)驗(yàn) 獲得超9個(gè)贊
正如在有關(guān)此問(wèn)題的眾多SO線程之一中提到的那樣:有時(shí)鎖定表的進(jìn)程顯示為在進(jìn)程列表中睡眠!我正在撕扯我的頭發(fā),直到我殺死所有在相關(guān)數(shù)據(jù)庫(kù)中打開(kāi)的睡眠線程(當(dāng)時(shí)沒(méi)有一個(gè)是活躍的)。最終解鎖了表并讓更新查詢運(yùn)行。
這位評(píng)論者說(shuō)了一句類(lèi)似于“有時(shí)一個(gè)MySQL線程會(huì)鎖定一個(gè)表,然后在等待與MySQL無(wú)關(guān)的事情發(fā)生時(shí)休眠?!?/p>
在重新審核show engine innodb status日志之后(一旦我跟蹤了負(fù)責(zé)鎖定的客戶端),我發(fā)現(xiàn)有問(wèn)題的卡住線程列在事務(wù)列表的最底部,位于即將發(fā)生錯(cuò)誤的活動(dòng)查詢下方由于凍結(jié)鎖定:
------------------
---TRANSACTION 2744943820, ACTIVE 1154 sec(!!)
2 lock struct(s), heap size 376, 2 row lock(s), undo log entries 1
MySQL thread id 276558, OS thread handle 0x7f93762e7710, query id 59264109 [ip] [database] cleaning up
Trx read view will not see trx with id >= 2744943821, sees < 2744943821
(不確定“Trx讀取視圖”消息是否與凍結(jié)鎖相關(guān),但與其他活動(dòng)事務(wù)不同,此消息不會(huì)顯示已發(fā)出的查詢,而是聲稱(chēng)事務(wù)處于“清理”狀態(tài),但具有多個(gè)行鎖)
故事的寓意是,即使線程處于休眠狀態(tài),事務(wù)也可以處于活動(dòng)狀態(tài)。

TA貢獻(xiàn)1784條經(jīng)驗(yàn) 獲得超2個(gè)贊
由于MySQL的普及,難怪鎖定等待超時(shí); 嘗試重啟事務(wù)異常得到如此多的關(guān)注SO。
您擁有的爭(zhēng)用越多,死鎖的可能性就越大,數(shù)據(jù)庫(kù)引擎將通過(guò)暫停其中一個(gè)死鎖事務(wù)來(lái)解決這個(gè)問(wèn)題。此外,已修改(例如UPDATE
或DELETE
)大量條目(如“ 高性能Java持久性”一書(shū)中所述,它采用鎖以避免臟寫(xiě)異常)的長(zhǎng)時(shí)間運(yùn)行事務(wù)更有可能與其他事務(wù)產(chǎn)生沖突。
雖然InnoDB MVCC,您仍然可以使用該FOR UPDATE
子句請(qǐng)求顯式鎖。但是,與其他流行的數(shù)據(jù)庫(kù)(Oracle,MSSQL,PostgreSQL,DB2)不同,MySQL 使用REPEATABLE_READ
默認(rèn)的隔離級(jí)別。
現(xiàn)在,您獲取的鎖(通過(guò)修改行或使用顯式鎖定)將在當(dāng)前運(yùn)行的事務(wù)期間保留。如果你想之間的差異的一個(gè)很好的解釋REPEATABLE_READ
,并READ COMMITTED
在問(wèn)候鎖定,請(qǐng)閱讀這篇文章的Percona。
在REPEATABLE READ中,在事務(wù)期間保持的每個(gè)鎖都在事務(wù)期間保持。
在READ COMMITTED中,在STATEMENT完成后釋放與掃描不匹配的鎖。
...
這意味著在READ COMMITTED中,一旦UPDATE語(yǔ)句完成,其他事務(wù)可以自由更新它們無(wú)法更新的行(在REPEATABLE READ中)。
隔離級(jí)別越嚴(yán)格(REPEATABLE_READ
,SERIALIZABLE
),死鎖的可能性就越大。這不是一個(gè)“本身”的問(wèn)題,這是一個(gè)權(quán)衡。
您可以獲得非常好的結(jié)果READ_COMMITED
,因?yàn)樵谑褂每缭蕉鄠€(gè)HTTP請(qǐng)求的邏輯事務(wù)時(shí),您需要應(yīng)用程序級(jí)丟失更新防護(hù)。在樂(lè)觀鎖定方法的目標(biāo)丟失更新,如果你使用的是甚至可能發(fā)生SERIALIZABLE
隔離級(jí)別,同時(shí)通過(guò)允許您使用減少了鎖爭(zhēng)用READ_COMMITED
。
添加回答
舉報(bào)