redolog
- 在Innodb存储引擎产生,环形物理日志,通常配置为4个1G文件。记录页修改操作,在事务进行过程中不断写入。
- LSN(Log Sequence Number)的含义:
- redo log的写入总量。
- checkpoint的位置。表示已经刷新到磁盘页上redo log位置,恢复时从checkpoint开始。
- 页的版本。数据库启动时,如果redo log中的LSN大于页的版本且事务已经提交,则应用重做日志。
checkpoint
- checkpoint和redo日志通过LSN标识版本号,即时序。
- 每次写入长度为 length 的 redo log, LSN 的值就会加上 length。
- checkpoint之后redo日志对应的脏页均未刷新到磁盘。
redolog写入
- 事务执行时,写入redo log buffer。
- 控制写入时机的参数,innodb_flush_log_at_trx_commit:
- =0。每次提交事务,只写redo log buffer中。
- 后台线程1s一次write到文件系统缓存并fsync到磁盘。
- 有可能持久化未提交事务的redolog。
- =1。每次提交事务,fsync到磁盘。
- =2。每次提交事务,write到文件系统缓存。
- =0。每次提交事务,只写redo log buffer中。
组提交优化
- 并发事务持久化到磁盘。
- 步骤:
- 事务1到达,为leader。
- 事务1开始写盘,LSN增加为160。
- 事务1写盘,将LSN小于160的一起写盘,即同时持久化事务2和3。
- redo和binlog的fsync拖到两个write之后,等待组提交。
- 提升组提交效果,可以减少IO压力,但可能增加语句响应时间的参数:
- binlog_group_commit_sync_delay:延迟多少微秒后才调用 fsync;
- binlog_group_commit_sync_no_delay_count:累积多少次以后才调用 fsync。
binlog
- 在server层产生,是追加式的逻辑日志,记录行的修改,在事务完成后一次写入。
T*为提交时的日志
binlog格式
- statement格式。记录sql原文,可能造成主备不一致。
- 比如delete+limit,主备不走同一个索引。
- row格式。记录主键id和操作前后的值。
- mixed。mysql判断优先使用statement,如果可能不一致则使用row。
binlog写入
- 事务执行时,写入binlog cache。
- 一个事务的binlog不能拆分,如果大小超过binlog_cache_size,临时文件暂存。
- 事务提交时,binlog cache写入binlog file,并清空cache。
- 控制写binlogfile时机的参数,sync_binlog:
- =0。每次提交事务,只write到文件系统缓存,不fsync到磁盘。
- =1。每次提交事务,fsync。牺牲吞吐换取持久性。
- N>1。每次提交事务,write,累计N次fsync。
redo和binlog的一致性
- 两阶段提交。
- 崩溃恢复的规则:
- redo log完整,且已经commit,直接提交。
- redo log只有完整的prepare,binlog完整则提交,否则回滚。判断binlog的完整性:
- statement格式的binlog,最后会有 COMMIT。
- row 格式的 binlog,最后会有一个 XID event。
- redo log和binlog通过XID关联。
双1配置
- sync_binlog 和 innodb_flush_log_at_trx_commit 都设置成 1。
- 一个事务提交前,两次刷盘,一次是 redo log(prepare 阶段),一次是 binlog。
undolog
- undo是逻辑日志,记录行回滚到特定版本,存放在共享表空间的undo段。
- 实现rollback和 mvcc 。
- undo格式:
- insert undo log:插入操作的undo,对事务本身可见,提交后可删除。
- update undo log:更新和删除的undo,需要提供mvcc,提交后放入Undo链表,purge后删除。