2012-03-28 46 views
1

我有一個Python腳本,有幾個線程通過隊列鏈接在一​​起。其中一個線程有一個MySQLdb連接,它在線程的init函數中以及線程主循環中的主循環中使用。如何在Python線程中解決這個奇怪的MySQL鎖定行爲?

現在腳本運行時,MySQLdb連接在線程的init部分中工作得很好。但是當它在線程的主循環中使用時,它會在self.cursor.execute(SQL)線路上完全死鎖。現在,當我在死鎖後點擊Ctrl-C時,事情變得更加怪異。死鎖然後被破壞,MySQLdb遊標得到它的結果,線程繼續正常,直到KeyboardInterupt被捕獲。

我在很多時候使用過相同的代碼,但這是我第一次使用MySQLdb。我以前從未遇到過這種行爲,而且我無法理解這裏發生了什麼。如果我有一些例外可以參考是一回事,但是沒有。另外,我不太明白爲什麼在我按Ctrl-C後self.cursor.execute(SQL)行實際返回正確的值。

我不能隨意展示實際的代碼,但相信我,這是完全沒有任何裝飾的直截了當。線程的主循環只是一個while循環,帶有一個帶有MySQLdb查詢的Queue get函數。它似乎不是一個SQL問題,因爲我已經嘗試了最簡單的SELECT 'hello'查詢,它仍然導致相同的行爲。

這種行爲的原因是什麼?

FWIW,我正在使用Python 2.7,並且我在OS X/Ubuntu 11.10上獲得了相同的行爲。

編輯:我開始懷疑這是否是由MySQL服務器設置造成的。我只是嘗試使用另一個Python MySQL庫(pymysql),它給出了相同的行爲。

EDIT2:我剛剛用慢日誌查詢的東西重新啓動MySQL服務器。奇怪的是,我可以看到其他查詢,但塊沒有顯示的查詢。

EDIT3:[求助]我發現this配方詳細說明如何查看線程是什麼。經過一些調試,很明顯罪魁禍首是MySQLdb模塊中的導入。然後,我簡單地在MySQLdb/cursors.py中註釋了第83-95行,它突然工作正常。我不認爲這些行很重要,因爲他們似乎只是提出了一些警告,我確信我正在運行的這些特定查詢的質量。

如果有人真的知道更強大的方式解決這個問題,我很樂意聽到它。

+0

你評論了什麼? – Adders 2017-02-25 14:03:59

+0

我通過降低我的'executemany()'語句的插入量來解決這個問題 - 我將其從'5000'插入到'1000'並且將其改爲停止 - 這只是使連接之間的事務更快 – Adders 2017-02-25 14:11:42

回答

1

也許你正在共享線程之間的連接。 MySQLdb documents建議

不要在 線程之間共享連接。這真的不值得你或我的努力,最後, 可能會損害性能,因爲MySQL服務器爲每個連接運行單獨的 線程。您當然可以做一些事情,例如在池中緩存 連接,並在 時間將這些連接提供給一個線程。如果讓兩個線程同時使用連接,MySQL客戶端庫可能會掛起並死亡。你一直在 警告。

+0

是的,我也讀過那部分。但我真的在線程之間共享連接嗎?我技術上只是在一個線程中使用它。或者我在這裏誤解了什麼? – c00kiemonster 2012-03-28 11:46:08