前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >(第四回合)回龙观大叔狂磕mysql

(第四回合)回龙观大叔狂磕mysql

作者头像
用户2825413
发布2022-04-19 09:37:03
3520
发布2022-04-19 09:37:03
举报
文章被收录于专栏:呆呆熊的技术路

大叔, 听说你入职了一家新公司?

大叔诧异的看了我一眼, 问你这个家伙咋知道的?

我看你的脉脉更新了啊.

年轻人你刚入职场没多久, 就别整天看脉脉了, 有这时间还不如多学习会儿呢.

image.png

大叔地铁站出行

image.png

大叔从地铁站出来, 需要打开亿通行APP, 获取到一个地铁站二维码, 扫码后对应的通道闸机就会打开.

正常情况下, 钱扣了闸机打开了,这次交易就结束了.

大叔坐地铁的场景映射到数据库有以下概念:

1.原子性

出站扣费看作一个原子.

扫码出站后扣费, 不能扣了大叔的钱, 闸机还不打开, 这样大叔肯定会跳起来的.

不扣账户的钱, 闸机自动给大叔打开, 大叔开心了, 这个地铁运营公司也不干.

2.隔离性

扫码闸机打开, 只能大叔自己通过高峰时期排队也有可能自己扫码让别人进去了(我们一般通过人工智能保证隔离性)

3.持久性

大叔乘进站和出站要有乘车记录, 我们需要将它固化下来.

4.一致性

原子性+隔离性+持久性 组成了一致性

总结

在数据库中, 我们称以上为事务(ACID), 事务是必须满足原子性、隔离性、一致性和持久性的.

一致性与其他特性的关系

一致性是基础,也是最终目的,其他三个特性(原子性、隔离性和持久性)都是为了保证一致性的 在比较简单的场景(没有高并发)下,可能会发生一些数据库崩溃等情况,这个时候,依赖于对日志的 REDO/UNDO 操作就可以保证一致性 而在比较复杂的场景(有高并发)下,可能会有很多事务并行的执行,这个时候,就很可能导致最终的结果无法保证一致性.

大叔写工作进度汇报

每周五下午, 大叔所在的小组就需要把这周的工作进度同步到 wiki 一个周报里.

因为人多集中时间写, 好多次提交都跟其他同事冲突, 大叔通过学习数据库隔离级别概念的思路解决了这个问题, 我们来看看他是怎么做的吧.

在数据库标准中有4种隔离级别:

1.未提交读

同事小王还没提交工作进度, 就被我看到了(嘿嘿~), 这种我们称为脏读问题.

2.已提交读

同事小王提交了工作进度, 又被我看到了, 这种我们称为不可重复读.

3.可重复读 (mysql默认使用隔离级别)

同事小王提交了工作进度, 但是当前我没退出编辑状态, 还是我之前读到的数据(可重复读)

但是~ 小李新增的进度咋展示出来了...(新插入数据导致幻读)

4.可串行化

上面三个方案看起来一个比一个好, 但是都有点问题, 大叔会心一笑, 心想我在学 mysql小册 时候就知道这些问题啦, 完全可以靠最高隔离级别-串行化解决

于是组内提议: 同时只有一个人可读写, 提议谁要编辑在群里说一下, 改完后再通知下一个人再操作吧, 这样就可以避免冲突.

然而串行化虽然可以避免冲突, 但是对于性能影响过大, 当通知下一个人时候, 如果下一个人迟迟不回复, 可能需要等一段时间确认会浪费一些时间.

大叔又仔细想了想, git 提交代码也是每个人同时进行, 为什么写个 wiki 这就这么费劲呢?

我们每个人基于当前自己的改动生成一个版本, 提交后与最新版本比对, 解决冲突.

mysql的多版本并发控制

MVCC,全称Multi-Version Concurrency Control,即多版本并发控制.

主要是为了提高数据库并发性能,用更好的方式去处理读-写冲突,做到即使有读写冲突时,也能做到不加锁,非阻塞并发读, InnoDB 事务的可重复读和读取已提交隔离等级就是通过 mvcc+undo 实现的.

还记得我们上一回合介绍的 InnoDB 行记录上隐藏了两个列为 事务trx_id 和 roll_pointer.

多个事务对 InnoDB 更改记录, 都会对应记录一条 undo日志, 每条 undo日志 也都有一个 roll_pointer 属性, 记录指向下一条 undo日志 的指针, 组成一个链表, 事务提交后 undo日志 删除.

image.png

大叔中午食堂订餐

大叔的工作地点坐落在中关村某栋大厦里, 比较幸运的是大厦负一层就有一个食堂餐厅, 中午坐电梯就可以直接到了(当然挤电梯也不容易)

上次就因为大叔点了一份鱼香肉丝盖饭, 因为商家做的时候发现没有鱼肉, 去提前采购, 导致大叔等了一个小时才吃到饭(困~).

餐厅问题1:你给餐厅一位服务员说了, 但是互相传达不到

大叔给商家想了一个办法, 每次客户的要求都要写到服务单中, 防止因服务员过于忙碌(服务崩溃)而忘了之后做的事情, 服务员只需按照服务单做事即可.

WAL(write ahead log) 预写式日志, 解决了服务崩溃数据恢复问题, 关键点在于先写日志再写磁盘, 在对数据页进行修改时, 通过将"修改了什么"这个操作记录在日志中, 而不必马上将更改内容刷新到磁盘上, 从而将随机写转换为顺序写, 提高了性能.

mysql 的 WAL 跟 redo log 是一回事, 通常是物理日志, 记录的是数据页的物理修改, 而不是某一行或某几行修改成怎样怎样, 它用来恢复提交后的物理数据页(恢复数据页,且只能恢复到最后一次提交的位置)

餐厅问题2: 做到一半发现食材不够还让我等

大叔给商家说, 如果发现食材不够了, 就让撤销订单好了, 把之前的付费记录查出来退钱, 我再重新下单.

undo log用来回滚行记录到某个版本。undo log一般是逻辑日志,根据每行记录进行记录.

多个事务对 InnoDB 更改记录, 都会对应记录一条 undo日志, 可重复读的隔离级别也是利用了undo log.

image.png

餐厅问题3: 鱼香肉丝不用鱼

回龙观大叔总结

大叔终于找到了工作, 也没时间跟我聊天说话了, 当然这也是 mysql 最后一回合了, 希望大叔能够在之后的职场和生活中顺利~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小宇技术研究所 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 大叔地铁站出行
    • 1.原子性
      • 2.隔离性
        • 3.持久性
          • 4.一致性
            • 总结
              • 一致性与其他特性的关系
              • 大叔写工作进度汇报
                • 在数据库标准中有4种隔离级别:
                  • 1.未提交读
                  • 2.已提交读
                  • 3.可重复读 (mysql默认使用隔离级别)
                  • 4.可串行化
                • mysql的多版本并发控制
                  • 大叔中午食堂订餐
                    • 餐厅问题1:你给餐厅一位服务员说了, 但是互相传达不到
                    • 餐厅问题2: 做到一半发现食材不够还让我等
                    • 餐厅问题3: 鱼香肉丝不用鱼
                • 回龙观大叔总结
                相关产品与服务
                云数据库 SQL Server
                腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档