我们可以把事务理解成一组sql语句的集合,事务可以只包含一条sql语句,也可以包含多条复杂的sql语句,事务中的所有sql语句被当做一个操作单元,换句话说,事务中的sql语句要么都执行成功,要么全部执行失败,事务内的sql语句被当做一个整体,被当做一个原子进行操作。
mysql中,innodb存储引擎是支持事务的,而且innodb存储引擎的事务完全符合ACID的特性,ACID是如下四大特性的首字母缩写。
A:atomicity 原子性
C:consistency 一致性
I:isolation 隔离性
D:durability 持久性
原子性:整个事务中的所有操作要么全部执行成功,要么全部执行失败后混滚到最初状态。
一致性:数据库总是从一个一致性状态转为另一个一致性状态。
隔离性:一个事务在提交之前所做出的的操作是否能为其他事务可见,由于不同的场景需求不同,所以针对隔离性来说,有不同的隔离级别。
持久性:事务一旦提交,事务所做出的修改将会永久保存,此时即使数据库崩溃,修改的数据也不会丢失。
使用redo log,能够实现ACID中的A,也就是原子性,即事务中的所有sql被当做一个执行单元。
redo log其实由两部分组成:redo log buffer(重做日志缓冲) 和 redo log file(重做日志文件)
redo log buffer存在于内存之中,是易失的,redo log file是持久的,存在于磁盘上。
缓存到磁盘:
重做日志先被写入到redo log buffer中,虽然内存的速度极快,但是无法满足持久性的需求,因为内存中的数据是易失的,所以为了满足持久性,需要将redo log buffer中的日志写入到redo log file中,相当于从内存中同步到磁盘上,所以磁盘的性能会影响事务的性能,由于redo log file是磁盘上一段连续的空间,所以写速度还是比较快的,比离散的写操作要快很多,当操作记录被记录到redo log file中以后,再从redo log file中将操作同步到数据文件中。
缓存刷新策略:
虽然,我们应该实时将redo log buffer中的数据写入到redo log file中以保证数据的安全性,但是这样会极大的降低性能,我们可以通过设置innodb_flush_log_at_trx_commit参数来修改从redo log buffer写入redo log file的策略,但是如果这样做,则会丧失持久性,有可能会丢失部分数据,具体使用怎样的刷写策略,还需要根据实际情况自己权衡。
redo log是物理日志,之所以说它是物理日志,是因为redo log 中记录的是数据库对页的操作,而不是逻辑上的增删改查,重做日志具有幂等性。
刚才我们大致的描述了什么是redo log ,现在来聊聊什么是undo log,我们可以把undo log理解成数据被修改前的备份。如果说事务进行了一半,有一条sql没有执行成功,那么数据库可以根据undo log进行撤销,将所有修改过的数据从逻辑上恢复到修改之前的样子,注意,是逻辑上还原成原来的样子,比如,之前insert了1000条数据 ,那么就delete它们,如果delete了2000条,就insert它们,如果update了500条数据,就再次根据undo log去update它们,所以,undo log是逻辑日志,与redo log记录的页操作物理日志不同。
log group为重做日志组,一个重做日志组(log group)中有多个重做日志文件(redo log file),当日志组中的第一个logfile被写满,则会开始将redo log写入日志组中的下一个重做日志文件中,以此类推,当日志组中的所有redo log file都被写满,则将redo log再写入第一个redo log file 中,覆盖原来的redo log,以便新的redo log 被写入。
如果重做日志所在的设备崩溃了,那么redo log将有可能丢失,这样就无法保证redo log在任何时候都是可用的,所以,log group还支持日志组镜像,为了保险起见,我们应该将log group放在有冗余能力的设备上,比如raid1。
转载自:mysql/mariadb知识点总结(19):事务相关概念 (事务总结之一) | 朱双印博客
原文:https://www.cnblogs.com/gengyufei/p/14320180.html