mysql数据库ACID实现原理
说到事物的四大特性原子性、一致性、隔离性、持久性,懂的人很多,但是稍微涉及细节,四大特性在数据库中的实现原理是怎么实现的?几乎很少有人能够答上来。所以这里着重讨论下mysql中的实现原理。
问题一:Mysql怎么保证一致性的?
OK,这个问题分为两个层面来说。
从数据库层面,数据库通过原子性、隔离性、持久性来保证一致性。也就是说ACID四大特性之中,C(一致性)是目的,A(原子性)、I(隔离性)、D(持久性)是手段,是为了保证一致性,数据库提供的手段。数据库必须要实现AID三大特性,才有可能实现一致性。例如,原子性无法保证,显然一致性也无法保证。
但是,如果你在事务里故意写出违反约束的代码,一致性还是无法保证的。例如,你在转账的例子中,你的代码里故意不给B账户加钱,那一致性还是无法保证。因此,还必须从应用层角度考虑。
从应用层面,通过代码判断数据库数据是否有效,然后决定回滚还是提交数据!
问题二: Mysql怎么保证原子性的?
OK,是利用Innodb的undo log。
undo log名为回滚日志,是实现原子性的关键,当事务回滚时能够撤销所有已经成功执行的sql语句,他需要记录你要回滚的相应日志信息。
例如
- (1)当你delete一条数据的时候,就需要记录这条数据的信息,回滚的时候,insert这条旧数据
- (2)当你update一条数据的时候,就需要记录之前的旧值,回滚的时候,根据旧值执行update操作
- (3)当年insert一条数据的时候,就需要这条记录的主键,回滚的时候,根据主键执行delete操作
undo log记录了这些回滚需要的信息,当事务执行失败或调用了rollback,导致事务需要回滚,便可以利用undo log中的信息将数据回滚到修改之前的样子。
ps:具体的undo log日志长啥样,这个可以写一篇文章了。而且写出来,看的人也不多,姑且先这么简单的理解吧。
问题三: Mysql怎么保证持久性的?
OK,是利用Innodb的redo log。
正如之前说的,Mysql是先把磁盘上的数据加载到内存中,在内存中对数据进行修改,再刷回磁盘上。如果此时突然宕机,内存中的数据就会丢失。
怎么解决这个问题?
简单啊,事务提交前直接把数据写入磁盘就行啊。
这么做有什么问题?
- 只修改一个页面里的一个字节,就要将整个页面刷入磁盘,太浪费资源了。毕竟一个页面16kb大小,你只改其中一点点东西,就要将16kb的内容刷入磁盘,听着也不合理。
- 毕竟一个事务里的SQL可能牵涉到多个数据页的修改,而这些数据页可能不是相邻的,也就是属于随机IO。显然操作随机IO,速度会比较慢。
于是,决定采用redo log解决上面的问题。当做数据修改的时候,不仅在内存中操作,还会在redo log中记录这次操作。当事务提交的时候,会将redo log日志进行刷盘(redo log一部分在内存中,一部分在磁盘上)。当数据库宕机重启的时候,会将redo log中的内容恢复到数据库中,再根据undo log和binlog内容决定回滚数据还是提交数据。
采用redo log的好处?
其实好处就是将redo log进行刷盘比对数据页刷盘效率高,具体表现如下
- redo log体积小,毕竟只记录了哪一页修改了啥,因此体积小,刷盘快。
- redo log是一直往末尾进行追加,属于顺序IO。效率显然比随机IO来的快。
ps:不想具体去谈redo log具体长什么样,因为内容太多了。
问题四: Mysql怎么保证隔离性的?
OK,利用的是锁和MVCC机制。还是拿转账例子来说明,有一个账户表如下
表名t_balance
id |
user_id |
balance |
1 |
A |
200 |
2 |
B |
0 |
其中id是主键,user_id为账户名,balance为余额。还是以转账两次为例,如下图所示
至于MVCC,即多版本并发控制(Multi Version Concurrency Control),一个行记录数据有多个版本对快照数据,这些快照数据在undo log中。
如果一个事务读取的行正在做DELELE或者UPDATE操作,读取操作不会等行上的锁释放,而是读取该行的快照版本。
由于MVCC机制在可重复读(Repeateable Read)和读已提交(Read Commited)的MVCC表现形式不同,就不赘述了。
但是有一点说明一下,在事务隔离级别为读已提交(Read Commited)时,一个事务能够读到另一个事务已经提交的数据,是不满足隔离性的。但是当事务隔离级别为可重复读(Repeateable Read)中,是满足隔离性的。
mysql数据库ACID实现原理相关推荐
- Mysql数据库存储的原理
Mysql数据库存储的原理 Mysql储存过程简介 Mysql数据库存储的优点 1.存储过程能实现较快的执行速度. 2.存储过程允许标准组件是编程. 3.存储过程可以用流控制语句编写,有很强的灵活性, ...
- 数据库acid实现原理(二)
一.基础概念 事务(Transaction)是访问和更新数据库的程序执行单元:事务中可能包含一个或多个sql语句,这些语句要么都执行,要么都不执行.作为一个关系型数据库,MySQL支持事务,本文介绍基 ...
- MySQL事务ACID实现原理
照例,我们先来一个场景~ 面试官:"知道事务的四大特性么?" 你:"懂,ACID嘛,原子性(Atomicity).一致性(Consistency).隔离性(Isolati ...
- 使用Memcache缓存mysql数据库操作的原理和缓存过程浅析
1.首先明确是不是一定要上缓存,当前架构的瓶颈在哪里,若瓶颈真是数据库操作上,再继续往下看. 2.明确memcached和redis的区别,到底要使用哪个.前者终究是个缓存,不可能永久保存数据(LRU ...
- 阿里P8架构师谈:MySQL数据库的索引原理、与慢SQL优化的5大原则
MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓"好马配好鞍",如何能够更好的使用它,已经成为开发工程师的必修 ...
- [数据库] 一文读懂Mysql数据库索引实现原理
咱们用了这么久Mysql数据库做项目,你知道数据是怎么存在数据库里吗?他们是如何存储的吗? 今天咱们就来扒一扒Mysql数据库索引的底层实现,Mysql数据库的索引是由都是由B+树实现的,那为什么不是 ...
- mysql数据库访问控制_一文总结MySQL数据库访问控制实现原理
MySQL 访问控制实际上由两个功能模块共同组成,一个是负责"看守 MySQL 大门"的用户管理模块,另一个就是负责监控来访者每一个动作的访问控制模块.用户管理模块决定用户是否能登 ...
- 清空缓存的命令_超详细的mysql数据库查询缓存原理解析、涉及命令、流程分析等...
概述 mysql查询缓存在数据库优化可以起到很大的作用,今天主要针对这一块做一个总结,下面一起来看看吧~ 一.缓存条件,原理 MySQL Query Cache是用来缓存我们所执行的SELECT语句以 ...
- MySQL数据库底层实现原理
一.MySQL 历史: 1996年发布,2003年MySQL加入innodb. 历史版本有5.5 /5.7:最新版本8.0. 二.MySQL原理: 当执行SQL的时候,数据库底层到底发生了什么? My ...
最新文章
- 深度学习“见顶”不等于AI寒冬
- centos的网络配置
- 团队项目——ASC Master
- 类选择器与ID选择器的比较
- mysql 组复制和传统复制_MySQL的GTID复制与传统复制的相互切换
- ASP.NET Core 简单实现七牛图片上传(FormData 和 Base64)
- 的表格点击全选_“逼死”强迫症的杂乱表格,原来3秒就能整理好!(必学)...
- 使用FlashFXP V3.8烈火汉化绿色版软件连接Linux
- MairDB 修改表(三)
- mysql编译gcov_Mysql 编译参数详解
- Kotlin入门(13)类成员的众生相
- QTsocket网络编程
- 《麦肯锡方法》读书笔记17
- 171021 逆向-Xp0intCTF(re300)
- 阿里云服务器公网带宽下载上传速度及测速Ping值测试工具
- 计算机的学情分析报告,计算机教学计划合集总结5篇
- 区块链应用 | 高盛报告深度解读:区块链在未来的5大应用
- L1-058 6翻了 (15 分)循环的妙用
- 如何用小程序玩转裂变?你要的小程序裂变营销都在这里
- 拥有一本CISP证书,我的工资会翻倍吗?
热门文章
- 如何让char不要忽略开头的空格_如何使用C语言实现JSON解析库(二)
- python 把numpy.ndarray转为图像_Python 让蔡徐坤在我的命令行里打篮球?打得还不错...
- HDoj-1863-畅通project-并查集
- MultiResolution研究
- IDC分析报告:亚洲安全软件市场兴旺
- qt翻译--QDragMoveEvent拖放类
- Leetcode Math刷题笔记
- Linux下批量修改文件名
- 简练软考知识点整理-建设项目团队
- 解决sourceTree的git clone 报SSH密钥认证失败的问题