大叔, 据说你入职了一家新公司?mysql
大叔诧异的看了我一眼, 问你这个家伙咋知道的?git
我看你的脉脉更新了啊.sql
年轻人你刚入职场没多久, 就别成天看脉脉了, 有这时间还不如多学习会儿呢.数据库
大叔从地铁站出来, 须要打开亿通行APP, 获取到一个地铁站二维码, 扫码后对应的通道闸机就会打开.markdown
正常状况下, 钱扣了闸机打开了,此次交易就结束了.并发
大叔坐地铁的场景映射到数据库有如下概念:mvc
出站扣费看做一个原子.高并发
扫码出站后扣费, 不能扣了大叔的钱, 闸机还不打开, 这样大叔确定会跳起来的.性能
不扣帐户的钱, 闸机自动给大叔打开, 大叔开心了, 这个地铁运营公司也不干.学习
扫码闸机打开, 只能大叔本身经过高峰时期排队也有可能本身扫码让别人进去了(咱们通常经过人工智能保证隔离性)
大叔乘进站和出站要有乘车记录, 咱们须要将它固化下来.
原子性+隔离性+持久性 组成了一致性
在数据库中, 咱们称以上为事务(ACID), 事务是必须知足原子性、隔离性、一致性和持久性的.
一致性是基础,也是最终目的,其余三个特性(原子性、隔离性和持久性)都是为了保证一致性的 在比较简单的场景(没有高并发)下,可能会发生一些数据库崩溃等状况,这个时候,依赖于对日志的 REDO/UNDO 操做就能够保证一致性 而在比较复杂的场景(有高并发)下,可能会有不少事务并行的执行,这个时候,就极可能致使最终的结果没法保证一致性.
每周五下午, 大叔所在的小组就须要把这周的工做进度同步到 wiki 一个周报里.
由于人多集中时间写, 好屡次提交都跟其余同事冲突, 大叔经过学习数据库隔离级别概念的思路解决了这个问题, 咱们来看看他是怎么作的吧.
同事小王还没提交工做进度, 就被我看到了(嘿嘿~), 这种咱们称为脏读问题.
同事小王提交了工做进度, 又被我看到了, 这种咱们称为不可重复读.
同事小王提交了工做进度, 可是当前我没退出编辑状态, 仍是我以前读到的数据(可重复读)
可是~ 小李新增的进度咋展现出来了...(新插入数据致使幻读)
上面三个方案看起来一个比一个好, 可是都有点问题, 大叔会心一笑, 心想我在学 mysql小册 时候就知道这些问题啦, 彻底能够靠最高隔离级别-串行化解决
因而组内提议: 同时只有一我的可读写, 提议谁要编辑在群里说一下, 改完后再通知下一我的再操做吧, 这样就能够避免冲突.
然而串行化虽然能够避免冲突, 可是对于性能影响过大, 当通知下一我的时候, 若是下一我的迟迟不回复, 可能须要等一段时间确认会浪费一些时间.
大叔又仔细想了想, git 提交代码也是每一个人同时进行, 为何写个 wiki 这就这么费劲呢?
咱们每一个人基于当前本身的改动生成一个版本, 提交后与最新版本比对, 解决冲突.
MVCC,全称Multi-Version Concurrency Control,即多版本并发控制.
主要是为了提升数据库并发性能,用更好的方式去处理读-写冲突,作到即便有读写冲突时,也能作到不加锁,非阻塞并发读, InnoDB 事务的可重复读和读取已提交隔离等级就是经过 mvcc+undo 实现的.
还记得咱们上一回合介绍的 InnoDB 行记录上隐藏了两个列为 事务trx_id 和 roll_pointer.
多个事务对 InnoDB 更改记录, 都会对应记录一条 undo日志, 每条 undo日志 也都有一个 roll_pointer 属性, 记录指向下一条 undo日志 的指针, 组成一个链表, 事务提交后 undo日志 删除.
大叔的工做地点坐落在中关村某栋大厦里, 比较幸运的是大厦负一层就有一个食堂餐厅, 中午坐电梯就能够直接到了(固然挤电梯也不容易)
上次就由于大叔点了一份鱼香肉丝盖饭, 由于商家作的时候发现没有鱼肉, 去提早采购, 致使大叔等了一个小时才吃到饭(困~).
大叔给商家想了一个办法, 每次客户的要求都要写到服务单中, 防止因服务员过于忙碌(服务崩溃)而忘了以后作的事情, 服务员只需按照服务单作事便可.
WAL(write ahead log) 预写式日志, 解决了服务崩溃数据恢复问题, 关键点在于先写日志再写磁盘, 在对数据页进行修改时, 经过将"修改了什么"这个操做记录在日志中, 而没必要立刻将更改内容刷新到磁盘上, 从而将随机写转换为顺序写, 提升了性能.
mysql 的 WAL 跟 redo log 是一回事, 一般是物理日志, 记录的是数据页的物理修改, 而不是某一行或某几行修改为怎样怎样, 它用来恢复提交后的物理数据页(恢复数据页,且只能恢复到最后一次提交的位置)
大叔给商家说, 若是发现食材不够了, 就让撤销订单好了, 把以前的付费记录查出来退钱, 我再从新下单.
undo log用来回滚行记录到某个版本。undo log通常是逻辑日志,根据每行记录进行记录.
多个事务对 InnoDB 更改记录, 都会对应记录一条 undo日志, 可重复读的隔离级别也是利用了undo log.
大叔终于找到了工做, 也没时间跟我聊天说话了, 固然这也是 mysql 最后一回合了, 但愿大叔可以在以后的职场和生活中顺利~