• 首页
  • 国产小呦泬泬99精品
  • 最近2019中文字幕在线高清
  • 免费看少妇作爱视频
  • 曰批全过程免费视频在线观看网站
  • 国色天香在线观看全集免费播放
  • 婆岳同床双飞呻吟
  • 国色天香在线观看全集免费播放你的位置:三级小说 > 国色天香在线观看全集免费播放 > 美团二面:如何料理 Bin Log 与 Redo Log 的一致性问题

    美团二面:如何料理 Bin Log 与 Redo Log 的一致性问题

    发布日期:2022-06-18 17:11    点击次数:174

    美团二面:如何料理 Bin Log 与 Redo Log 的一致性问题

    刚看见这个题标的技巧如故有点懵逼的,自后才反映过来其实问的等于 redo log 的两阶段提交

    老章程,背诵版在文末。点击阅读原文不错直达我收录整理的各大厂口试真题

    为什么说 redo log 具有崩溃规复的能力

    前边咱们说过,MySQL Server 层领有的 bin log 只可用于存档,不及以终了崩溃规复(crash-safe),需要借助 InnoDB 引擎的 redo log 才能领有崩溃规复的能力。所谓崩溃规复等于:即使在数据库宕机的情况下,也不会出现操作一半的情况

    至于为什么说 redo log 具有崩溃规复的能力,而 bin log 莫得,咱们先来简便看一下这两种日记有哪些不同点:

    1)适用对象不同:

    bin log 是 MySQL 的 Server 层终了的,通盘引擎都不错使用

    而 redo log 是 InnoDB 引擎独有的

    2)写入内容不同:

    bin log 是逻辑日记,纪录的是这个语句的原始逻辑,比如 “给 id = 1 这一滑的 age 字段加 1”

    redo log 是物理日记,纪录的是 “在某个数据页上做了什么修改”

    3)写入方式不同:

    bin log 是不错追加写入的。“追加写” 是指 bin log 文献写到一定大小后会切换到下一个,并不会隐秘以前的日记

    redo log 是轮回写的,空间固定会被用完

    不错看到,redo log 和 bin log 的一个很大的区别等于,一个是轮回写,一个是追加写。也等于说 redo log 只会纪录未刷入磁盘的日记,仍是刷入磁盘的数据都会从 redo log 这个有限大小的日记文献里删除。

    而 bin log 是追加日记,保存的是全量的日记。这就会导致一个问题,那等于莫得标志能让 InnoDB 从 bin log 中判断哪些数据仍是刷入磁盘了,哪些数据还莫得。

    举个例子,bin log 纪录了两条日记:

    纪录 1:给 id = 1 这一滑的 age 字段加 1 纪录 2:给 id = 1 这一滑的 age 字段加 1 

    假定在纪录 1 刷盘后,纪录 2 未刷盘时,数据库崩溃。重启后,只通过 bin log 数据库是无法判断这两札纪录哪条仍是写入磁盘,哪条莫得写入磁盘,无论是两条都规复至内存,如故都不规复,对 id = 1 这行数据来说,都是分手的。

    但 redo log 不一样,只好刷入磁盘的数据,都会从 redo log 中被抹掉,数据库重启后,径直把 redo log 中的数据都规复至内存就不错了。

    这等于为什么说 redo log 具有崩溃规复的能力,而 bin log 不具备。

    redo log 两阶段提交

    前边咱们先容过一条 SQL 查询语句的扩充过程,简便追思:

    MySQL 客户端与作事器间配置一语气,客户端发送一条查询给作事器;

    作事器先查验查询缓存,若是射中了缓存,则坐窝复返存储在缓存中的服从;不然投入下一阶段;

    作事器端进行 SQL 领会、预处理,生成正当的领会树;

    再由优化器生成对应的扩充计算;

    扩充器左证优化器生成的扩充计算,调用相应的存储引擎的 API 来扩充,并将扩充服从复返给客户端

    关于更新语句来说,这套经过相似亦然要走一遍的,不同的是,更新经过还波及两个环节的日记模块 bin log 和 redo log。

    以底下这条简便的 SQL 语句为例,咱们来评释下扩充器和 InnoDB 存储引擎在更新时做了哪些事情:

    update table set age = age + 1 where id = 1; 

    扩充器:找存储引擎取到 id = 1 这一滑纪录

    存储引擎:左证主键索引树找到这一滑,若是 id = 1 这一滑地方的数据页原来就在内存池(Buffer Pool)中,就径直复返给扩充器;不然, 97视频需要先从磁盘读入内存池,然后再复返

    扩充器:拿到存储引擎复返的行纪录,把 age 字段加上 1,获得一滑新的纪录,然后再调用存储引擎的接口写入这行新纪录

    存储引擎:将这行新数据更新到内存中,同期将这个更新操作纪录到 redo log 内部,此时 redo log 处于 prepare 景况。然后见告扩充器扩充完成了,随时不错提交事务

    珍惜不要把这里的提交事务和咱们 sql 语句中的提交事务 commit 敕令搞混了哈,咱们这里说的提交事务,指的是事务提交过程中的一个小要领,亦然临了一步。当这个要领扩充完成后,commit 敕令就扩充顺利了。

    扩充器:生成这个操作的 bin log,并把 bin log 写入磁盘

    扩充器:调用存储引擎的提交事务接口

    存储引擎:把刚刚写入的 redo log 景况改成提交(commit)景况,更新完成

    如下图所示:

    不错看到,所谓两阶段提交,其实等于把 redo log 的写入拆分红了两个要领:prepare 和 commit。

    是以,为什么要这么预备呢?这么预备若何就概况终了崩溃规复呢?

    左证两阶段提交,崩溃规复时的判断规定是这么的:

    若是 redo log 内部的事务是美满的,也等于仍是有了 commit 象征,则径直提交

    若是 redo log 内部的事务处于 prepare 景况,则判断对应的事务 binlog 是否存在并美满

    a. 若是 binlog 存在并美满,则提交事务; b. 不然,回滚事务。

    虽然,这么说小伙伴们确定没法走漏,国色天香在线观看全集免费播放底下来看几个实质的例子:

    如下图所示,假定数据库在写入 redo log(prepare) 阶段之后、写入 binlog 之前,发生了崩溃,此时 redo log 内部的事务处于 prepare 景况,binlog 还没写(对应 2b),是以崩溃的技巧,这个事务会回滚。

    Why?

    因为 binlog 还莫得写入,之后从库进行同步的技巧,无法扩充这个操作,可是实质上主库仍是完成了这个操作,是觉得了主备一致,在主库上需要回滚这个事务

    而况,由于 binlog 还没写,是以也就不会传到备库,从而幸免主备不一致的情况。

    而若是数据库在写入 binlog 之后,redo log 景况修改为 commit 前发生崩溃,此时 redo log 内部的事务仍然是 prepare 景况,binlog 存在并美满(对应 2a),是以即使在这个时刻数据库崩溃了,事务仍然会被日常提交。

    Why?

    因为 binlog 仍是写入顺利了,这么之后就会被从库同步以前,可是实质上主库并莫得完成这个操作,是觉得了主备一致,在主库上需要提交这个事务。

    是以,其实不错看出来,处于 prepare 阶段的 redo log 加上美满的 bin log,就能保证数据库的崩溃规复了。

    可能有同学就会问了,MySQL 咋线路 bin log 是不是美满的?

    简便来说,一个事务的 binlog 是有美满花样的(这个咱们在后头的著述中会细心评释):

    statement 花样的 bin log,临了会有 COMMIT row 花样的 bin log,临了会有 XID event

    而关于 bin log 可能会在中间出错的情况,MySQL 5.6.2 版块以后引入了 binlog-checksum 参数,用来考证 bin log 内容的正确性。

    思考一个问题,两阶段提交是必要的吗?可不行以先 redo log 写完,再写 bin log 或者反过来?

    1)关于先写完 redo log 后写 bin log 的情况:

    假定在 redo log 写完,bin log 还莫得写完的技巧,MySQL 崩溃。主库中的数据如实仍是被修改了,可是这技巧 bin log 内部并莫得纪录这个语句。因此,从库同步的技巧,就会丢失这个更新,和主库不一致。

    2)关于先写完 binlog 后写 redo log 的情况:

    若是在 bin log 写完,redo log 还没写的技巧,MySQL 崩溃。因为 binlog 仍是写入顺利了,这么之后就会被从库同步以前,可是实质上 redo log 还没写,主库并莫得完成这个操作,是以从库比较主库就会多扩充一个事务,导致主备不一致

    临了放上这道题的背诵版:

    口试官:

    问法 1:如何料理 bin log 与 redo log 的一致性问题? 问法 2:一条 SQL 更新语句是如何扩充的? 问法 3:讲一下 redo log / redo log 两阶段提交旨趣

    小牛肉:

    所谓两阶段提交,其实等于把 redo log 的写入拆分红了两个要领:prepare 和 commit。

    领先,存储引擎将扩充更新好的新数据存到内存中,同期将这个更新操作纪录到 redo log 内部,此时 redo log 处于 prepare 景况。然后见告扩充器扩充完成了,随时不错提交事务

    然后扩充器生成这个操作的 bin log,并把 bin log 写入磁盘

    临了扩充器调用存储引擎的提交事务接口,存储引擎把刚刚写入的 redo log 景况改成提交(commit)景况,更新完成

    若是数据库在写入 redo log(prepare) 阶段之后、写入 binlog 之前,发生了崩溃:

    此时 redo log 内部的事务处于 prepare 景况,binlog 还没写,之后从库进行同步的技巧,无法扩充这个操作,可是实质上主库仍是完成了这个操作,是觉得了主备一致,MySQL 崩溃时会在主库上回滚这个事务

     

    而若是数据库在写入 binlog 之后,redo log 景况修改为 commit 前发生崩溃,此时 redo log 内部的事务仍然是 prepare 景况,binlog 存在并美满,这么之后就会被从库同步以前,可是实质上主库并莫得完成这个操作,是觉得了主备一致,即使在这个时刻数据库崩溃了,主库上事务仍然会被日常提交。

     



    Powered by 三级小说 @2013-2022 RSS地图 HTML地图