zoukankan      html  css  js  c++  java
  • 初探Mysql架构和InnoDB存储引擎

    前言

    mysql相信大家都不陌生了,分享之前我们先思考几个面试题:

    1.undo log和redo log了解过吗?它们的作⽤分别是什么?

    2.redo log是如何保证事务不丢失的?

    3.mysql的事务是先提交还是先刷盘?

    4.更新操作为什么不直接更新磁盘反而设计这样⼀个复杂的InnoDB存储引擎来完成?

    下面我们开始逐步探索Mysql架构的运行流程。

    前台操作触发Mysql服务器执⾏请求

    前台⽤户各种操作触发后台sql执⾏,通过web项⽬中⾃带的数据库连接池:如dbcp、c3p0、druid等,与数据库服务器的数据库连接池建⽴⽹络连接;

    数据库连接池中的线程监听到请求后,将接收到的sql语句通过SQL接⼝响应给查询解析器,

    查询解析器将sql按照sql的语法解析出查询哪个表的哪些字段,查询条件是啥;

    再通过查询优化器处理,选择该sql最优的⼀套执⾏计划,然后执⾏器负责调⽤存储引擎的⼀系列接⼝,执⾏该计划⽽完成整个sql语句的执行,如下图所示:

    InnoDB存储引擎-缓冲池中完成更新的基本操作

    具体执⾏这些执⾏计划得要存储引擎来完成,比如⾸次更新users表中id=10的这条数据,缓冲池中⼀开始肯定没有该条数据的,

    得要先从磁盘中将被更新数据的原始数据加载到缓冲池中(这⾥涉及到的innodb buffer暂时不讲)。

    同时为了保证并发更新数据安全问题,会对这条数据先加锁,防⽌其他事务进⾏更新。

    接着将更新前的值先备份写⼊到undo log中(便于事务回滚时取旧数据),⽐如update语句即存储被更新字段之前的值。

    最后更新缓存⻚中的数据为最新的数据,⾄此就完成了在缓冲池中的执⾏流程,如下图所示: 

    Redo Log和BinLog保证事务的可靠性

    缓冲池中更新完数据后,需要将本次的更新信息顺序写到Redo Log⽇志以及Binlog⽇志中(此时信息还在内存中),

    Redo Log刷盘策略由innodb_flush_log_at_trx_commit属性值来定,

    0:不会写到磁盘
,宕机会导致已提交事务数据丢失

    1:数据过来即写磁盘,做到教据零丢失但是效率会很低

    2:写到os cache,每秒刷新一次到磁盘,宕机最多丢失1s的数据,速度够快

    Binlog刷盘策略由sync_binlog属性来定,

    1:强制刷盘;0:写入os cache。

    ⼀般我们为了保证数据不丢失会配置双1策略,

    Redo Log落盘后,写Binlog落盘,再将Binlog的⽂件名、⽂件所在路径信息以及commit标记给同步顺序写到Redolog中(其中commit标记是否更新到Redo Log中,是判定事务是否成功提交的⼀个⽐较重要的标准),

    Redo Log和BinLog分别在物理和逻辑层⾯为本次事务、提供数据上的⼀致性保障,如下图所示

    将事务的操作持久化

    前⾯⼀些列操作执⾏成功后,InnoDB存储引擎后台有⼀个IO线程,会在数据库压⼒的低峰期间时如凌晨时分,

    将缓冲池中被事务更新、但还没来得及写到磁盘中的数据(脏数据,因为磁盘数据和内存数据已经不⼀致了)给刷到磁盘中,完成事务的持久化。

    面试题解答

    1.undo log和redo log了解过吗?它们的作⽤分别是什么?

    undo log和redo log是mysql中InnoDB存储引擎的基本组成:

    (1)undo log保存了事务执⾏前数据的值,以便于事务回滚时能回到事务执⾏前的数据版本,多次更

    新会有undo log的版本链;

    (2)redo log在物理层⾯上记录了事务操作的⼀系列信息,保证就算遇到mysql宕机等因素还没来得

    及将数据刷到磁盘⾥,通过redo log也能恢复事务提交的数据。

    2.redo log怎样保证事务不丢失的?

    当⼀个事务提交成功后,虽然缓冲池中的数据不⼀定来得及⻢上落地到磁盘中,但是redo log记录的

    事务信息持久化到磁盘中了、且含有commit标记,此时如果mysql宕机导致缓冲池中的、已经被事务更新

    过的内存数据丢失了,此时在mysql重启时,将磁盘中的redo log中将事务变更信息给加载到缓冲池中,

    保证事务信息不会丢失。或者redo log刷盘了,binlog写成功了,在重启时会⾃动给上commit标记,在重

    放数据。

    3.事务是先提交还是先刷盘?

    事务先提交后刷盘;

    1.Redo log刷盘成功->2.Binlog刷盘->3.BinLog名称和⽂件路径信息、commit标志写到Redo log

    中,事务两阶段提交的⽅式来保证。

    4.更新操作为什么不直接更新磁盘反⽽设计这样⼀个复杂的InnoDB存储引擎来完成?

    直接更新磁盘是随机IO写,存在磁盘地址寻址操作,性能⾮常低,承载不了⾼并发场景;

    ⽽转换为InnoDB中,内存⾼速读写、redo log和undo log顺序写磁盘性能相对于随机IO写性能会⾼

    的多,⽽这种性能上的提⾼⾜以抵消这种架构上带来的复杂,可在⼀定QPS内承载⾼并发场景。

    往期文章推荐:

    JVM专栏

    消息中间件专栏

    并发编程专栏

    微信搜索“HUC思梦”关注我吧,关注有惊喜,不定时有免费资源分享!
  • 相关阅读:
    xamarin开发UWP元素的初始化设置顺序
    MailKit---状态更改和删除
    MailKit---获取邮件
    xamarin MasterDetailPage点击Master时卡顿现象
    xamarin UWP ActivityIndicator
    wpf ListView DataTemplate方式的鼠标悬停和选中更改背景色
    wpf Webbrowser 乱码问题及弹窗被遮挡
    47.go get安装库以及gopm替换方式——2020年04月12日21:04:30
    46.GRPC初识——2020年04月12日20:45:43
    45.解决github仓库下载慢问题——2020年04月12日
  • 原文地址:https://www.cnblogs.com/lm970585581/p/14578253.html
Copyright © 2011-2022 走看看