当前位置:首页 > 文章列表 > 数据库 > MySQL > MySQL事务熟练使用就够?和腾讯大佬的一席对话,原来考点都在这些方面!

MySQL事务熟练使用就够?和腾讯大佬的一席对话,原来考点都在这些方面!

来源:SegmentFault 2023-01-13 20:24:52 0浏览 收藏

大家好,今天本人给大家带来文章《MySQL事务熟练使用就够?和腾讯大佬的一席对话,原来考点都在这些方面!》,文中内容主要涉及到MySQL、原理、面试、后端,如果你对数据库方面的知识点感兴趣,那就请各位朋友继续看下去吧~希望能真正帮到你们,谢谢!

苍茫大地一剑尽挽破,何处繁华笙歌落。 难道这普天之下尽没我容纳之处?为何这面试官总要与我争风相对,这不是难为人吗?

每次经历痛领悟,总会悠然南山下,独自愁楚。记录心中一片大海,唯有独自努力,方能实现行业之俊杰。

我内心不忍一颤,今天怕是要遇到人了。整整一个架构师的大叔呀。

果不其然,他手里拿着我的简历,快速的扫了一下,然后用眼角余光看了一下我,像是在掂量着什么。上来开口即问。

事务简介和原理

面试官: 看你简历描述精通 Mysql 优化方法,那你先说说你对Mysql的事务的了解吧。

我吒吒辉内心独自平静了一些,这个不难,就是一个事务定义和执行得调用的方法。殊不知后面的内容都是对我得严刑拷打。

吒吒辉: 好呢,数据库的事务是指一组sql语句访问各种数据项的数据库逻辑处理单元,在这组 SQL 操作中,要么全部执行成功,要么全部执行失败。

举个经典的例子就是转账,事务 A 要进行转账,那么,转出的账号要扣钱,转入的账号要加钱,这两操作要么同时执行成功,要么都全部执行失败。为得就是确保数据的一致性。

吒吒辉: 一般请求进入MySQL,都是根据不同请求类型先在服务层内部做数据处理,然后在由后台线程把数据刷到磁盘中。从而避免频繁的读写磁盘。

回答完毕后,自己笑笑的模一下头发,打理一下自己的发型,整理了一下脖子上得领结。

面试官:吆喝,这小子还有点料啊,敢在太岁头上动土,你还要反了天呀你。还在这欺负我头上的没头发。个小崽子。

面试官: 刚你提到了 MySQL 内部的工作,那你知道事务的特性吗? 数据是如何刷盘? 服务层数据如何修改? 这样得工作模式有什么好处? 怎么避免频繁写入? 读请求和写请求在服务层工作是一样的吗?

我内心一钝,这老秃驴,不要命啦,逮到这么问我。看来自己得正经点,感觉空气中弥漫着杀气腾腾的气息。

尴尬的冲他笑了一笑。立马说到

吒吒辉: 在Mysql中事务的四大特性主要包含:
原子性(Atomicity)
一致性(Consistent)
隔离性(Isalotion)
持久性(Durable),简称为 ACID。由它们共同来保证数据的一致性。

面试官: 嗯,说说你对这四大特的理解?

吒吒辉:

  • 原子性: 故名思议原子是最小的元素单位,所以一个事务是一个不可拆分的最小工作单元。整个事务操作要么全部执行成功,要么全部失败回滚。

因执行成功和失败都是状态的变化,如果只有执行效果只有一半,数据就会不完整,从而违背了原子的特点。

  • 一致性: 指数据库从一个一致性的状态转换到另外一个一致性的状态。要保证事务前后的状态要一致
  • 隔离性:一个事务所做的修改在最终提交以前,对其他事务是不可见的。
  • 持久性:一旦事务提交,则其所做的修改就会永久保存到磁盘上。是执行结果一直生效。

面试官: 那数据库底层是如何实现这四大特性的?

顿时,我望向他那张有点油腻的大脸,可他确实气定神闲的望着我,面相是多么的随和。此刻内心不断策马崩腾,第一个问题就给我整了这么多,后面可咋办? 内心感觉悬了

吒吒辉:

  • 原子性:由 undo log 保证,也称回滚日志,主要用于记录数据被修改前的信息

undo log 主要记录数据的逻辑变化。所以需要将之前的操作都记录下来,然后在发生错误或执行事务回滚时才能保证回滚到之前的操作。

面试官: 那这个请求过程是怎么实现的?

比如当写请求为 insert 操作进入到数据库服务层时,会先在缓冲池下面的写缓冲中进行数据的写入,然后先把写请求的物理语言写入到 read log中,并记录一条删除当前语句的逻辑语句到 undo log中。 最后由 MySQL 后台线程定期刷新数据到磁盘里面。

但是这个写缓冲在5.5之前叫 插入缓冲,只针对 insert 优化; 现在对 update 和 delete更新操作都有效。现在叫做:写缓冲

面试官: 这个写缓冲有什么好处呢?

吒吒辉:
避免频繁磁盘I/O的写操作,如果没得这玩意,需要在磁盘里面读到数据,然后才能数据上面的修改。

但大多数场景下都是读多写少,如果在高并发的场景下,通过打包批次处理就能有效避免,在写操作处理时资源开销而影响到大量得读请求。

  • 一致性: 由 Redo log 日志保证,也叫重做日志,是用来实现事务的持久性。该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log),前者是在内存中,后者在磁盘中。

    当事务提交之后会把所有修改信息都会存到该日志中。假设有个表叫做t1(id,username) 现在要插入数据(3,'吒吒辉')。

start transaction;
  //数据写入 写缓冲中
insert into t1 (id,username) values (3,'吒吒辉')
// 生成 重做日志 id =3 , username = '吒吒辉'
commit;

面试官: 那这 redo log 有什么作用?

为了提升性能,不会把每次的修改都实时同步到磁盘,而是会先存到Boffer Pool(缓冲池)里头,把这个当作缓存来用。然后使用后台线程去做缓冲池和磁盘之间的同步。

面试官: 那如果缓冲池的数据还没来得急同步就宕机或断电了怎么办? 这样可是会导致丢部分已提交事务的修改信息!

吒吒辉: 所以引入redo log来记录已成功提交事务的修改信息,并且会把redo log持久化到磁盘,系统重启之后在读取redo log恢复最新数据

面试官: 可以举一个场景,怎么应用它们呢?

吒吒辉: 假如某个时刻数据库崩溃,在崩溃之前有相关事务在执行,一半已经提交,一半还未提交。当数据库重启进行 crash-recovery 时,就会通过 Redo log将已经提交事务的更改先载入到内存,然后再写到数据文件,而还没有提交的就通过 Undo log 进行 roll back。

面试官: 嗯,继续

此时,内心发毛。回答到这个程度,还面不改色,就一个继续打发我了?你可真是深造。

吒吒辉:

  • 隔离性 也叫多版本并发控制。

    InnoDB的 MVCC ,是通过在每行记录的后面保存两个隐藏的列来实现的。这两个列, 一个保存了行的创建时间,一个保存了行的过期时间(或删除时间), 当然存储的并不是实际的时间值,而是系统版本号。

--摘自《高性能Mysql》这本书对MVCC的定义

面试官: 那不同的SQL请求,MySQL 是如何实现得?

吒吒辉:

    • select 请求根据系统当前的事务版本号去和数据列中版本号做对比,先过滤存在过期时间的数据列。然后取出满足小于或者等于当前版本号的记录。
    • insert innodb为每插入一行,就保留当前系统版本号为行版本
    • delete innodb为删除每一行,就保存当前系统版本号作为行删除标识。
    • update innodb为insert 插入一行新记录,保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为行删除标识。

    面试官: 那这个机制有什么好处?

    吒吒辉:
    它主要实现思想是通过数据多版本来做到读写分离。每个请求给到不同版数据来执行。从而实现不加锁读进而做到读写并行。
    MVCC机制实现还需要依赖于 undo log与read view

    undo log: undo log 中记录某行记录的多个版本的数据。

    read view: 用来判断当前版本数据的可读性

    面试官: 那你给我画个图看看

    什么鬼,这玩意还画图。我用那水汪汪的大眼睛,直勾勾的看着他。只见他看口说到。

    **面试官:没明白吗? 就是用白板笔画出原理图解

    吒吒辉: 我急忙应和到。额额额,好


    吒吒辉: 就这样,每个请求修改时就会对应一个版本。

    面试官: 那这 MVCC 是如何保证多个版本数据得最终一致呢?

    吒吒辉: 因数据操作为多个版本,所以它支持读写并行。

    在请求进行事务操作前,会先入到读、写队列里面,然后再分别执行读写请求。若第一个写请求执行事务但未提交,但这时它就会拿到最新版本。

    如果此时读请求进入也会直接执行,只不过读取数据时得系统版本就为未执行写请求的版本号,根据它来进行数据的读取。

    这样在事务未进行提交前,所有读操作读取到的数据是一样的,因为它受系统当前版本控制。读取的都是同一个版本数据。

    面试官: MySQL是多线程, 那同时有多个线程修改同一行数据,这种情况怎么处理的?

    吒吒辉: 一般如果系统达到并发执行的情况,对用户请求得要求是很高的,每秒至少得几万请求,如有并发问题产生。

    假如事务 A、B 都要执行 update 操作,事务A先 update 数据时,会先获取行锁,锁定数据,当事务 B 要进行 update 操作时,也会尝试获取该数据行的行锁,但此时已经被事务A占有,故事务B只能 wait。

    吒吒辉: 如事务A,是个很费时的大SQL,长时间没释放锁。那么事务 B 就会等待超时。

    查询全局等待事务锁超时时间
    SHOW GLOBAL VARIABLES LIKE 'innodb_lock_wait_timeout';

    面试官: 这个是在 update 的where后的条件是在有索引的情况下吧?

    吒吒辉: 嗯,是的,因为 innodb 的行数只有索引才会触发,锁定的是行锁

    面试官: 那没有索引的条件下,就没办法快速定位到数据行呀?

    吒吒辉: 若是没有索引的条件下,就会退化为表锁。 然后获取所有行后,Mysql 再过滤符合条件的的行并释放锁。往后只有符合条件的行才持有锁。

    吒吒辉: 这样就降低了并发度,并且性能开销也会很大。

    吒吒辉: 而最后的一致性,实际上是通过原子性、持久性、隔离性来实现的

    此刻,感觉自己多少放松了一些,内心有点小得意,感觉达到了巅峰时刻。然后再拿着面前的矿泉水,饮了一口,顺便擦了下汗水。一切是那么得行云流水。然而面试官那脸还是一沉不变,像是在酝酿着什么,这不又开始了。

    MySQL 内核工作原理

    面试官: 那请继续数据是如何刷盘? 这样得工作模式是怎么避免频繁读写得?

    吒吒辉: 说到数据刷盘,首先得谈下 innodb 缓冲池。

    buffer pool 主要由数据、索引、插入缓冲、自适应哈希索引、锁等组成。

    不同请求会根据 buffer pool里面对应部分数据来执行相关的操作。buffer pool中的数据会根据配置参数定期同步到磁盘中;只是这里刷盘的数据主要由 数据和日志 组成。

    数据

    由 innodb_max_dirty_pages_pct 参数决定。在说到这个之前,得说说脏页

    脏页指存在于内存中的数据,但未同步到持久化存储里面,因为数据库的数据用页来读取,故此称之为脏页。

    innodb_max_dirty_pages_pct 参数可动态调整,最小值为0, 最大值为99.99,默认值为 75。

    根据缓冲池的大小和存储脏页的数量计算比例,如果满足了就调用后台线程把数据刷新到持久层当中里面。

    这样做的好处就是合并其它数据页,从而提高写入的效率。

    日志

    由 innodb_flush_log_at_trx_commit 变量来控制日志缓冲刷新频繁程度。

    • 0:把日志缓冲写到日志文件,并且每秒钟刷新一次持久化存储,但是事务提交时不做任何事。
    • 1: 将日志缓冲写到日志文件,并且每次事务提交都刷新到持久化存储。这是默认的(并且是最安全的)设置,该设置能保证不会丢失任何已经提交的事务,除非磁盘或者操作系统是“伪”刷新,即写入到磁盘缓冲
    • 2: 每次提交时把日志缓冲写到日志文件,但是并不刷新到持久化存储。InnoDB 每秒做一次刷新到持久化存储。一般也会选2,如果MySQL进程“挂了”,2 不会丢失任何事务。如果整个服务器“挂了”或者断电了,则还是可能会丢失 1s 的事务。

    为什么上面把日志缓冲写到日志文件,还没到持久化存储呢?

    因为在大部分操作系统中,把日志缓冲写到日志文件只是简单地把数据从 InnoDB 的内存缓冲转移到了操作系统的缓存,也是在内存里,并没有真的把数据写到了持久化存储。所以还需要进行数据磁盘同步的刷写。

    吒吒辉: 缓冲池是降低频繁得读写请求,这个得分情况来看:

    • 读请求: 请求首先在缓冲池下面找缓存的数据,从而避免每次访问都进行磁盘IO。
    • 写请求:事务请求执行时,先根据日志缓冲配置的方式把数据记录到日志文件中,等数据的脏页达到一定比例或内存不够时,就会把数据落地磁盘上。

    从而把大量磁盘的随机I/O改写为顺序I/O。
    每次更新相关请求都基于 MVCC 特性拿到当前操作数据最新版本,从而并发执行多个版本。

    面试官: 嗯嗯

    瞬间感觉被榨干了,怎么都这样出招,幸好以前多少有点准备。忽然感觉自己身后开始滑落着汗滴。只见面试官看了看简历,脸上表情祥和,感觉在端详着什么。。。。

    面试官: 小伙,这今天就面到这里,我看你好像有点热呀,先回去等通知吧

    感情你老这才开胃呀!还能这样整。行不行你到是给句花呗。让我流这么多汗,我得喝多少水才补得回来,这不虚都被你搞虚。瞬间炸裂开来

    吒吒辉: 这样啊,那好吧。。。。

    我命由我不由天,只为那不甘心的,如有帮助,关注分享额 文章持续更新,可微信搜索「莲花童子哪吒 」第一时间阅读,还有在线技术答疑群聊
    图片描述

    本篇关于《MySQL事务熟练使用就够?和腾讯大佬的一席对话,原来考点都在这些方面!》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于数据库的相关知识,请关注golang学习网公众号!

    版本声明
    本文转载于:SegmentFault 如有侵犯,请联系study_golang@163.com删除
    mysql数据实时同步到Elasticsearch注意事项mysql数据实时同步到Elasticsearch注意事项
    上一篇
    mysql数据实时同步到Elasticsearch注意事项
    拥有大厂梦,却因为MySQL败下阵来,那你一定要看这本经典之作
    下一篇
    拥有大厂梦,却因为MySQL败下阵来,那你一定要看这本经典之作
    查看更多
    最新文章
    查看更多
    课程推荐
    • 前端进阶之JavaScript设计模式
      前端进阶之JavaScript设计模式
      设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
      542次学习
    • GO语言核心编程课程
      GO语言核心编程课程
      本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
      508次学习
    • 简单聊聊mysql8与网络通信
      简单聊聊mysql8与网络通信
      如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
      497次学习
    • JavaScript正则表达式基础与实战
      JavaScript正则表达式基础与实战
      在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
      487次学习
    • 从零制作响应式网站—Grid布局
      从零制作响应式网站—Grid布局
      本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
      484次学习
    查看更多
    AI推荐
    • 笔灵AI生成答辩PPT:高效制作学术与职场PPT的利器
      笔灵AI生成答辩PPT
      探索笔灵AI生成答辩PPT的强大功能,快速制作高质量答辩PPT。精准内容提取、多样模板匹配、数据可视化、配套自述稿生成,让您的学术和职场展示更加专业与高效。
      13次使用
    • 知网AIGC检测服务系统:精准识别学术文本中的AI生成内容
      知网AIGC检测服务系统
      知网AIGC检测服务系统,专注于检测学术文本中的疑似AI生成内容。依托知网海量高质量文献资源,结合先进的“知识增强AIGC检测技术”,系统能够从语言模式和语义逻辑两方面精准识别AI生成内容,适用于学术研究、教育和企业领域,确保文本的真实性和原创性。
      22次使用
    • AIGC检测服务:AIbiye助力确保论文原创性
      AIGC检测-Aibiye
      AIbiye官网推出的AIGC检测服务,专注于检测ChatGPT、Gemini、Claude等AIGC工具生成的文本,帮助用户确保论文的原创性和学术规范。支持txt和doc(x)格式,检测范围为论文正文,提供高准确性和便捷的用户体验。
      30次使用
    • 易笔AI论文平台:快速生成高质量学术论文的利器
      易笔AI论文
      易笔AI论文平台提供自动写作、格式校对、查重检测等功能,支持多种学术领域的论文生成。价格优惠,界面友好,操作简便,适用于学术研究者、学生及论文辅导机构。
      38次使用
    • 笔启AI论文写作平台:多类型论文生成与多语言支持
      笔启AI论文写作平台
      笔启AI论文写作平台提供多类型论文生成服务,支持多语言写作,满足学术研究者、学生和职场人士的需求。平台采用AI 4.0版本,确保论文质量和原创性,并提供查重保障和隐私保护。
      35次使用
    微信登录更方便
    • 密码登录
    • 注册账号
    登录即同意 用户协议隐私政策
    返回登录
    • 重置密码