0%

数据库三种日志原理详解

[toc]

数据库日志分类#

Q: 数据库有哪三种log?#

A:

  • redo log
    和大多数关系型数据库一样,InnoDB记录了对数据文件的物理更改,并保证总是日志先行,也就是所谓的WAL
    即在持久化数据文件前,保证之前的redo日志已经写到磁盘。
    mysql重新启动时会检查redo log的日志,把由于mysql异常退出导致没有刷新到磁盘的数据页从redo log中恢复。
    innodb_log_group_home_dir表示redo log的目录;innodb_log_file_size表示redo log文件的大小;innodb_log_files_in_group表示redo log文件个数。
    redo log文件以ib_logfile[number]命名。

  • undo log
    为了满足事务的原子性,在操作任何数据之前,首先将数据备份到一个地方(这个存储数据备份的地方就是undo Log)。然后进行数据的修改。如果出现了错误或者用户执行了ROLLBACK语句,系统可以利用undo Log中的备份将数据恢复到事务开始之前的状态。
    详细分析MySQL事务日志(redo log和undo log)

  • bin log(二进制日志)
    记录sql语句,可用于主从复制。
    二进制日志只在事务提交的时候一次性写入(基于事务的innodb二进制日志),提交前的每个二进制日志记录都先cache,提交时写入
    [查询日志、二进制日志详解](https://www.cnblogs.com/f-ck-need-u/p/9001061.html


Q: binlog和relog都有哪些区别呢?#

A:

  1. 层次不同。
    bin二进制日志是在存储引擎的上层产生的,不管是什么存储引擎,对数据库进行了修改都会产生二进制日志。而redo log是innodb层产生的,只记录该存储引擎中表的修改
  2. 记录的东西不同。
    二进制日志记录操作的方法是逻辑性的语句。本质也还是逻辑的SQL设置,如该行记录的每列的值是多少。而redo log是在物理格式上的日志,它记录的是数据库中具体到每个页的修改。
  3. 写日志的时机不同。
    二进制日志只在每次事务提交的时候一次性写入缓存中的日志"文件"(对于非事务表的操作,则是每次执行语句成功后就直接写入)。
    而redo log在数据准备修改前写入缓存中的redo log中,然后才对缓存中的数据执行修改操作
  4. 一次事务生成的日志记录数不同。
    二进制日志一次提交对应一次记录。
    而redo log中是记录的物理页的修改,redo log文件中同一个事务可能多次记录,最后一个提交的事务记录会覆盖所有未提交的事务记录。

例如事务T1,可能在redo log中记录了 T1-1,T1-2,T1-3,T1* 共4个操作,其中 T1* 表示最后提交时的日志记录,所以对应的数据页最终状态是 T1* 对应的操作结果

  1. 幂等性不同
    二进制日志不具有幂等性。重复执行多次会造成数据错误。
    redolog具有幂等性, 因为始终是对页做覆盖,不会出错

relog#

relog刷磁盘时,存在应用层logBuffer、 操作系统层面的buffer、日志文件。
408b231580c2619c1e253d461789312de00d6bd5

Q: relog刷日志到磁盘有哪几种方式?#

A:
MySQL支持用户自定义在commit时如何将log buffer中的日志刷log file中。这种控制通过变量 innodb_flush_log_at_trx_commit 的值来决定。该变量有3种值:0、1、2,默认为1

  • 当设置为1的时候,事务每次提交都会将log buffer中的日志写入os buffer并调用fsync()刷到log file on disk中。。
  • 当设置为0的时候,事务提交时不会将log buffer中日志写入到os buffer,而是每秒写入os buffer并调用fsync()写入到log file on disk中。也就是说设置为0时是(大约)每秒刷新写入到磁盘中的,当系统崩溃,会丢失1秒钟的数据。
  • 当设置为2的时候,每次提交都写入到os buffer,并且是每秒调用fsync()将os buffer中的日志写入到log file on disk。
    47fae1c3b36b7192457b99d4a8ea432bf05b7117

Q: relog日志块的格式是怎么样的?#

A:

  • redo log以块为单位进行存储的,每个块占512字节,这称为redo log block。(不管是log buffer中还是os buffer中以及redo log file on disk中,都是这样以512字节的块存储的)
  • 组成部分:
  1. 日志块头(包含buffer中的位置id、已记录log大小、涉及分拆日志块时的偏移位置、检查点信息)
  2. 日志块尾
  3. 日志主体
    c1feeeef68511ecef418c32a6113910de4bbb137

有时候一个数据页产生的日志量超出了一个日志块,这是需要用多个日志块来记录该页的相关日志。例如,某一数据页产生了552字节的日志量,那么需要占用两个日志块,第一个日志块占用492字节,第二个日志块需要占用60个字节,那么对于第二个日志块来说,它的第一个log的开始位置就是73字节(60+12)


binlog#

Q: binlog的格式又是怎么样的?#

A:
mysql binlog日志有三种格式,分别为Statement,MiXED,以及ROW!
可以用命令查看自己的mysql用的是什么模式。

  • statement 只记录更新的sql语句
    缺点:
    像一些特定函数功能,slave可与master上要保持一致会有很多相关问题(如sleep()函数, last_insert_id(),以及user-defined functions(udf)会出现问题

  • Row:不记录sql语句上下文相关信息,仅保存哪条记录被修改,仅需要记录那一条记录被修改成什么了。
    一条update语句,修改多条记录,则binlog中每一条修改都会有记录,这样造成binlog日志量会很大

  • Mixedlevel:以上两种level的混合使用。MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种

Mysql默认是使用Statement日志格式,推荐使用MIXED.


undolog#

Q: undolog的日志格式?#

A:
对数据的变更操作,主要来自 INSERT UPDATE DELETE,而UNDO LOG中分为两种类型
一种是 INSERT_UNDO(INSERT操作),记录插入的唯一键值;
一种是 UPDATE_UNDO(包含UPDATE及DELETE操作),记录修改的唯一键值以及old column记录。
因此update/delete操作的undolog数据会比insert操作的数据多
c1a931eb22c5bddff24bac883b757d7f04b76e12


Q: checkpoint是做什么的?#

A:
“检查点”会创建一个已知的正常点,在意外关闭或崩溃后进行恢复的过程中, SQL Server 数据库引擎 可以从该点开始应用日志中所包含的更改。
检查点(Checkpoint)的本质


Q: LSN称为日志的逻辑序列号, 具体是怎么生效的?#

A: