A:原子性 - 都做 或者 都不做
C:一致性 - 使用事务完成 , 从一个一致性状态转移到另一个一致性状态
I : 隔离性 - 并发控制 下保证不可见性 数据库并发控制 - 隔离性 I
D: 持久性 - 提交即永久保存
事务有嵌套的特征
redo日志:重做日志 , 保证 原子性 和 持久性 - 没成功可以恢复
undo日志: 保证一致性 - 失败了可以回滚
redo 恢复提交事务修改的页数据
undo 回滚行记录
redo 使用重做日志缓冲 完成到重做日志文件的过渡
可以选择多个不同的时机刷新重做日志缓冲
- 1 : 事务提交的时候 fsync 触发 - 默认策略
- 0 : 每秒刷新一次
- 2: 事务提交的时候写入文件系统缓存,不fsync
fsync的作用:
- binlog: 记录数据库的变化的逻辑操作文件,是数据库层面的日志,记录的是SQL语句,主要用于数据库的复制和恢复;
- binlog 是事务提交的时候写入的
- redo log: innodb 层面的日志,记录页数据的修改;
- redo 日志 恢复的是物理页的数据,所以 redo 是幂等 (一个物理页不断写就是一个覆盖的过程);
- redo log是不断的写入,写入基本单位是 512 字节,默认是一个扇区的大小,保证原子性
- undo 日志是存储在 undo segment 里面的;记录的是逆向的SQL, 事务很多,所以 undo log 不是幂等的,只能依次记录
LSN : 日志序列号 , 使用 8字节存储,代表重做日志的字节总数
- 当前LSN:当前逻辑的最新的LSN
- 刷入到重做日志缓冲区的LSN
- 刷入到磁盘的LSN - 如果需要恢复数据,从这里开始恢复
MVCC是依赖 undo log 实现的,即读取之前的版本的行版本信息,实现非锁定读取
WAL
现在描述一下日志写入的过程
commit logging 写入数据前,先记录日志文件
- 先记录日志文件,提交 commit record
- 再修改数据,提交 end record
如果存在 end record , 表示事务成功了
如果存在 commit record , 没有 end record : 使用 redo 日志重做到磁盘
如果不存在 commit record :使用 undo 日志 ,回滚状态
上面的过程保证了数据的持久性,但是在事务提交前,还是不允许修改数据,即使现在磁盘存在空闲,所以性能不是很好
如果允许在事务提交前将数据写入到磁盘呢? - Write Ahead Logging
对于已经写入的数据,如果失败了如何回滚? =》 undo log , 允许提前写入,那就必须存在回退机制
- 复习 ACID (@2024-01-18)