zoukankan      html  css  js  c++  java
  • 定点分析: MySQL InnoDB是如何保证系统异常断电情况下的数据可靠性?

    MySQL支持事务,所以保证数据可靠的前提是对数据的修改事务已经成功提交
    这个问题可以解释为‘MySQL InnoDB是如何保证事务C(一致性)D(持久性)性的?’

    可能出现的两种情况:

    1. (一致性)数据不一致。 例如本来在一个事务里要执行两条SQL,结果系统断电导致只有一条SQL执行成功了
    2. (持久性)写入数据丢失。 本来要写入的两条数据由于系统断电数据都没有写进去

    MySQL遵循日志先行的准则,写日志要先于写数据。这里的日志包括redo日志和undo日志。redo日志用于记录数据更新后的的值,undo日志记录数据修改前的值,在写数据之前redo日志和undo日志都会
    写到日志文件里。系统断电丢数据的主要原因是数据库为了提高性能会在IO上加缓存,比如insert一条数据可能不会立即刷入磁盘里,而是暂时写到系统的内存缓存里,当达到某个定义的阈值时才会把缓存
    里的数据刷新到磁盘上,数据库里的数据和日志可以看成一行一行的数据,每一条数据或日志都有一个序列号,每次执行刷新缓存的时候都会把当前最新刷新到的序列号记录下来,比如当前数据刷新到了1000行,
    redo日志执行到了3000行这样。这个在MySQL里叫做checkpoint(检查点),小于最新检查点的数据就表示已经持久化到磁盘里了,系统重启的时候只需要处理大于检查点的日志即可。

    redo日志和undo日志的执行的简化流程如下:

    假设有两个数据A,B值分别为1,2

    A. 事务开始
    B. 记录 A = 1 到undo log
    C. 修改 A = 3
    D. 记录 A = 3到redo log
    E. 记录B = 2到undo log
    F. 修改 B = 4
    G. 记录B=4到redo log
    H. 将redo log和undo log写入磁盘
    I. 事务提交

    当数据库系统重启时会把大于检查点的所有redo log表示的数据更新都重新执行一遍,包括未提交的事务。然后再
    根据undo log把所有未提交的事务反向重做一遍(比如原始sql为insert,那么就执行delete,redo log和
    undo log都是存储引擎层面的,所以这里的所有执行动作都是基于数据文件的)。

    通过执行redo日志可以保证只要成功提交了事务,那么提交的数据就不会丢失。

    通过执行undo日志可以保证没有提交成功的日志,不会造成写一半数据的情况。

    参考:

    https://www.letiantian.me/2014-06-18-db-undo-redo-checkpoint/

    http://www.zhdba.com/mysqlops/2012/04/06/innodb-log1/

    https://www.cnblogs.com/chenpingzhao/p/5107480.html/

    https://www.cnblogs.com/fjdingsd/p/5273008.html/

  • 相关阅读:
    $动态规划系列(1)——金矿模型的理解
    $Java HttpClient库的使用
    $Java-json系列(二):用JSONObject解析和处理json数据
    $百度应用引擎BAE的使用与应用部署
    利用ajax短轮询+php与服务器交互制作简易即时聊天网站
    MYSQL explain详解
    Redis 5种数据结构使用及注意事项
    Redis 存储机制
    memcache
    mysql分表和表分区详解
  • 原文地址:https://www.cnblogs.com/caiyao/p/8832890.html
Copyright © 2011-2022 走看看