MySQL server has gone away && Lost connection to MySQL server during query


 

問題一、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(...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM