REDO日志内容

REDO日志是物理逻辑日志,根据页进行记录,记录的内容是逻辑的(页的变化,并非SQL语句)

+---------------+----------+---------+---------------+
| redo_log_type| space no | page no | redo logbody |
+---------------+----------+---------+---------------+
 redo log 类型   表空间号     页号      redo log 内容

相关参数

REDO 即常说的重做日志,用来实现持久性,相关组件有有 redo log buffer 和 redo log file 。

  • --innodb_log_buffer_size <-- 通常 8M 已经足够使用
  • --innodb_log_file_size <-- 单个 innodb redo文件的大小(推荐8G,官方建议等于 buffer_pool_size)
  • --innodb_log_files_in_group <-- 设置有几个 redo 日志文件
  • --innodb_log_group_home_dir <-- 可以外考虑将 redo 文件和数据文件分开,放在更快的盘

5.5版本的redo文件的总大小是有限制的(小于4G),5.6以后限制为512G,如果调的太大,恢复速度会很慢。
redo日志循环写的好处是不需要归档,减少了IO操作;缺点是如果 redo_log_file 太小,则可能需要等待(所以需要把 redo log file 设置的尽可能的大)。
redo log buffer 和 redo log 都是由 log block 组成,每个 log block 512 字节。

修改日志数量和大小

1.检查innodb_fast_shutdown的值
该参数可取0,1,2三个值,0表示shutdow normal,1表示shutdown immediate(默认),2表示shutdown abort。如果该值为2,先修改为1。

2.正常关闭mysql后调整参数
MySQL 5.6以后调整完参数即可直接启动数据库,MySQL会自动扩展/减小该文件大小;之前的版本需要先将原日志文件移走后再启动数据库。

REDO Log Buffer的刷新条件

  1. master thread 每秒刷新 buffer 到 logfile。5.6 版本后,增加 innodb_flush_log_at_timeout 参数(默认为1),可以设置刷新间隔,该值设置的越大,相对性能就好一点(IO 操作变少),但是如果 innnodb_flush_log_at_trx_commit 的值不是1,并且发生宕机,丢失的数据也就越多。
  2. redo log buffer 使用量大于1/2 时进行刷新。
  3. 事物提交时进行刷新(--innnodb_flush_log_at_trx_commit = {0|1|2})

    innnodb_flush_log_at_trx_commit

  • 0 - 事物提交的时候并不把日志(redo log buffer)写入到磁盘(1s 或者 大于1/2 时刷日志)
  • 1 - 事物每次提交的时候要确保日志(redo log buffer)写入磁盘,即使宕机,也可以通过redo恢复,达到持久性的要求
  • 2 - 事物提交的时候,仅将日志(redo log buffer)写入到操作系统缓存

1 可以保证数据不丢失,建议设置为1。
0 可能会丢失1秒(innodb_flush_log_at_timeout)的数据,
2 如果是mysql停止,不会丢数据,因为在缓存里面,但是当系统宕机了,在缓存里面的数据就丢失了。

redo 刷新情况

mysql> show engine innodb statusG
Log sequence number 537665207 -- 当前内存中的LSN
Log flushed up to 537665207
Pages flushed up to 537665207 -- 最后刷新到磁盘的页上的最新的LSN
Last checkpoint at 537665198

-- 两者之差表示 redo log 还有多少没有刷新的磁盘
-- 如果该差值接近重做日志的总大小的75%时,表明你的 innodb_log_file_size 设置小了(75%左右就强制刷新了)

组提交

一次 fsync 刷新多个事务,性能提高10倍左右,5.6 默认开启,不能关闭。5.5 有 bug,开启 binlog 后组提交失效,性能较差。

fsync

  • O_DIRECT 仅对写数据时有用,redo 日志是不会通过 O_DIRECT 方式写入到磁盘的,而是写到文件系统的缓存中
  • fsync 可以将 redo 日志从内存中直接同步到磁盘
  • O_DIRECT 仅仅写数据到磁盘,但是数据的元数据没有同步,比如time、owner、size等等,从数据的角度看,fsync可以将元数据同步到磁盘

IOPS--决定-->fsync--决定-->TPS。
假设HDD磁盘IOPS为100(即每秒只有100次fsync),且一个事务中只有一条 insert into 的SQL时,那1秒钟内就只能插入100条数据,即TPS就只有100。
假设使用组提交 ,一次 fsync 可以刷新5个事务(假设),那在IOPS为100的情况下,也可以提交500个事务,这样性能就得到了提升(一次IO提交多个事物)。

-- By 许望(RHCA、OCM、VCP)
最后修改:2020 年 01 月 14 日 11 : 35 AM
如果觉得我的文章对你有用,请随意赞赏