定点分析: MySQL InnoDB是如何保证系统异常断电情况下的数据可靠性?
MySQL支持事务,所以保证数据可靠的前提是对数据的修改事务已经成功提交
这个问题可以解释为‘MySQL InnoDB是如何保证事务C(一致性)D(持久性)性的?’
可能出现的两种情况:
- (一致性)数据不一致。 例如本来在一个事务里要执行两条SQL,结果系统断电导致只有一条SQL执行成功了
- (持久性)写入数据丢失。 本来要写入的两条数据由于系统断电数据都没有写进去
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是如何保证系统异常断电情况下的数据可靠性?的更多相关文章
- 如何在不使用系统函数的情况下实现PHP中数组系统函数的功能
PHP中为我们提供了各种各样的系统函数来实现我们需要的各种功能,那么,在不使用系统函数的情况下我们要怎样来实现这些功能呢?以下就是几种系统函数的实现方式. 首先,我们来定义一个数组: $arr= ar ...
- 关于MySQL什么时候使用索引问题以及什么情况下应不建或少建索引
一,什么情况下使用索引1. 表的主关键字 自动建立唯一索引 2. 表的字段唯一约束 ORACLE利用索引来保证数据的完整性 3. 直接条件查询的字段 在SQL中用于条件约束的字段 如zl_yhjbqk ...
- C++11 std::call_once:保证函数在任何情况下只调用一次
std::call_once的作用是很简单的, 就是保证函数或者一些代码段在并发或者多线程的情况下,始终只会被执行一次.比如一些init函数,多次调用可能导致各种奇怪问题. 给个例子: #includ ...
- 系统在某些情况下会自动调节UIScrollView的contentInset
出现情景 如果一个控制器(ViewController)被导航控制器管理,并且该控制器的第一个子控件是UIScrollView,系统默认会调节UIScrollView的contentInset UIE ...
- 【Nginx】不改系统源代码的情况下,动态网站离线缓存方案
背景: 公司的一套系统,由前端.界面.服务层.大数据开发平架等多层组成,每一层被划分为多个模块,每个模块会依赖若干组建.由于公司的这套系统是部署在内网环境中的,现在需要拿出去给客户演示,用一个笔记本装 ...
- 在mysql 上如何在不影响生产的情况下删除一个大表
mysql 中常用的删除的方法基本上有下面三种方式: 1.delete 一般用于删除少量表中的数据 优化建议,一定要加上where 条件,并且where条件的列上 一定要有主键或者索引.否则会出现全表 ...
- 在docker容器下利用数据卷实现在删除了mysql容器或者镜像的情况下恢复数据
当把mysql容器销毁,在新建一个容器,进行之前的数据恢复. 因为之前建立了数据卷,那么现在就可以利用这个数据卷进行数据恢复. 使用docker volume create volume_name命令 ...
- MySQL InnoDB技术内幕:内存管理、事务和锁
前面有多篇文章介绍过MySQL InnoDB的相关知识,今天我们要更深入一些,看看它们的内部原理和机制是如何实现的. 一.内存管理 我们知道,MySQl是一个存储系统,数据最后都写在磁盘上.我们以前也 ...
- MySQL InnoDB的一些参数说明
参考:http://addls.com/mysql-innodb-%E4%B9%8B-ibdata1-%E7%98%A6%E8%BA%AB%E5%A4%A7%E6%B3%95.html # 备份数据库 ...
随机推荐
- svn 发布脚本整合
svn提交时出现(413 Request Entity Too Large)错误解决方法 在nginx的server配置中增加 client_max_body_size 100M; linux多实例a ...
- 设计模式 --> (16)观察者模式
观察者模式 定义对象间的 一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新.它还有两个别名,依赖(Dependents),发布- 订阅(Publish-Sub ...
- node.js应用脚手架:koa2、sequelize、mysql
自制了一个 nodejs 应用的脚手架. 基于 koa2 的,所以需要保证 node 环境至少为 7.6.0 吸取了以前的踩坑教训,添加了守护进程,确保应用不会因为异常导致网站直接挂掉(使用了 for ...
- [BZOJ 1297][SCOI2009]迷路
1297: [SCOI2009]迷路 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1418 Solved: 1017[Submit][Status ...
- C++ STL常用容器基本用法汇总
1.vector 包含头文件#include<vector> 使用命名域using namespace std 定义元素类型为T的vector vector<T> vec 增: ...
- 201621123060《JAVA程序设计》第九周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 2. 书面作业 本次作业题集集合 1. List中指定元素的删除(题集题目) 1.1 实验总结.并回答:列举至 ...
- PTA博客制作的模版
C高级第 次PTA作业( ) 题目 - 此处填写题目名称 1.设计思路 (1)算法 (2)流程图 2.实验代码 此处填写代码 3.本题调试过程碰到问题及解决办法 错误信息: 错误原因: 改正方法: 提 ...
- 转 Eclipse快捷键调试大全
(1)Ctrl+M --切换窗口的大小(2)Ctrl+Q --跳到最后一次的编辑处(3)F2 ---重命名类名 工程名 --当鼠标放在一个标记处出现Tooltip时候按F2则把鼠标移开时To ...
- 《高级软件测试》JIRA使用手册(一)JIRA基本情况
JIRA 官方网站为:https://www.atlassian.com/software/jira 中文代理网站为:https://www.jira.cn 现版本:v7.3.0 Atlassian公 ...
- bzoj 4399 魔法少女LJJ
4399: 魔法少女LJJ Time Limit: 20 Sec Memory Limit: 162 MBhttp://www.lydsy.com/JudgeOnline/problem.php?i ...