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;


### 解决
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(...)

猜你喜欢

转载自www.cnblogs.com/hsmwlyl/p/11424768.html
今日推荐