2010-11-12 96 views
0

我有一個查詢,我每天運行一次,從我的數據庫中取出某些表並將它們放到一個表中,以便我可以快速導出我需要的任何格式的信息。有沒有辦法在MySQL中沒有鎖定?

我遇到然而一個問題,使我有以下錯誤:「SQLSTATE [40001]:序列化失敗:1213死鎖發現試圖獲取鎖時,請嘗試重新啓動交易」

從我知道這聽起來就像我的查詢試圖在已經存在鎖定的情況下獲取表上的鎖定。然而我承認,我不知道任何關於表鎖定或它是如何工作的。

真的,我只是想讀其他表,而不寫給他們,有沒有辦法,我可以創建查詢,但不要求鎖?

我的查詢很可笑,所以這就是爲什麼我沒有發佈它。如果有某些部分需要告訴我,我可以發佈。

+0

表的類型? InnoDB或MyISAM? – razzed 2010-11-12 16:13:44

+0

這些表都是InnoDB。 – 2010-11-12 16:22:47

回答

2

你可以嘗試使用INSERT DELAYED,這裏是做什麼的:

When a client uses INSERT DELAYED, it gets an okay from the server at once, and the row is queued to be inserted when the table is not in use by any other thread.

如果你願意看到在混合狀態下的數據,您可以更改事務隔離級別

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; 
-- Problematic SELECT query goes here -- 
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; 

我瞭解到另一個SO的答案by Jon Erickson

+0

這不適用於InnoDB表,因爲它們不支持INSERT DELAYED。 – 2011-09-11 16:38:15

2

如果您處於事務隔離模式REPEATABLE_READ(這是默認值),則選擇應該不創建任何鎖。這個是正常的。

但是,如果你使用插入...當然選擇你會在目標表中鎖定。

因此,如果沒有其他人正在寫入目標表,並且一次運行程序的最多隻有一個副本,則永遠不會發生死鎖。

當兩個(或更多)進程嘗試執行永遠不會完成的衝突事件時,會發生死鎖。通常這涉及以不同順序更新同一對行,但它可能取決於您的表結構。

思路來考慮:

  • 使用外置鎖(InnoDB的),以
  • 更改事務隔離模式連載過程中對多個副本READ_COMMITTED此操作 - 如果你明白這是什麼意思,並能容忍它。
  • 在一個事務(提交更加頻繁)

你可以看到參與死鎖的交易是幹什麼的,用SHOW ENGINE INNODB STATUS,僵局後少做工作。

你應該能夠看到其他過程是什麼以及他們在做什麼。考慮打開一般日誌或使用其他調試技術。

一定要在非生產系統中進行任何測試!