MySQL系列—11.Redo log
1.简介
概念
redo log用于记录事务操作变化,记录的是数据被修改之后的值,(tbs space id + page no + action)。
作用
尚未完成的DML,数据库崩溃则用log恢复。保证事务持久性。
(
1
)
在页面修改完成之后,脏页刷入磁盘之前,写入
Redo
日志;
(
2
)
实现
WAL:
日志比数据页先写回磁盘
(
3
)
聚簇索引
/
二级索引
/
Undo
页面修改,记录
Redo
日志;
(4)至少要有2个redo log,文件名序号从0开始,从ib_logfile0到ib_logfileN
相关参数
innodb_log_files_in_group
#redo log
文件的个数,命名方式如:
ib_logfile0
,
iblogfile1
innodb_log_file_size
#
单个
redo log
文件设置大小
innodb_log_group_home_dir
#redo log
文件组所在的路径
innodb_log_buffer_size
#redo log buffer
大小
,
默认
16
M
。
事务日志写入磁盘,把
redo log
放到该缓冲区,然后根据
innodb_flush_log_at_trx_commit
参数的设
置,再把日志从
buffer
中
flush
到磁盘中
innodb_flush_log_at_trx_commit
#redo log刷新到磁盘策略,默认1
-
值为
0
,
每次
commit
事务
,
并不将事务的重做日志写入磁盘上日志文件,而是等待主线程每秒
刷新
-
1
,
执行
commit
时将重做日志缓冲同步写到磁盘,即伴有
fsync
的调用
-
2
,将重做日志异步写到磁盘,即写到文件系统的缓存(OS cache)中。
缺点
-
0
,当数据库发生宕机时,部分日志未刷新到磁盘,因此会丢失最后一段时间的事务。
-
2
,当操作系统宕机时,会丢失未从文件系统缓存刷新到重做日志文件那部分事 务。
2.工作流程
更新一条记录
,redo
流程如下
:
(
1
)从磁盘加载索引数据页到
buffer pool
的索引页中
(
2
)写入数据的旧值便于
rollback
(
3
)更新缓冲页中的数据
(
4
)生产一条重做日志并写入
redo log buffer
,记录的是数据被修改后的值
(
5
)当事务
commit
时,将
redo log buffer
中的内容刷新到
redo log file
,对
redo lo
g file
采用追加写的方式
(
6
)定期将内存中修改的数据刷新到磁盘中
3.Write Ahead Log
InnoDB
的更新操作采用的是
Write Ahead
Log
(
预先日志持久化
)
策略,即先写日志,再写
入磁盘。
作用:
(
1
)
修改的
这个操作记录在日志中,
而不必马上将更改内容刷新到磁盘上
,
从而将随机写
转换为顺序写
,
提高了性能。
(2)
内存中的数据页会和磁盘上的数据页内容不一致
,
此时将内存中的这种数据页称为 脏页
4.Redo Log Buffer 空间管理
buffer pool
中把数据修改情况记录到
redo log buffer
,出现以下情况,再把
redo log
刷下
到
redo log file
:
- Redo log buffer空间不足
- 事务提交(依赖innodb_flush_log_at_trx_commit参数设置)
- 做checkpoint
- 实例shutdown
- binlog切换
5.LSN
1.LSN
LSN:
(
log sequence number)日志序列号,LSN
是一个一直递增的整型数字,表示事务写入到日志的字节总量
.
存在位置
(
1
)
日志会携带一个
LSN
(
2
)
每个数据页上也会记录一个
LSN(
日志序列号
).
查看lsn
show engine innodb status\G
Log sequence number:
当前系统最大的
LSN
号
log flushed up
to
:
当前已经写入
redo
日志文件的
LSN
pages flushed up
to
:已经将更改写入脏页的
lsn
号
Last
checkpoint
at
就是系统最后一次刷新
buffer pool
脏中页数据到磁盘的
checkpoint
6.checkpoint
概念
对于内存中的脏页,在一定条件下将脏页刷新到磁盘,这个点位行为叫checkpoint.
分类
(
1
)sharp checkpoint
:在关闭数据库的时候,将
buffer pool
中的脏页全部刷新到磁盘中。
(
2
)fuzzy checkpoint
:数据库正常运行时,在不同的时机,将部分脏页写入磁盘,也是为了避免一次刷新全部的脏页造成的性能问题。
-
Master Thread checkpoint
:每秒或者每
10
秒一次的频率,将部分脏页从内存中刷新
到磁盘
-
Async
/
Sync Flush checkpoint:
设重做日志的
LSN
记为
redo_lsn
,将已经刷新回磁盘最新页的
LSN
记为
checkpoint_lsn.
则
checkpoint_age
=
redo_lsn
-
checkpoint_lsn
async_water_mark
=
75
% *
total_redo_log_file_size #
异步
sync_water_mark
=
90
% *
total_redo_log_file_size #
同步
checkpoint_age<
async_water_mark #
无需刷盘
async_water_mark<checkpoint_age<
sync_water_mark #触发刷盘到
checkpoint_age
<
async_water_mark
checkpoint_age>
sync_water_mark #
强制同步刷盘
,
影响数据库性能会抖一下
,
基本很
少发生
查看参数:
mysql> show global status like 'Innodb_buffer_pool_pages%';
+----------------------------------+-------+
| Variable_name | Value |
+----------------------------------+-------+
| Innodb_buffer_pool_pages_data | 995 |
| Innodb_buffer_pool_pages_dirty | 0 |
| Innodb_buffer_pool_pages_flushed | 200 |
| Innodb_buffer_pool_pages_free | 7194 |
| Innodb_buffer_pool_pages_misc | 3 |
| Innodb_buffer_pool_pages_total | 8192 |
+----------------------------------+-------+
mysql> show global status like '%wait_free';
+------------------------------+-------+
| Variable_name | Value |
+------------------------------+-------+
| Innodb_buffer_pool_wait_free | 0 |
+------------------------------+-------+
1 row in set (0.00 sec)
#不为0代表需要free page,没有可用的freepage,数据库性能有问题