企业网站不备案,学校网站的建设,产品创意设计,济南百度代理InnoDB引擎为什么选可重复读作为默认隔离级别
一般的DBMS系统#xff0c;默认都会使用读提交#xff08;Read-Comitted#xff0c;RC#xff09;作为默认隔离级别#xff0c;如Oracle、SQL Server等#xff0c;而MySQL却使用可重复读#xff08;Read-Repeatable#x…InnoDB引擎为什么选可重复读作为默认隔离级别
一般的DBMS系统默认都会使用读提交Read-ComittedRC作为默认隔离级别如Oracle、SQL Server等而MySQL却使用可重复读Read-RepeatableRR。要知道越高的隔离级别能解决的数据一致性问题越多理论上性能损耗更大可并发性越低。隔离级别依次为
SERIALIZABLE RR RC Read-Uncommited
InnoDB引擎选可重复读作为默认隔离级别主要是解决主从同步不一致的问题。
从Binlog说起
Mysql binlog是二进制日志文件用于记录mysql的数据更新或者潜在更新(比如DELETE语句执行删除而实际并没有符合条件的数据)在mysql主从复制中就是依靠的binlog。可以通过语句“show binlog events in ‘binlogfile’”来查看binlog的具体事件类型。binlog记录的所有操作实际上都有对应的事件类型的
MySQL binlog的三种工作模式 Row(用到MySQL的特殊功能如存储过程、触发器、函数又希望数据最大化一直则选择Row模式) 简介日志中会记录每一行数据被修改的情况然后在slave端对相同的数据进行修改。 优点能清楚的记录每一行数据修改的细节 缺点数据量太大
Statement (默认)简介每一条被修改数据的sql都会记录到master的bin-log中slave在复制的时候sql进程会解析成和原来master端执行过的相同的sql再次执行。在主从同步中一般是不建议用statement模式的因为会有些语句不支持比如语句中包含UUID函数以及LOAD DATA IN FILE语句等 优点解决了 Row level下的缺点不需要记录每一行的数据变化减少bin-log日志量节约磁盘IO提高新能 缺点容易出现主从复制不一致
Mixed(混合模式)简介结合了Row level和Statement level的优点同时binlog结构也更复杂。
主从不一致实操
binlog为STATEMENT格式且隔离级别为**读已提交(Read Commited)**时有什么bug呢? mysql select * from test; ±—±-----±----- | id | name | age | ±—±-----±----- | 1 | NULL | NULL | | 2 | NULL | NULL | | 3 | NULL | NULL | | 4 | NULL | NULL | | 5 | NULL | NULL | | 6 | NULL | NULL | ±—±-----±----- 6 rows in set (0.00 sec) 这个时候我们有两个事务进行操作
Master此时输出 select * from test; ±—±-----±----- | id | name | age | ±—±-----±----- | 7 | name | 100 | ±—±-----±----- 1 row in set (0.00 sec) 但是你在此时在从(slave)上执行该语句得出输出 mysql select * from test; Empty set (0.00 sec) 在master上执行的顺序为先删后插。 而此时binlog为STATEMENT格式是基于事务记录在事务未提交前二进制日志先缓存在commit提交后再写入记录的因此顺序为先插后删slave同步的是binglog因此从机执行的顺序和主机不一致。slave在插入后删除了所有数据.
解决方案有两种
(1) 隔离级别设为可重复读(Repeatable Read)在该隔离级别下引入间隙锁。当Session 1执行delete语句时会锁住间隙。那么Ssession 2执行插入语句就会阻塞住。
(2) 将binglog的格式修改为row格式此时是基于行的复制自然就不会出现sql执行顺序不一样的问题。奈何这个格式在mysql5.1版本开始才引入。因此由于历史原因mysql将默认的隔离级别设为可重复读(Repeatable Read)保证主从复制不出问题!