报错如下:
(0, '')
分析:
在网上搜了这个报错,是说因为mysql client的连接实例虽然还在,但因为client和server已经太久没有通信,所以server已经把连接关了,所以client连不上了。也就是如果不用的时候就应该把连接关掉才对,这种不合理的闲置连接超出了server的wait_timeout时间。
代码里是因为在循环里该break的地方写成continue了,就没有适时地释放对象、关闭连接。。
复现:
-
启动本地
mysql server -
设置
wait_timeout=10(默认值是28800)
import pymysql.cursors
connect = pymysql.Connect(host='127.0.0.1', user='root', passwd='root')
cursor = connect.cursor()
# set value to 10
cursor.execute("set global wait_timeout = 10")
connect.close()
connect = pymysql.Connect(host='127.0.0.1', user='root', passwd='root')
cursor = connect.cursor()
cursor.execute("show variables like 'wait_timeout'")
ret_wait = cursor.fetchone()
print(f"after change: {ret_wait}")
- 模拟在循环里持有数据库连接并闲置超过10秒,然后再查数据库,就看到了这个报错
import time
import pymysql
class DBHelper:
def __init__(self, host, user, passwd, port=3306):
print('DBHelper init')
self.db = pymysql.Connect(host=host, port=port, user=user, passwd=passwd)
def query(self, sql):
try:
cursor = self.db.cursor()
cursor.execute(sql)
rows = cursor.fetchall()
except Exception as e:
raise e
else:
return rows
class QueryWrapper:
def __init__(self):
self.mars6_db = DBHelper(
'127.0.0.1',
'root',
'root'
# port is default to 3306
)
def query_test(self):
try:
sql = f"select id from test.person where id=1;"
rows = self.mars6_db.query(sql)
return rows[0][0]
except Exception as e:
print(f"query_test error, {e}")
return -1
class Slave:
def __init__(self):
self.utils = QueryWrapper()
def problem(self):
count = 15
while True:
time.sleep(1)
count -= 1
try:
if count > 0:
print('no task...')
time.sleep(1)
continue # SHOULD break here
r = self.utils.query_test()
print(f'task result: {r}')
except Exception as e:
print(e)
break
def job():
daily_classifier_slave = Slave()
daily_classifier_slave.problem()
if __name__ == '__main__':
while True:
job()
print('sleep...')
time.sleep(5)