最近项目中用到了mysql-proxy,在次记录遇到的问题
环境:python2.7+django1.11
0.使用proxy无法查询,解决办法
https://github.com/ssjunior/django/commit/52bf6c7630ab6b17a3a3ff64213e1ad36d6fe270
1.使用django.db connections 经常报错mysq has gone away
这个错误网上很多博客都有在讲,但是这里似乎是bug
代码如下
from django.db import connections
with connections['dbname'].cursor() as cursor:
cursor.execute(select_str)
columns = [col[0] for col in cursor.description]
event_logs = [
dict(zip(columns, row))
for row in cursor.fetchall()
]
处理错误,外层加个try 连后retry一次
def close_old_connections():
# reconnect mysql if the old connection timeout; do nothing if connection is ok
for conn in connections.all():
conn.close_if_unusable_or_obsolete()
观察发现大约50%的请求都会报这个错误,这很明显有问题,水平有限不知道具体原因,切换了其他连接方式
import MySQLdb
from MySQLdb.cursors import DictCursor
from DBUtils.PooledDB import PooledDB
from settings import DB_NAME, DB_HOST, DB_PASSWORD, DB_PORT, DB_USER
class Mysql(object):
__pool = None
def __init__(self):
self._conn = Mysql.__getConn()
self._cursor = self._conn.cursor()
@staticmethod
def __getConn():
if Mysql.__pool is None:
DBCHAR = "utf8"
__pool = PooledDB(creator=MySQLdb, mincached=1, maxcached=20,
host=DB_HOST, port=int(DB_PORT), user=DB_USER,
passwd=DB_PASSWORD,
db=DB_NAME, use_unicode=False, charset=DBCHAR,
cursorclass=DictCursor)
return __pool.connection()
def getAll(self, sql, param=None):
if param is None:
count = self._cursor.execute(sql)
else:
count = self._cursor.execute(sql, param)
if count > 0:
result = self._cursor.fetchall()
else:
result = False
return result
切换到这种方式后没有再报错
另外,使用proxy过程经常遇到写入进程卡死,通过火焰图分析,发现程序耗时在创建连接,说明连接创建有问题,查看过mysql状态一切正常,处理方式是重启proxy后端mysql db 或者重启 写进程,这个问题目前仍未解决
2021-07-13更新
该问题已于2021年3月解决,原因是数据库连接过多,达到三四百,将数据库连接优化到一百以内后,没有再出现过