给Python中的MySQLdb模块添加超时功能的教程


Posted in Python onMay 05, 2015

使用Python操作MySQL数据库的时候常使用MySQLdb这个模块。

今天在开发的过程发现MySQLdb.connect有些参数没法设置。通过这个页面我们可以看到在connect的时候,可以设置的option和client_flags和MySQL c api相比差不少。

一个很重要的参数 MYSQL_OPT_READ_TIMEOUT没法设置,这个参数如果不设置,极致状况MySQL处于hang住,自动切换IP漂移,客户端无法重连到新MySQL。

给MySQLdb加Option很简单,只要修改_mysql.c这个把Python对象映射到MySQL操作的文件,添加参数,再加一段mysql_option即可。

下面是修改后的git diff 文件

?View Code BASH

diff --git a/_mysql.c b/_mysql.c
index d42cc54..61a9b34 100644
--- a/_mysql.c
+++ b/_mysql.c
@@ -489,9 +489,10 @@ _mysql_ConnectionObject_Initialize(
"named_pipe", "init_command",
"read_default_file", "read_default_group",
"client_flag", "ssl",
-                 "local_infile",
+                 "local_infile", "read_timeout",
NULL } ;
int connect_timeout = 0;
+    int read_timeout = 0;
int compress = -1, named_pipe = -1, local_infile = -1;
char *init_command=NULL,
*read_default_file=NULL,
@@ -500,7 +501,7 @@ _mysql_ConnectionObject_Initialize(
self->converter = NULL;
self->open = 0;
check_server_init(-1);
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ssssisOiiisssiOi:connect",
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ssssisOiiisssiOii:connect",
kwlist,
&host, &user, &passwd, &db,
&port, &unix_socket, &conv,
@@ -509,7 +510,8 @@ _mysql_ConnectionObject_Initialize(
&init_command, &read_default_file,
&read_default_group,
&client_flag, &ssl,
-                    &local_infile /* DO NOT PATCH FOR RECONNECT, IDIOTS
+                    &local_infile, &read_timeout
+                    /* DO NOT PATCH FOR RECONNECT, IDIOTS
IF YOU DO THIS, I WILL NOT SUPPORT YOUR PACKAGES. */
))
return -1;
@@ -540,6 +542,12 @@ _mysql_ConnectionObject_Initialize(
mysql_options(&(self->connection), MYSQL_OPT_CONNECT_TIMEOUT,
(char *)&timeout);
}
+
+    if (read_timeout) {
+        unsigned int timeout = read_timeout;
+        mysql_options(&(self->connection), MYSQL_OPT_READ_TIMEOUT, (char *)&timeout);
+    }
+
if (compress != -1) {
mysql_options(&(self->connection), MYSQL_OPT_COMPRESS, 0);
client_flag |= CLIENT_COMPRESS;

代码修改完毕,python setup.py install 即可,如果出现mysql_config找不到的问题。你还要修改setup_posix.py文件。

hoterran@hoterran-laptop:~/Projects/MySQL-python-1.2.3$ git diff setup_posix.py
diff --git a/setup_posix.py b/setup_posix.py
index 86432f5..f4f08f1 100644
--- a/setup_posix.py
+++ b/setup_posix.py
@@ -23,7 +23,7 @@ def mysql_config(what):
     if ret/256 > 1:
       raise EnvironmentError("%s not found" % (mysql_config.path,))
   return data
-mysql_config.path = "mysql_config"
+mysql_config.path = "/usr/local/mysql/bin/mysql_config"

 def get_config():
   import os, sys

编译通过,我们来试试添加的read_timeout这个参数。

conn = MySQLdb.connect(host = DB_SERVER,user = DB_USERNAME,passwd = DB_PASSWORD,db = DB_NAME, port=int(DB_PORT), client_flag = 2, read_timeout = 10)

然后执行语句前,你试着把mysql用gdb hang住10s后,python就会异常抛错

OperationalError: (2013, 'Lost connection to MySQL server during query')
 >/home/hoterran/Projects/dbaas/trunk/dbtest.py(18)()
 >mydb.execute_sql(conn, sql)
(Pdb)
--Return--
> /home/hoterran/Projects/dbaas/trunk/dbtest.py(18)()->None
> mydb.execute_sql(conn, sql)
(Pdb)
OperationalError: (2013, 'Lost connection to MySQL server during query')
> <string>(1)<module>()->None

Python 相关文章推荐
python实现简单淘宝秒杀功能
May 03 Python
python 实现得到当前时间偏移day天后的日期方法
Dec 31 Python
Python基础之循环语句用法示例【for、while循环】
Mar 23 Python
Pyqt5实现英文学习词典
Jun 24 Python
python爬虫 execjs安装配置及使用
Jul 30 Python
Flask中endpoint的理解(小结)
Dec 11 Python
python Qt5实现窗体跟踪鼠标移动
Dec 13 Python
python飞机大战pygame游戏背景设计详解
Dec 17 Python
Python爬虫解析网页的4种方式实例及原理解析
Dec 30 Python
pytorch:实现简单的GAN示例(MNIST数据集)
Jan 10 Python
python中random.randint和random.randrange的区别详解
Sep 20 Python
python学习之panda数据分析核心支持库
May 07 Python
用Python实现一个简单的多线程TCP服务器的教程
May 05 #Python
简单介绍Python中的try和finally和with方法
May 05 #Python
python中的闭包用法实例详解
May 05 #Python
Python闭包实现计数器的方法
May 05 #Python
深入探究Python中变量的拷贝和作用域问题
May 05 #Python
Python使用metaclass实现Singleton模式的方法
May 05 #Python
python中查看变量内存地址的方法
May 05 #Python
You might like
星际争霸任务指南——虫族
2020/03/04 星际争霸
php生成的html meta和link标记在body标签里 顶部有个空行
2010/05/18 PHP
WordPress中给媒体文件添加分类和标签的PHP功能实现
2015/12/31 PHP
JavaScript获取指定元素位置的方法
2015/04/08 Javascript
浅谈Javascript线程及定时机制
2015/07/02 Javascript
JQuery操作textarea,input,select,checkbox方法
2015/09/02 Javascript
详解AngularJS Filter(过滤器)用法
2015/12/28 Javascript
基于Bootstrap实现图片轮播效果
2016/05/22 Javascript
easyUI实现(alert)提示框自动关闭的实例代码
2016/11/07 Javascript
Vue.JS入门教程之自定义指令
2016/12/08 Javascript
nodejs实现爬取网站图片功能
2017/12/14 NodeJs
基于百度地图api清除指定覆盖物(Overlay)的方法
2018/01/26 Javascript
详解js的视频和音频采集
2018/08/09 Javascript
详解使用Nuxt.js快速搭建服务端渲染(SSR)应用
2019/03/13 Javascript
浅谈KOA2 Restful方式路由初探
2019/03/14 Javascript
微信小程序实现传递多个参数与事件处理
2019/08/12 Javascript
使用jQuery实现掷骰子游戏
2019/10/24 jQuery
Python获取单个程序CPU使用情况趋势图
2015/03/10 Python
Python实现的概率分布运算操作示例
2017/08/14 Python
python 列表,数组,矩阵两两转换tolist()的实例
2018/04/04 Python
python读取视频流提取视频帧的两种方法
2020/10/22 Python
Python按钮的响应事件详解
2019/03/04 Python
关于Python 的简单栅格图像边界提取方法
2019/07/05 Python
pytorch 使用加载训练好的模型做inference
2020/02/20 Python
python实现猜单词游戏
2020/05/22 Python
Python如何急速下载第三方库详解
2020/11/02 Python
PHP经典面试题
2016/09/03 面试题
android面试问题与答案
2016/12/27 面试题
2014年两会学习心得体会
2014/03/17 职场文书
水电工程师岗位职责
2015/02/13 职场文书
你会写报告?产品体验报告到底该怎么写?
2019/08/14 职场文书
浅谈JS和Nodejs中的事件驱动
2021/05/05 NodeJs
php去除deprecated的实例方法
2021/11/17 PHP
JavaScript选择器函数querySelector和querySelectorAll
2021/11/27 Javascript
Win10防火墙白名单怎么设置?Win10添加防火墙白名单方法
2022/04/06 数码科技
BCL经典机 SONY ICF-5900W电路分析
2022/04/24 无线电