MySQL使用可重复读作为默认隔离级别的原因(2)

由上可知,在MySQL 5.1及以上的RC隔离级别下,语句级BinlogDR上执行的结果是不正确的!

那么,MySQL 5.0呢?5.0允许RC下语句级Binlog,是不是说很容易产生DB/DR不一致呢?

事实上,在5.0重复上述一个测试,并不存在这个问题,原因是5.0RC5.1RR使用类似的并发和上锁机制,也就是说,MySQL 5.0RC5.1及以上的RC可能存在兼容性问题

下面看看RR是怎么解决这个问题的。

2. 默认隔离级别-可重复读

导致RC隔离级别DB/DR不一致的原因是:RC不可重复读,而Binlog要求SQL串行化!

RR下,重复以上测试

会话1

 

会话2

 

use test;

#初始化数据

create table t1(c1 int, c2 int) engine=innodb;

create table t2(c1 int, c2 int) engine=innodb;

insert into t1 values(1,1), (2,2);

insert into t2 values(1,1), (2,2);

#设置隔离级别

set tx_isolation='repeatable-read';

Query OK, 0 rows affected (0.00 sec)

#连续更新两次

mysql> Begin;

Query OK, 0 rows affected (0.03 sec)

mysql> update t2 set c2 = 3 where c1 in (select c1 from t1);

Query OK, 2 rows affected (0.00 sec)

Rows matched: 2  Changed: 2  Warnings: 0

mysql> update t2 set c2 = 4 where c1 in (select c1 from t1);

Query OK, 2 rows affected (0.00 sec)

Rows matched: 2  Changed: 2  Warnings: 0

mysql> select * from t2;

+------+------+

| c1   | c2   |

+------+------+

|    1 |    4 |

|    2 |    4 |

+------+------+

2 rows in set (0.00 sec)

mysql> commit;

 

#设置隔离级别

set tx_isolation=' repeatable-read';

Query OK, 0 rows affected (0.00 sec)

#两次更新之间执行删除

mysql> delete from t1 where c1 = 2;

--阻塞,直到会话1提交

Query OK, 1 row affected (18.94 sec)

 

RC隔离级别不同的是,在RR中,由于保证可重复读,会话2delete语句会被会话1阻塞,直到会话1提交。

RR中,会话1语句update t2 set c2 = 3 where c1 in (select c1 from t1)会先在t1的记录上S锁(5.1RC中不会上这个锁,但5.0的RC会),接着在t2的满足条件的记录上X锁。由于会话1没提交,会话2delete语句需要等待会话1S锁释放,于是阻塞。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/ad6ca165bfafc755283d008b87158bc7.html