注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

^_^ china.ygw的博客

软件开发/c/c++/数据库/开源/linux/windows/安全/网络...

 
 
 

日志

 
 
 
 

MySQL 5.5启用二进制日志造成的触发器查询死锁  

2012-01-06 20:36:28|  分类: mysql |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

        前一段时间,在使用mysql时遇到一个很奇怪的死锁问题,环境描述如下:

        1)MySQL 5.5任意版本(不区分Linux或Windows);

        2)数据表为innodb;

        3)MySQL启用二进制日志文件,其格式为statement或mixed,对应my.cnf文件“[mysqld]”区中配置信息如下:

             log-bin=mysql-bin
             binlog_format=mixed     或者     statement

        3)表test1与表test2分别存在主键,且各自存在before update触发器,触发器内容为依据主键读对方表的数据;

        4)相关SQL语句如下:

             drop table if exists tbl_test1;
             create table tbl_test1(
                    id int unsigned not null primary key,
                    name varchar(256) not null
            )engine=innodb;

 

            drop trigger if exists trigger_test1;
            delimiter //
            create trigger trigger_test1 before update on tbl_test1 for each row
            begin
                  declare var_id int unsigned default null;
                  select id into var_id from tbl_test2 where id = 1;
            end //
            delimiter ;

 

            insert into tbl_test1 values(1, 'name 1');

 

            drop table if exists tbl_test2;
            create table tbl_test2(
                  id int unsigned not null primary key,
                  age int unsigned not null
            )engine=innodb;

 

            drop trigger if exists trigger_test2;
            delimiter //
            create trigger trigger_test2 before update on tbl_test2 for each row
            begin
                   declare var_id int unsigned default null;
                   select id into var_id from tbl_test1 where id = 1;
            end //
            delimiter ;

 

            insert into tbl_test2 values(1, 11);

       在如上环境中,登录mysql会话1,执行命令如下:

               set autocommit=0;
               update tbl_test1 set name='name 111' where id = 1;

       另开mysql会话2,招行命令如下:

               set autocommit=0;
               update tbl_test2 set age=111 where id = 1;

       此时发现会话2在执行update语句时一直处于等待状态。按道理,这两个会话不会造成该结果,因为查询不会加锁,能够立即返回。如果此时再开mysql会话3,执行与会话1一样的命令,在会话1中手工执行“commit”后,会话3会输出死锁提示,如下:

               ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

       死锁就这么产生了。

       但是MySQL 5.1版本没有该问题,另外MySQL 5.5版本的二进制日志格式使用row时也没有该问题。看来,这是MySQL 5.5使用statement格式二进制日志造成的问题,因为mixed格式二进制日志是依据实际情况自动选择row与statement。

  评论这张
 
阅读(885)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018