MYSQL为什么能做到数据的一致性?

架构小魔方2024-04-24 21:25:08  51

什么是事务?

众所周知,MYSQL是一个事务性的数据库,它可以绝对可靠保证数据一致性,目前也广泛用于线上实时在线业务,目前各大互联网公司均采用MYSQL,就算是一些公司自研的数据库也是基于开源MYSQL基础进行优化和改造,那么MYSQL到底是如何保证数据的一致性的呢?

要说到MYSQL的一致性,那就不得不提事务,事务有一个ACID特性(原子性、隔离性、持久性以及一致性)。

原子性(Atomicity):一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节,而且事务在执行过程中发生错误,会被回滚到事务开始前的状态,就像这个事务从来没有执行过一样,就好比买一件商品,购买成功时,则给商家付了钱,商品到手;购买失败时,则商品在商家手中,消费者的钱也没花出去。

一致性(Consistency):是指事务操作前和操作后,数据满足完整性约束,数据库保持一致性状态。比如,用户 A 和用户 B 在银行分别有 800 元和 600 元,总共 1400 元,用户 A 给用户 B 转账 200 元,分为两个步骤,从 A 的账户扣除 200 元和对 B 的账户增加 200 元。一致性就是要求上述步骤操作后,最后的结果是用户 A 还有 600 元,用户 B 有 800 元,总共 1400 元,而不会出现用户 A 扣除了 200 元,但用户 B 未增加的情况(该情况,用户 A 和 B 均为 600 元,总共 1200 元)。

隔离性(Isolation):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致,因为多个事务同时使用相同的数据时,不会相互干扰,每个事务都有一个完整的数据空间,对其他并发事务是隔离的。也就是说,消费者购买商品这个事务,是不影响其他消费者购买的。

持久性(Durability):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失.

MYSQL的存储架构

首先来看下MYSQL的存储架构,它分为三个主要的文件,undo log(回滚日志)、redo(重做日志)和binlog(归档日志),而事务中的原子性主要是通过undo log 来保证的,持久性是通过redo log 来保证,隔离性是通过MVCC(多版本并发控制)来保证的,一致性是通过持久性+原子性+隔离性来保证,而数据库的主从数据一致是通过binlog日志来保证的。详细来说,这个四个文件的作用如下:

undo log(回滚日志):是 Innodb 存储引擎层生成的日志,实现了事务中的原子性,主要用于事务回滚和 MVCC。

redo log(重做日志):是 Innodb 存储引擎层生成的日志,实现了事务中的持久性,主要用于掉电等故障恢复;

binlog(归档日志):是 Server 层生成的日志,主要用于数据备份和主从复制;

MYSQL如何保证数据的一致性?

当写入一条数据时,先会记录 undo log 日志,然后 redo log 会记录事务执行后的数据, 事务提交后,会同步写入binlog 日志,在通过二阶段来保证redolog和binlog的一致性,避免主从数据不一致,事务提交后数据会更新到buffer pool 缓冲,在由innodb_flush_log_at_trx_commit参数控制刷盘的频率,undolog记录的是事务执行之前的数据,如果事务执行过程中失败,根据undolog进行事务回滚。

Undo log 是逻辑日志,可以理解为:

当delete一条记录的时候,Undo log会记录下一条insert语句,当insert一条记录的时候,Undo log会记录下一条delete语句,当update一条记录时,Undo log会记录下一条相反的update语句

Redo log日志与Undo log恰恰相反

Redo log记录的是新数据的备份,在事务提交前,只需要将 Undo log持久化即可,不需要将数据持久化。当系统崩溃时,虽然数据没有持久化,但是 Undo log已经持久化。系统可以根据 Undo log的内容,将数据恢复到最新的状态。

为什么要采用二阶段来保证一致性?

当需要向表中插入一条记录X的时候。

情况一:

如果先写binlog再写redo log,那么假设binlog写完后崩溃后,此时redo log还没写。那么重启恢复的时候就会出现问题,binlog中已经有X的记录,当从主机同步数据的时候,或者使用binlog恢复数据的时候,就会同步X这条记录。但是redo log中没有关于X的记录,所以恢复崩溃之后,插入X记录的这个事务是无效的,即数据库中没有该行的记录,这就造成了数据不一致的情况。

情况二:

如果是先写redo log再写 binlog,那么假设redo log写完后崩溃了,此时binlog还没写。那么重启恢复的时候也会出现问题,redo log中已经有X的记录了,所以崩溃恢复之后,插入X记录的这个事务是有效的,通过该记录可以将数据恢复到数据库中;但是binlog中还没有关于X的记录,所以当从机从主机同步数据的时候,或者使用binlog恢复数据的时候,就不会同步到X这条记录,这就造成了数据不一致。

两阶段提交如何保证数据一致性?

情况一:一阶段提交之后崩溃了,即已写入 redo log,处于 prepare 状态的时候崩溃了,此时由于 binlog 还没写,redo log 处于 prepare 状态还没提交,所以崩溃恢复的时候,这个事务会回滚,此时 binlog 还没写,所以也不会传到备库。

情况二:假设写完 binlog 之后崩溃了,此时redo log 中的日志是不完整的,处于 prepare 状态,还没有提交,那么恢复的时候,首先检查 binlog 中的事务是否存在并且完整,如果存在且完整,则直接提交事务,如果不存在或者不完整,则回滚事务。

情况三:假设 redo log 处于 commit 状态的时候崩溃了,那么重启后的处理方案同情况二。

由此可见,两阶段提交能够确保数据的一致性。

转载此文是出于传递更多信息目的。若来源标注错误或侵犯了您的合法权益,请与本站联系,我们将及时更正、删除、谢谢。
https://www.414w.com/read/398787.html
0
随机主题
惹众怒! 南通支云转争议文章, 内涵泰山申花球迷, 遭球迷集体抵制【猛男快报】英特尔月湖信息解禁,三大内核全更新,确认今年Q3发布!上合外长会议召开,中方没与印外长对话,莫迪想在金砖“出风头”20万买沃尔沃值得买吗 一文告诉你男单爆大冷! 男单世界冠军2-3日本选手, 无缘开门红, 球迷很意外科比没有詹姆斯一样强悍的身体天赋, 否则生涯绝对不仅仅是5冠打起来了? 以军再次发起“斩首行动”, 以色列或被围攻, 美英失声德甲保级推送: 波鸿VS杜塞尔多夫, 不败金身再添一局, 德甲升降机名不虚传!曝森林北爱上汪峰损失大, 活动被取消, 阳光清纯遭质疑, 但不后悔37岁生日拿下生涯1100胜, 德约科维奇剑指法网冠军奖杯乌苏为10家拥军企业授牌内地封杀的女星, 被岛国拍出来了空军有歼20, 海军有超级航母, 解放军陆军也终于迎来新型重装备?楚悦辰: 5.23黄金现价2380空单进场, 目标2350南海交锋,外军4打2,解放军战机遭火控雷达锁定,现场惊心动魄1950年毛岸英牺牲, 9年后罗瑞卿密电任荣: 主席有一项任务交给你揭秘大公司生产操作:ASML或可远程关闭台积电光刻机11集之后, 《庆余年2》终于挽回口碑, 6个老戏骨, 被严重低估了坎塞洛叫板c罗,没资格鞭打督邮:上司对刘备敲诈勒索,张飞:先暴揍他一顿!最佳阵容8大遗珠: 马克西领衔, 福克斯场均26+5, 三位状元被低估
最新回复(0)