mysql数据库的默认隔离级别为什么是可重复读 - Go语言中文社区

mysql数据库的默认隔离级别为什么是可重复读


 

目录

一 mysql的主从复制

二 当mysql数据库的隔离级别为“读提交”时:

三 当mysql默认隔离级别为可重复读时

总结:


一 mysql的主从复制

  • 1 主服务器上面的任何操作都会通过自己的 I/O tread(I/O 线程)保存在二进制日志 Binary log 里面。

  • 2 从服务器上面也启动一个 I/O thread,通过配置好的用户名和密码, 连接到主服务器上面请求读取二进制日志,然后把读取到的二进制日志写到本地的一个Realy log(中继日志)里面。

  • 3 从服务器上面同时开启一个 SQL thread 定时检查 Realy log(这个文件也是二进制的),如果发现有更新立即把更新的内容在本机的数据库上面执行一遍。(链接:https://www.jianshu.com/p/faf0127f1cb2)

二 当mysql数据库的隔离级别为“读提交”时:

首先通过命令,查询一下默认隔离级别。

show variables like 'transaction_isolation';

设置session隔离级别为“读提交”

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

在读提交的隔离级别下开启两个会话:按上面的顺序执行命令。最后得到的数据库中有一条记录。

在mysql5.1以前mysql的逻辑操作日志binlog默认的是statement模式,用于恢复和复制。主从复制的binlog的采用的事statement方式。主库就是将每次数据库的sql修改(增删改)在提交前以二进制编码的形式保存到日志文件中。从库定时从主库的日志文件复制到本地日志,从库根据本地日志(继中日志)的变化执行sql语句。


根据上面的情况,当命令提交前,才会向日志文件中写入。所以日志文件的sql语句顺序是先增加后删除,所以在从库中数据库是没有数据的。而主库中有数据,这就造成了主从不一致的问题。

mysql5.1的binlog又提供了两种格式row、和fixed。mysql会根据情况择优选择使用哪种格式。就算是这样也不能避免主从不一致的问题。就像前面的例子如果删除大量数据的时候保存binlog日志采用statement格式,未提交;插入大量数据的时候也采用了statement。(为什么采用statement格式,可看推荐文章《mysql主服务器 binlog_format 的 statement,row, mixed 三种格式对比。》),那么就可能造成主从不一致的问题。只有将修改的语句串行化才能解决这个问题。将隔离级别提升为可重复读就能将写入binlog的语句串行化。从库是根据binlog日志执行了的。binlog保证了与主库相同的执行顺序,那么也就保证了主从的一致性。

三 当mysql默认隔离级别为可重复读时

开启两个会话,左边为session1,右边为session2,按数字所示顺序执行。

隔离级别设为可重复读(Repeatable Read),在该隔离级别下引入间隙锁。当Session 1执行delete语句时,会锁住间隙。那么,Ssession 2执行插入语句就会阻塞住,无法继续执行。只有到session1 提交(commit)了之后。才能执行。实现了写入binlog的语句串行化。解决了主从不一致的问题。

总结:

MySQL使用可重复读来作为默认隔离级别的主要原因是语句级的Binlog。可重复读能提供SQL语句的写可串行化,保证了主从一致。

个人的见解,如有问题,欢迎指正。

参考文章:

为什么mysql默认隔离级别设置为可重复读 

mysql主服务器 binlog_format 的 statement,row, mixed 三种格式对比。(通俗易懂)

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

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/zhangyingjie09/article/details/103484181
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-06-26 22:05:02
  • 阅读 ( 1012 )
  • 分类:数据库

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢