这几天往sqlproxy中添加事务支持时发现服务端global/session的autocommit变量值与server返回的OK包中的值不一致。(当后端mysqld以autocommit=0启动的时候)
当客户端向mysqld发送select等查询语句的时候,mysqld会在结果集合的末尾返回一个EOF包;(正确处理时)
当客户端向mysqld发送insert等修改或管理语句的时候,mysqld会放回一个OK包;(正确处理时)
在EOF包与OK包中包含了server_status来标识当前连接对应的mysqld中的工作线程的一些状态信息,主要有:
(include/mysql_com.h)
#define SERVER_STATUS_IN_TRANS
1
#define SERVER_STATUS_AUTOCOMMIT
2
#define SERVER_MORE_RESULTS_EXISTS 8
#define SERVER_QUERY_NO_GOOD_INDEX_USED 16
#define SERVER_QUERY_NO_INDEX_USED
32
当mysqld中的工作线程写OK包或EOF包的时候,会把当前线程中的server_status写入包中, 以OK包为例:
下图的函数完成了OK包的封包工作,232行,该函数将当前THD对象中的server_status写入到包中。
然后我们来看看THD->server_status是怎么初始化的
(sql/sql_class.cc )
从929行可以看出, THD->server_status在初始化的时候就会把SERVER_STATUS_AUTOCOMMIT置1.
而对于server_status该位的修改只会在fix_autocommit中被更新,该函数在global/session的autocommit变量被变更是调用。
(sql/sys_vars.cc )
所以这就导致一个问题:THD->server_status中的SERVER_STATUS_AUTOCOMMIT与global/session中的autocommit变量值可能不一致(启动mysqld的时候以autocommit=0启动)。
注:转载注明来自高孝鑫的blog
当客户端向mysqld发送select等查询语句的时候,mysqld会在结果集合的末尾返回一个EOF包;(正确处理时)
当客户端向mysqld发送insert等修改或管理语句的时候,mysqld会放回一个OK包;(正确处理时)
在EOF包与OK包中包含了server_status来标识当前连接对应的mysqld中的工作线程的一些状态信息,主要有:
(include/mysql_com.h)
#define SERVER_STATUS_IN_TRANS
#define SERVER_STATUS_AUTOCOMMIT
#define SERVER_MORE_RESULTS_EXISTS 8
#define SERVER_QUERY_NO_GOOD_INDEX_USED 16
#define SERVER_QUERY_NO_INDEX_USED
当mysqld中的工作线程写OK包或EOF包的时候,会把当前线程中的server_status写入包中, 以OK包为例:
下图的函数完成了OK包的封包工作,232行,该函数将当前THD对象中的server_status写入到包中。
然后我们来看看THD->server_status是怎么初始化的
(sql/sql_class.cc )
从929行可以看出, THD->server_status在初始化的时候就会把SERVER_STATUS_AUTOCOMMIT置1.
而对于server_status该位的修改只会在fix_autocommit中被更新,该函数在global/session的autocommit变量被变更是调用。
(sql/sys_vars.cc )
所以这就导致一个问题:THD->server_status中的SERVER_STATUS_AUTOCOMMIT与global/session中的autocommit变量值可能不一致(启动mysqld的时候以autocommit=0启动)。
注:转载注明来自高孝鑫的blog