MySQLInnodbACID的实现原理
作者:发布时间:2021-07-09 08:42:27点击:1178
ACIDMySQL作为一个关系型数据库,以最常见的InnoDB引擎来说,是如何保证ACID的。
(Atomicity)原子性:事务是最小的执行单位,不允许分割。原子性确保动作要么全部完成,要么完全不起作用;(Consistency)一致性:执行事务前后,数据保持一致;(Isolation)隔离性:并发访问数据库时,一个事务不被其他事务所干扰。(Durability)持久性:一个事务被提交之后。对数据库中数据的改变是持久的,即使数据库发生故障。隔离性隔离性主要是锁和MVCC实现的。这个也可以看我前面mysql系列的文章,这里就不在赘述了。原子性MySQL的日志有很多种,如二进制日志、错误日志、查询日志、慢查询日志等,此外InnoDB存储引擎还提供了两种事务日志:redolog(重做日志)和undolog(回滚日志)。其中redolog用于保证事务持久性;undolog则是事务原子性和隔离性实现的基础。undolog,回滚日志。我们知道隔离性的MVCC就是依靠它来实现的,原子性也是。实现原子性的关键,是当事务回滚时能够撤销所有已经成功执行的sql语句。当事务对数据库进行修改时,InnoDB会生成对应的undolog;如果事务执行失败或调用了rollback,导致事物需要回滚,便可以利用undolog中的信息将数据回滚到修改之前的样子。undolog属于逻辑日志,它记录的是sql执行相关的信息。当发生回滚时,InnoDB会根据undolog的内容做与之前相反的工作:对于每个insert,回滚时会执行delete;对于每个delete,回滚时会执行insert;对于每个update,回滚时会执行一个相反的update,把数据改回去。以update操作为例:当事务执行update时,其生成的undolog中会包含被修改行的主键(以便知道修改了哪些行)、修改了哪些列、这些列在修改前后的值等信息,回滚时便可以使用这些信息将数据还原到update之前的状态。持久性上面讲到Innnodb有很多log,持久性靠的是redolog。读数据:会首先从缓冲池中读取,如果缓冲池中没有,则从磁盘读取在放入缓冲池;写数据:会首先写入缓冲池,缓冲池中的数据会定期同步到磁盘中(会产生脏读);于是redolog就派上用场了。既然redolog也需要存储,也涉及磁盘IO为啥还用它?1、redolog的存储是顺序存储,而缓存同步是随机操作。2、缓存同步是以数据页为单位的,每次传输的数据大小大于redolog。redolog采用的是WAL(Write-aheadlogging,预写式日志),所有修改先写入日志,再更新到BufferPool,保证了数据不会因MySQL宕机而丢失,从而满足了持久性要求。既然redolog也需要在事务提交时将日志写入磁盘,为什么它比直接将BufferPool中修改的数据写入磁盘(即刷脏)要快呢?主要有以下两方面的原因:1、刷脏是随机IO,因为每次修改的数据位置随机,但写redolog是追加操作,属于顺序IO。2、刷脏是以数据页(Page)为单位的,MySQL默认页大小是16KB,一个Page上一个小修改都要整页写入;而redolog中只包含真正需要写入的部分,无效IO大大减少。redolog与binlog的区别:1、作用不同:redolog是用于crashrecovery的,保证MySQL宕机也不会影响持久性;binlog是用于point-in-timerecovery的,保证服务器可以基于时间点恢复数据,此外binlog还用于主从复制。2、层次不同:redolog是InnoDB存储引擎实现的,而binlog是MySQL的服务器层(可以参考文章前面对MySQL逻辑架构的介绍)实现的,同时支持InnoDB和其他存储引擎。3、内容不同:redolog是物理日志,内容基于磁盘的Page;binlog的内容是二进制的,根据binlog_format参数的不同,可能基于sql语句、基于数据本身或者二者的混合。4、写入时机不同:binlog在事务提交时写入;redolog的写入时机相对多元:默认刷盘策略:当事务提交时会调用fsync对redolog进行刷盘;修改innodb_flush_log_at_trx_commit参数可以改变该策略,但事务的持久性将无法保证。其他刷盘时机:如masterthread每秒刷盘一次redolog等,这样的好处是不一定要等到commit时刷盘,commit速度大大加快。一致性一致性是事务追求的最终目标,实现一致性的措施包括:保证原子性、持久性和隔离性,如果这些特性无法保证,事务的一致性也无法保证.数据库本身提供保障,例如不允许向整形列插入字符串值、字符串长度不能超过列的限制等应用层面进行保障,例如如果转账操作只扣除转账者的余额,而没有增加接收者的余额,无论数据库实现的多么完美,也无法保证状态的一致.CAP和ACID中的一致性CAP定理中的数据一致性,其实是说分布式系统中的各个节点中对于同一数据的拷贝有着相同的值;而ACID中的一致性是指数据库的规则,如果schema中规定了一个值必须是唯一的,那么一致的系统必须确保在所有的操作中,该值都是唯一的,由此来看CAP和ACID对于一致性的定义有着根本性的区别。总结事务的ACID四大基本特性是保证数据库能够运行的基石,但是完全保证数据库的ACID,尤其是隔离性会对性能有比较大影响,在实际的使用中我们也会根据业务的需求对隔离性进行调整,除了隔离性,数据库的原子性和持久性相信都是比较好理解的特性,前者保证数据库的事务要么全部执行、要么全部不执行,后者保证了对数据库的写入都是持久存储的、非易失的,而一致性不仅是数据库对本身数据的完整性的要求,同时也对开发者提出了要求-写出逻辑正确并且合理的事务。最后,也是最重要的,当别人在讲一致性的时候,一定要搞清楚他的上下文。