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/

定点分析: MySQL InnoDB是如何保证系统异常断电情况下的数据可靠性?的更多相关文章

  1. 如何在不使用系统函数的情况下实现PHP中数组系统函数的功能

    PHP中为我们提供了各种各样的系统函数来实现我们需要的各种功能,那么,在不使用系统函数的情况下我们要怎样来实现这些功能呢?以下就是几种系统函数的实现方式. 首先,我们来定义一个数组: $arr= ar ...

  2. 关于MySQL什么时候使用索引问题以及什么情况下应不建或少建索引

    一,什么情况下使用索引1. 表的主关键字 自动建立唯一索引 2. 表的字段唯一约束 ORACLE利用索引来保证数据的完整性 3. 直接条件查询的字段 在SQL中用于条件约束的字段 如zl_yhjbqk ...

  3. C++11 std::call_once:保证函数在任何情况下只调用一次

    std::call_once的作用是很简单的, 就是保证函数或者一些代码段在并发或者多线程的情况下,始终只会被执行一次.比如一些init函数,多次调用可能导致各种奇怪问题. 给个例子: #includ ...

  4. 系统在某些情况下会自动调节UIScrollView的contentInset

    出现情景 如果一个控制器(ViewController)被导航控制器管理,并且该控制器的第一个子控件是UIScrollView,系统默认会调节UIScrollView的contentInset UIE ...

  5. 【Nginx】不改系统源代码的情况下,动态网站离线缓存方案

    背景: 公司的一套系统,由前端.界面.服务层.大数据开发平架等多层组成,每一层被划分为多个模块,每个模块会依赖若干组建.由于公司的这套系统是部署在内网环境中的,现在需要拿出去给客户演示,用一个笔记本装 ...

  6. 在mysql 上如何在不影响生产的情况下删除一个大表

    mysql 中常用的删除的方法基本上有下面三种方式: 1.delete 一般用于删除少量表中的数据 优化建议,一定要加上where 条件,并且where条件的列上 一定要有主键或者索引.否则会出现全表 ...

  7. 在docker容器下利用数据卷实现在删除了mysql容器或者镜像的情况下恢复数据

    当把mysql容器销毁,在新建一个容器,进行之前的数据恢复. 因为之前建立了数据卷,那么现在就可以利用这个数据卷进行数据恢复. 使用docker volume create volume_name命令 ...

  8. MySQL InnoDB技术内幕:内存管理、事务和锁

    前面有多篇文章介绍过MySQL InnoDB的相关知识,今天我们要更深入一些,看看它们的内部原理和机制是如何实现的. 一.内存管理 我们知道,MySQl是一个存储系统,数据最后都写在磁盘上.我们以前也 ...

  9. MySQL InnoDB的一些参数说明

    参考:http://addls.com/mysql-innodb-%E4%B9%8B-ibdata1-%E7%98%A6%E8%BA%AB%E5%A4%A7%E6%B3%95.html # 备份数据库 ...

随机推荐

  1. Vmware虚拟机不能使用键盘的解决方法

    有个笔记本thinkpad T440要重装系统,但又怕前面的资料丢失,因此打算直接将整个物理机迁移到VCenter 6.5上去,比GHOST什么的方便多了,利用Vmware Convert工具直接在线 ...

  2. linux --> 为什么寄存器比内存快?

    为什么寄存器比内存快 计算机的存储层次(memory hierarchy)之中,寄存器(register)最快,内存其次,最慢的是硬盘. 原因一:距离不同 距离不是主要因素,但是最好懂,所以放在最前面 ...

  3. c++ --> cin和cout输入输出格式

    cin和cout输入输出格式 Cout 输出 1>. bool型输出 cout << true <<" or " << false < ...

  4. CSS速查列表-3-(font)字体

    CSS Fonts(字体) CSS字体属性定义 1.字体:font-family 属性设置文本的字体系列.p{font-family:"Times New Roman", Time ...

  5. sphinx的安装

    1.下载sphinx 没想到sphinx3解压后即可: wget http://sphinxsearch.com/files/sphinx-3.0.2-2592786-linux-amd64.tar. ...

  6. hibernate框架学习笔记8:一对多关系案例

    两个实体类:客户与联系人,一个客户可以有多个联系人 客户类: package domain; import java.util.HashSet; import java.util.Set; //客户实 ...

  7. MySQL之集合函数与分组查询

    这是分组查询用到的语句,也包括了排序以及常用的集合函数

  8. ajax 返回Json方法

    public static void sendJsonData(String data) { ActionContext ac = ActionContext.getContext(); HttpSe ...

  9. Linux进程调度分析

    原文:http://www.2cto.com/os/201112/113229.html 操作系统要实现多进程,进程调度必不可少. 有人说,进程调度是操作系统中最为重要的一个部分.我觉得这种说法说得太 ...

  10. 201621123027 《Java程序设计》第1周学习总结

    01621123027 <Java程序设计>第1周学习总结 1.本周学习总结 关键词:总概.承接.面向对象化 ​ 我认为第一周的Java学习是一些总结概括性质的内容,在比较联系之前学习过的 ...