问题一、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(...)