問題一、MySQL server has gone away
##### peewee from peewee import * from peewee import __exception_wrapper__ class RetryOperationalError(object): def execute_sql(self, sql, params=None, commit=True): try: cursor = super(RetryOperationalError, self).execute_sql(sql, params, commit) except OperationalError: if not self.is_closed(): self.close() with __exception_wrapper__: cursor = self.cursor() cursor.execute(sql, params or ()) if commit and not self.in_transaction(): self.commit() return cursor class RetryMySQLDatabase(RetryOperationalError, MySQLDatabase): def sequence_exists(self, seq): pass database = RetryMySQLDatabase(...) # 創建連接對象 # 代碼使用: 每次執行SQL前判斷連接是否關閉 def post(self): if database.is_closed(): database.connect() ... ##### pymysql def get_conn(): global conn global cur if conn is not None: try: conn.ping(True) return conn except Exception as e: logging.exception(e) try: conn = pymysql.Connect(host='主機名', user='用戶名', password='密碼', database='數據庫', port=3306, charset='utf8mb4', ) return conn except Exception as e: logging.exception(e) # 查詢數據 querystr ="SELECT * FROM t_user" get_conn() cur.execute(querystr) conn.commit() ### 原因 1、連接超時:當某個連接很久沒有發起新的數據庫操作,達到了MySQL的wait_timeout時,會被server端強行關閉,關閉之后再使用這個連接進行查詢,則會出現報錯信息,表現為第一天服務正常訪問,第二天無法訪問。 執行語句:show global variables like '%timeout'; wait_timeout的值則為連接無操作xxx秒后斷開連接 2、MySQL宕機:執行語句,show global status like 'uptime'; 查看MySQL的運行時長,uptime數值越大,MySQL的運行時間越長。 3、查詢結果集過大:執行語句,show global variables like 'max_allowed_packet'; 查看結果集的最大大小限制,會伴隨‘ Your SQL statement was too large.’的報錯,需優化SQL語句,或修改此參數的值。set global max_allowed_packet=1024*1024*16; 4、還有一種情況是:SQL語句過長也可能報這個錯誤,不知道為啥~~~ ### 解決 1、延長數據庫的連接時長,修改wait_timeout的值,不推薦。 2、代碼當中修改:每次執行SQL語句前,先判斷連接是否有效,無效則重新連接
問題二、pymysql.err.InterfaceError: (0, '')
# 原因一: mysql 連接自己給關閉導致的,對任何已經close的conn進行db相關操作,包括ping()都會爆出這個錯誤。 若出現了問題一的錯誤但未及時解決,仍然訪問服務,會出現這個錯誤,因為使用了已經關閉的連接。 # 原因二: 數據庫操作對象實例未注銷,但是持有的數據庫連接已經過期,導致后續數據庫操作不能正常進行 # 原因三: 數據庫連接代碼在函數外 # 原因四: 連接MySQL之后沒有關閉連接的操作,短時間內不會出問題,長時間保持這個連接會出現連接混亂 # 以下代碼會直接拋出異常無法執行except代碼段 try: db.ping(reconnect=True) except: db = pymysql.connection(..) findlly: cursor = db.cursor() cursor.execute(sql) # 轉載 class DataSource(object): def __init__(self): self.conn = self.to_connect() def __del__(self): self.conn.close() def to_connect(self): return pymysql.connections.Connection(params) def is_connected(self): """Check if the server is alive""" try: self.conn.ping(reconnect=True) print("db is connecting") except: traceback.print_exc() self.conn = self.to_connect() print("db reconnect")
問題三、pymysql.err.OperationalError: (2013,
Lost connection to MySQL server during query')
# 每次執行數據庫操作前執行,待補充
def reConnect(self): try: db.ping() except: db = pymysql.connect(...)