Mysql的timeout以及python重連方式
問題
近期使用多線程對(duì)數(shù)據(jù)庫(kù)操作報(bào)錯(cuò):
(2013, 'Lost connection to MySQL server during query')
解決方案
1. 更改timeout參數(shù)
出現(xiàn)這個(gè)問題順便就了解了一下mysql中的timeout都有什么:
mysql> show variables like '%timeout%'; +-----------------------------+----------+ | Variable_name | Value | +-----------------------------+----------+ | connect_timeout | 10 | | delayed_insert_timeout | 300 | | have_statement_timeout | YES | | innodb_flush_log_at_timeout | 1 | | innodb_lock_wait_timeout | 50 | | innodb_rollback_on_timeout | OFF | | interactive_timeout | 28800 | | lock_wait_timeout | 31536000 | | net_read_timeout | 30 | | net_write_timeout | 60 | | rpl_stop_slave_timeout | 31536000 | | slave_net_timeout | 60 | | wait_timeout | 28800 | +-----------------------------+----------+ 13 rows in set (0.06 sec)
很多參數(shù),網(wǎng)上對(duì)于connection lost這個(gè)問題有說改wait_timout也有說net_read_timeout和net_write_timeout的。
那么他們之間到底有什么區(qū)別呢?
簡(jiǎn)單來說:
- wait_timeout代表的是前一個(gè)sql操作和下一個(gè)sql操作的間隔。
- net_read_timeout和net_write_timeout涉及到網(wǎng)絡(luò)傳輸中的包的問題。通常情況下,一個(gè)sql語(yǔ)句由多個(gè)包組成??蛻舳藢⒁粋€(gè)一個(gè)包傳給服務(wù)端,然后在服務(wù)端再將包組合起來變?yōu)閟ql語(yǔ)句執(zhí)行。如果網(wǎng)絡(luò)情況太差,導(dǎo)致包遲遲不全,無法組成一個(gè)完整的可執(zhí)行語(yǔ)句,mysql服務(wù)端就會(huì)放棄這個(gè)語(yǔ)句的執(zhí)行。而這個(gè)等待時(shí)間就是net_read/write_timeout。
- read是服務(wù)器從客戶端讀取;write是服務(wù)器向客戶端寫。
- 這兩個(gè)參數(shù)都是session level的,可以在每次連接的時(shí)候?qū)ζ溥M(jìn)行更改。
- 此外,需要注意的是,如果問題出在傳輸執(zhí)行一個(gè)sql的過程中時(shí),使用ping是無法解決的。Mysql協(xié)議不允許客戶端在一次性數(shù)據(jù)沒有傳輸完畢的時(shí)候,向服務(wù)器傳輸其他的請(qǐng)求。(python里面的處理就是,如果使用了ping就自動(dòng)斷開了本次的執(zhí)行操作)
This for example typical cause of aborted connections while using Sphinx with large data sets and large buffers. While indexing Sphinx performs sorts and flushes buffers to the disk every so often which can take long enough to trigger default net_write_timeout on the server side.
You could ask why server does not do any flow control and can’t find out client just is just busy and it is not network issue – well this comes from simplicity of MySQL protocol which does not allow client to talk to the server until full result set is fetched. This is also the reason why you can’t stop fetching for ordinary statements and mysql_free_result will have to complete the fetch internally.
Is there any way to tell the server you need more time besides increasing net_write_timeout ? Not what I know of. You can’t use something like mysql_ping because connection is in the stage of getting the data. You can’t even fetch couple of rows every few seconds to show you’re fetching data because there is buffering happening inside MySQL client library so you never know when real network read will happen.
具體改什么還要視自己的情況而定:
詳細(xì)的net write timeout和wait timeout的比較
2. 測(cè)試連接,并將斷開的連接重新連接
還有另一個(gè)辦法,python使用ping()方法測(cè)試連接。
但是要注意ping方法不能在使用流式游標(biāo)進(jìn)行迭代獲取數(shù)據(jù)的過程中用,
否則會(huì)報(bào)錯(cuò):
UserWarning: Previous unbuffered result was left incomplete warnings.warn("Previous unbuffered result was left incomplete")
ping()應(yīng)用于兩個(gè)sql語(yǔ)句執(zhí)行之間進(jìn)行查詢,
這個(gè)檢查是為了應(yīng)付由于超出wait_timeout(而非net_read/write_timeout)服務(wù)器自動(dòng)斷開鏈接的。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
解決MySQL數(shù)據(jù)庫(kù)中文模糊檢索問題的方法
解決MySQL數(shù)據(jù)庫(kù)中文模糊檢索問題的方法...2007-11-11mysql如何通過當(dāng)前排序字段獲取相鄰數(shù)據(jù)項(xiàng)
這篇文章主要介紹了mysql如何通過當(dāng)前排序字段獲取相鄰數(shù)據(jù)項(xiàng),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05mysql8.0?.ibd文件恢復(fù)表結(jié)構(gòu)的實(shí)現(xiàn)
本文主要介紹了mysql8.0?.ibd文件恢復(fù)表結(jié)構(gòu)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-10-10Advanced SQL Injection with MySQL
Advanced SQL Injection with MySQL...2006-12-12MySQL特定表全量、增量數(shù)據(jù)同步到消息隊(duì)列-解決方案
mysql要同步原始全量數(shù)據(jù),也要實(shí)時(shí)同步MySQL特定庫(kù)的特定表增量數(shù)據(jù),同時(shí)對(duì)應(yīng)的修改、刪除也要對(duì)應(yīng),下面就為大家分享一下2021-11-11