mysql建立的連接配接,在8小時内都沒有通路請求的話,mysql server将主動斷開這條連接配接。在使用pymysql或MySQLdb操作資料庫連接配接時,當cursor一直處于連接配接狀态,未及時close時,連接配接池被占用。檢視背景日志:
"MySQL server has gone away (%r)" % (e,))
pymysql.err.OperationalError: (2006, "MySQL server has gone away (TimeoutError(110, 'Connection timed out'))")
def db_execute(query):
conn = MySQLdb.connect(*)
cur = conn.cursor()
cur.execute(query)
res = cur.fetchall()
cur.close()
conn.close()
return res
class MysqlConnect(object):
"""
mysql connect 基類
"""
def __init__(self, db_params=cmdb_test_params, maxconn=5):
self.db_params = db_params
self.maxconn = maxconn
self.pool = Queue(maxconn)
for i in range(maxconn):
self.connect = self._connect()
self.commit()
self.cursor = self._cursor()
def _connect(self):
"""
mysql connect
:return cursor:
"""
key = ['host', 'port', 'user', 'password', 'database', 'charset']
if not all([True if k in self.db_params else False for k in key]):
raise Exception(list(self.db_params.keys()), "資料庫連接配接失敗,請檢查配置參數")
try:
conn = pymysql.connect(**self.db_params)
conn.autocommit(True)
self.pool.put(self.connect)
except pymysql.Error as e:
logutil.Logger().error(e)
traceback.print_exc()
raise pymysql.Error("連接配接資料庫失敗 %s" % e)
self.connect = conn
return self.connect
def _cursor(self):
if self.connect:
conn = self.pool.get()
self.cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
else:
self._connect()
conn = self.pool.get()
self.cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
return self.cursor
def close(self):
if self.connect:
self.cursor.close() # 關閉遊标,未及時close時,連接配接池被占用 error code 2006
self.pool.put(self.connect)
self.connect = None
def commit(self):
try:
if self.connect:
self.connect.autocommit(True)
except pymysql.Error as e:
logutil.Logger().error(e)
traceback.print_exc()
raise pymysql.Error("資料庫送出失敗 %s" % e)
finally:
self.close()
def rollback(self):
try:
if self.connect:
self.connect.rollback()
except pymysql.Error as e:
logutil.Logger().error(e)
traceback.print_exc()
raise pymysql.Error("資料庫復原失敗 %s" % e)
finally:
if self.connect:
self.close()
def __del__(self):
self.commit()
def query_execute(self, sql):
try:
if self.connect is None:
self._connect()
self._cursor()
result_list = []
self.cursor.execute(sql)
for row in self.cursor.fetchall():
result_list.append(list(row))
return result_list
except pymysql.Error as e:
logutil.Logger().error(e)
traceback.print_exc()
raise pymysql.Error("資料庫查詢失敗 %s" % e)
finally:
if self.connect:
self.close()
def dml_execute(self, sql):
try:
if self.connect is None:
self._connect()
self._cursor()
if self.cursor is None:
self._cursor()
self.cursor.execute(sql)
self.commit()
except pymysql.Error as e:
logutil.Logger().error(e)
traceback.print_exc()
self.rollback()
raise pymysql.Error("資料庫執行dml失敗 %s" % e)
finally:
self.close()
def dml_execute_many(self, sql):
try:
if self.connect is None:
self._connect()
self._cursor()
if self.cursor is None:
self._cursor()
self.cursor.executemany(sql)
self.commit()
except pymysql.Error as e:
logutil.Logger().error(e)
traceback.print_exc()
self.rollback()
raise pymysql.Error("資料庫執行dml失敗 %s" % e)
finally:
self.close()
def testmysqldb(self,ip,user,password,dbname,Strsql):
try:
self.connect = pymysql.connect(host=ip,user=user,passwd=password,charset='utf8')
self.connect.select_db(dbname)
self.query_execute(Strsql)
return True
except Exception as e:
print(("Error %d :%s" %(e.args[0],e.args[1])))
return False