0

深入 MySQL (二) 文件系统

 3 years ago
source link: https://blog.duval.top/2021/01/30/%E6%B7%B1%E5%85%A5-MySQL-2-%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

本文介绍 MySQL 的几个重要的日志文件以及两阶段提交的原理。

binlog(二进制日志)

  • binlog 是MySQL Server 层的逻辑日志,可以被所有存储引擎使用;
  • binlog 日志常用于数据恢复、复制以及审计;
  • binlog 可以是 ROW、 STATEMENT、MIXED 三种格式:
    • ROW 格式下 binlog 日志记录的是每个数据行变化前和变化后的内容,因此占用空间相对较大;
    • STATEMENT格式 下,binlog 日志记录的是执行的 SQL 语句;
    • MIXED 格式下,默认采用 STATEMENT 格式,某些情况下会选择性地采用 ROW 格式;
  • 仅凭 binlog 日志是不能确保MySQL crash-safe的;
  • binlog日志是顺序追加写到磁盘文件,文件达到一定大小后会切换到下一个,因此不会发生数据覆盖;
  • 重要主库推荐配置 sync_binlog=1 ,可以使得MySQL每次提交事务都会将binlog日志同步到磁盘上,保证服务器崩溃的时候不会丢失数据;此外,如果是 Innodb 引擎,还需要配置 innodb_support_xa 为 1,才能确保二进制日志与 InnoDB 存储数据文件的同步(也就是下文的两阶段提交确保不丢失数据)。

redo log(重做日志)

  • redo log是InnoDB引擎特有的物理日志;

  • WAL 技术,WAL 的全称是 Write-Ahead Logging,它的关键点就是先写日志,再写磁盘数据;

  • redo log记录的是某个数据页做了什么修改;

  • 凭借redo log可以确保InnoDB的crash-safe;凭借redo log和binlog实现的两阶段提交可以保障MySQL的crash-safe;

  • redo log日志是固定大小的循环写,超过文件大小会擦除老日志;

    redo log循环写.png

    redo log循环写.png

  • 重做日志并不是直接写日志文件,而是先写一个重做日志缓冲(redo log buffer),然后再按照一定条件顺序写入日志文件。常见条件包括:

    • 主库配置 innodb_flush_log_at_trx_commit=1 ,可以使得每次提交事务都会将 buffer 刷到日志文件,保证服务器崩溃的时候不会丢失数据;
    • 主线程每秒会将重做日志缓冲写入日志文件,不论事务是否已经提交。

undo log (回滚日志)

  • 回滚日志记录的是事务的行为,当事务由于某种原因执行失败或者用户手动回滚的时候,便可以通过回滚日志来恢复缓冲池数据至历史版本;
  • 回滚日志默认保存在共享表空间中(也就是 ibdata 文件中);如果配置了 innodb_undo_tablespaces=N,则会保存到单独的undo001~undoN 文件中;

两阶段提交

两阶段提交.png

两阶段提交.png

两阶段提交过程:

  • 1.新数据更新到内存;
  • 2.新数据写入redo log,并处于prepare状态;
  • 3.写入binlog;
  • 4.提交事务,使redo log 更新为commit状态。

crash-safe保障原理:

  • 如果在步骤2之前数据库宕机,因为redo log 和binlog都没写入,内存数据丢失,所以不影响一致性;
  • 如果在步骤3之前数据库宕机,因为redo log存在且处于prepare状态,但检查binlog发现不存在,则回滚事务。所以不影响数据一致性;
  • 如果在步骤4之前数据库宕机,因为redo log存在且处于prepare状态,而检查binlog发现存在,则执行步骤4。所以事务成功,也不影响数据一致性;
  • 如果在步骤4之后数据库宕机,因为redo log存在且处于commit状态。所以不影响数据一致性。

binlog和redo log的联系:

它们有一个共同的数据字段,叫XID。崩溃恢复的时候,会按顺序扫描redo log:如果碰到commit状态的redo log,就直接提交;如果碰到只有 parepare状态的redo log,就拿着XID去binlog找对应的事务。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK