zoukankan      html  css  js  c++  java
  • mysql日志

    一、简介

    mysql有2个重要的日志模块:redo log(重做日志)和binlog(归档日志)

    二、redo log

    redo log是WAL技术(Write-Ahead Logging),先写日志,再写磁盘,是InnoDB引擎特有的,主要用于在数据恢复时还原innodb buffer pool中的脏数据页

    redo log的日志是一个环

    redo log可以保证之前提交的记录都不丢失,这个能力成为crash-safe

    由于redo log每次事务提交都要写一次磁盘,而且是顺序的,容易受限于io,所以InnoDB有组提交功能,可以将多个事务redo log的刷盘动作合并,减少磁盘顺序写

    innodb_flush_log_at_trx_commit

    为0:每秒将日志缓冲区写入log file,并同时flush到磁盘,跟事务提交无关,在机器crash并重启后,会丢失一秒的事务日志数据(并不一定是1s,也许会有延迟,跟操作系统调度有关),性能相对较高,可以在高并发时使用

    默认为1:每次事务提交时MySQL都会把log buffer的数据写入log file,并且flush(刷到磁盘)中去,性能相对较低(crash不会丢失数据)

    为2:每次事务提交将日志缓冲区写入log file,每秒flush一次到磁盘(crash有可能丢失数据)

    建议设置为1,保证异常重启后不丢失数据

    innodb_support_xa

    默认为1:开启两阶段提交,保证恢复后数据的一致性

    为0:关闭两阶段提交,innodb在prepare阶段就什么也不做,这可能会导致binlog的顺序与innodb提交的顺序不一致

    三、binlog

    binlog是Server层的日志,只依靠binlog没有crash-safe能力

    redo log是物理日志,记录的是"在某个数据页上做了什么修改",binlog是逻辑日志,记录的是这个语句的原始逻辑,比如"给ID=2 这一行的c字段加1"

    redo log是循环写的,空间固定会用完,binlog是可以追加写的,当文件写到一定大小后会切换到下一个,不会覆盖以前的日志

    sync_binlog

    默认为0:表示MySQL不控制binlog的刷新,由文件系统自己控制它的缓存的刷新。这时候的性能是最好的,但是风险也是最大的。因为一旦系统Crash,在binlog_cache中的所有binlog信息都会被丢失

    为 > 0:表示每sync_binlog次事务提交,MySQL调用文件系统的刷新操作将缓存刷下去,直到第n次事务再去刷新,有时需要牺牲一定的一致性,可以获得更高的并发和性能

    为1:每次事务提交都刷新,性能相对较低,最安全(这里的刷新意思是binlog cache写入disk的过程,会占用磁盘IOPS)

    建议设置为1,保证异常重启后binlog不丢失数据

    四、两阶段提交

    执行器和InnoDB引擎执行update语句的过程:

    1、执行器先找引擎取ID=2这一行,引擎用树搜索到这一行,如果数据页在内存中就直接返回,否则从磁盘读入内存返回

    2、执行器拿到行数据后,把值+1,再调用引擎接口写入新数据

    3、引擎将新数据更新到内存中,同时将更新操作记录到redo log里,此时redo log处于prepare状态。然后告知执行器执行完成了,随时可以提交事务

    4、执行器生成这个操作的binlog,并写入磁盘

    5、执行器调用引擎的提交事务接口,引擎把谷歌写入的redo log改成commit状态,更新完成

    为什么两阶段提交可以保证数据完整性(包括主从)?

    在数据更新到内存后,在写入redo log之前(还未开启事务提交),如果crash则更新当做未完成,不用恢复

    在写入redo log完毕进入prepare后,写binlog之前,如果crash则事务回滚

    在写入redo log完毕进入prepare后,写binlog时,如果crash则判断,如果binlog完整,则恢复过程中提交事务,如果不完整就回滚事务(binlog有结束标志可以判断是否完整)

    在已经处于commit状态时,恢复过程中提交事务

    为什么两阶段提交?

    因为如果redo log提交完成了,事务就不能回滚了,这时如果binlog写入失败,数据就和binlog日志不一致了,所以要等binlog完成以后再提交redo log事务

    为什么redo log和binlog缺一不可?

    binlog没有崩溃恢复的能力,它没有记录数据页的更新细节, 如果出现数据页级的丢失无法补回

    binlog也有redo log无法踢打的功能:redo log是循环写,起不到归档的作用;binlog复制功能是mysql高可用的基础

    参考:MySQL实战45讲

  • 相关阅读:
    LeetCode 4 :Majority Element
    LeetCode 3 :Min Stack
    Oracle操作4
    plsql安装教程
    java Date与String互相转化
    Oracle操作3
    Oracle操作2
    Oracle操作
    Oracle11g修改密码
    Visual Studio2013完全卸载
  • 原文地址:https://www.cnblogs.com/ctxsdhy/p/13491160.html
Copyright © 2011-2022 走看看