Mysql的zhu从复制、shi务、ge离、MVCC多版本并发

本文详细介绍了MySQL的主从复制机制,包括如何通过BinlogDump、I/O线程和SQL线程实现数据同步,以及如何利用二进制日志和中继日志保持主从数据一致性。此外,还探讨了事务的ACID特性,特别是隔离性,解释了四种不同的隔离级别及其可能的问题。最后,文章阐述了MVCC(多版本并发控制)在解决事务并发问题中的作用,特别是在可重复读级别下如何避免幻读问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.主从复制

1.什么是主从复制?

  • 主从复制是指将主数据库的DDLDML操作通过二进制日志传到数据库上,然后在数据库上对这些日志进行重新执行,从而使数据库和主数据库的数据保持一致

2.主从复制怎么实现的?

3个线程(Binlog Dump线程、I/O线程和SQL线程)+2个日志(Binlog日志、中继日志Relay Log)
  • 1.MySql主库在事务提交时会把数据变更作为事件记录在二进制日志Binlog中;
  • 2.主库推送二进制日志文件Binlog中的事件到从库的中继日志Relay Log中,之后从库根据中继日志重做数据变更操作,通过逻辑复制来达到主库和从库的数据一致性
  • 3.MySql通过三个线程来完成主从库间的数据复制,其中Binlog Dump线程跑在主库上,I/O线程和SQL线程跑着从库上;
  • 4.当在从库上启动复制时,首先创建I/O线程连接主库,主库随后创建Binlog Dump线程读取数据库事件并发送给I/O线程,I/O线程获取到事件数据后更新到从库的中继日志Relay Log中去,之后从库上的SQL线程读取中继日志Relay Log中更新的数据库事件并应用,如下图所示。
    在这里插入图片描述

2.事务

1.事务的4个特性——ACID

  • 原子性(atomicity): 事务的最小工作单元,要么全成功,要么全失败。

  • 一致性(consistency): 事务开始和结束后,数据库的完整性不会被破坏。

  • 隔离性(isolation): 不同事务之间互不影响,四种隔离级别为RU(读未提交)、RC(读已提交)、RR(可重复读)、SERIALIZABLE (串行化)。

  • 持久性(durability): 事务提交后,对数据的修改是永久性的,即使系统故障也不会丢失。

2.事务的隔离级别——4个级别

  • 1.未提交读(脏读)
    一个事务可以读取到另一个事务未提交的数据。这种隔离级别岁最不安全的一种,因为未提交的事务是存在回滚的情况。

  • 2.已提交读
    又称为不可重复读,一个事务因为读取到另一个事务已提交的修改数据,导致在当前事务的不同时间读取同一条数据获取的结果不一致。

  • 如下:SessionA3次读取3个不同的结果
    在这里插入图片描述

  • 3.可重复度(幻读
    一个事物读可以读取到其他事务提交的数据,但是在RR隔离级别下,当前读取此条数据只可读取一次,在当前事务中,不论读取多少次,数据任然是第一次读取的值,不会因为在第一次读取之后,其他事务再修改提交此数据而产生改变。读出来的数据并不一定就是最新的数据。

  • eg:SessionA3次读取的记录和第1次都一样。
    在这里插入图片描述

  • 4.串行化

所有的数据库的读或者写操作都为串行执行,当前隔离级别下只支持单个请求同时执行,所有的操作都需要队列执行。所以种隔离级别下所有的数据是最稳定的,但是性能也是最差的。

  • SessionA等待,直到SessionB提交commit之后才能读到数据
    在这里插入图片描述

3.事务和MVCC原理

  • 不同事务同时操作同一条数据产生的问题

1.LBCC,基于锁的并发控制,Lock Based Concurrency Control

  • 使用的机制,在当前事务需要对数据修改时,将当前事务加上锁,同一个时间只允许一条事务修改当前数据,其他事务必须等待锁释放之后才可以操作。

2.MVCC,多版本并发控制,Multi-Version Concurrency Control

  • 使用版本来控制并发情况下的数据问题,在B事务开始修改账户且事务未提交时,当A事务需要读取账户余额时,此时会读取到B事务修改操作之前的账户余额的副本数据,但是如果A事务需要修改账户余额数据就必须要等待B事务提交事务。

  • MVCC使得数据库读不会对数据加锁,普通的SELECT请求不会加锁,提高了数据库的并发处理能力。借助MVCC,数据库可以实现READ COMMITTED,REPEATABLE READ等隔离级别,用户可以查看当前数据的前一个或者前几个历史版本,保证了ACID中的I特性(隔离性)。

核心:创建版本号、删除版本号
  • InnoDB的MVCC,通过在每行记录后面保存两个隐藏的列来实现:一个保存了行的创建时间(行的事务ID),一个保存行的过期时间(删除时间),当然,这里的时间并不是时间戳,而是系统版本号(行的事务ID),每开始一个新的事务,系统版本号就会递增。在RR隔离级别下,MVCC的操作如下:

    • select操作。
      • InnoDB只查找版本早于(包含等于)当前事务版本的数据行。可以确保事务读取的行,要么是事务开始前就已存在,或者事务自身插入或修改的记录。
      • 行的删除版本要么未定义,要么大于当前事务版本号。可以确保事务读取的行,在事务开始之前未删除。
    • insert操作。将新插入的行保存当前版本号为行版本号
    • delete操作。将删除的行保存当前版本号为删除版本号
    • update操作。变为insert和delete操作的组合,insert的行保存当前版本号为行版本号,delete则保存当前版本号到原来的行作为删除标识。
    • 由于旧数据并不真正的删除,所以必须对这些数据进行清理,innodb会开启一个后台线程执行清理工作,具体的规则是将删除版本号小于当前系统版本的行删除,这个过程叫做purge。

3.可重复读级别怎么解决了幻读问题?

mysql里面实际上有两种读,一种是“快照读”,一种是“当前读”。

select 快照读

当执行select操作是innodb默认会执行快照读,会记录下这次select后的结果,之后select 的时候就会返回这次快照的数据,即使其他事务提交了不会影响当前select的数据,这就实现了可重复读了。

快照的生成当在第一次执行select的时候,也就是说假设当A开启了事务,然后没有执行任何操作,这时候B insert了一条数据然后commit,这时候A执行 select,那么返回的数据中就会有B添加的那条数据。

之后无论再有其他事务commit都没有关系,因为快照已经生成了,后面的select都是根据快照来的。

当前读

对于会对数据修改的操作(update、insert、delete)都是采用当前读的模式。在执行这几个操作时会读取最新的记录,即使是别的事务提交的数据也可以查询到。

假设要update一条记录,但是在另一个事务中已经delete掉这条数据并且commit了,如果update就会产生冲突,所以在update的时候需要知道最新的数据。也正是因为这样所以才导致上面我们测试的那种情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值