本地事务的理论依据

放了方便描述,本问题讨论的是都是page-oriented系统。道理都是一样的,其他类型的系统也适用。在事务里,有两个最重要的特性:

  1. 原子性:原子性保证了事务的多个操作要么都生效要么都不生效,不会存在中间状态
  2. 持久性:持久性保证了一旦事务生效,就不会再因为任何原因而导致其修改的内容被撤销或丢失

众所周知,数据必须要成功写入硬盘等持久化存储器后才能拥有持久性。实现原子性和持久性的最大困难是“写入硬盘”这个操作并不是原子的,不仅有“写入”与“未写入”状态,还客观地存在着“正在写”的中间状态。所以如果不做额外保障措施,只是简单把内存中的数据写入磁盘,并不能保证原子性与持久性。这个中间态,大致可以归纳成3种情形:

  1. 未提交事务,部分持久化,程序崩溃:例如修改5个数据,已经修改了3个,其中2个已经持久化。程序崩溃后重启,因为事务未提交,需要把持久化后的数据恢复回去。
  2. 已提交事务,部分持久化,程序崩溃:例如修改5个数据,已经修改完,返回调用方成功,数据未持久化。程序就崩溃后重启,需要把丢失的变更重做回来。
  3. 已提交事务,完全没持久化,程序崩溃:同2。

我们可以看到,这些问题可以归纳成2个问题:

  1. 把脏数据恢复成之前的数据
  2. 把丢失的数据恢复回来

为了解决这两个问题,有3个流派,我们每个流派都说一下

  1. Shadow Paging
  2. Commit Logging
  3. Write-Ahead Logging

Shadow Paging

基本思想是这样的,对于问题1,如果我不in-place update,就没有脏数据了,也就没有把脏数据恢复之说; 对于问题2,如果事务提交成功的前提,数据已经持久化,那么就不用丢失数据了。因此Shadow Paging在修改数据的时候,会先copy一份副本,基于这个副本做修改,如果需要修改多个数据,那么就分别copy多个副本做修改,修改完后把数据持久化下来。事务提交时,就是把之前引用老数据的指针,指向新数据,然后持久化,持久化完后,事务就提交成功。如果被修改的指针分布在几个页面上,那么对每个一个页面,也是执行shadow paging的策略去更新,是一个递归的过程。这里大家可以看到有几个问题:

  1. copy page本身的开销,性能问题
  2. 修改引用page也可能走shadow paging,性能问题
  3. 提交事务需要数据频繁持久化,性能问题(是否是随机IO,取决于持久化层存储引擎)
  4. 一些隔离级别做起来成本高,例如支持read commit,那么就有mvcc,保存的是多个完整的page

可以看到shadow paging策略最大的问题,就是性能差。如果要优化的化,对于2、3,一般会结合接下来讨论的两个流派做优化。

Commit Logging

基本思想是这样的,对于问题1,如果事务不提交,我就不持久化,那就没脏数据了,也就没有把脏数据恢复之说;对于问题2,事务提交成功的前提,是我把所有修改记录,都append到日志中,提交时把事务提交的标记也append到log中,然后做日志持久化,这样就完成的事务提交。这时恢复数据就很容易的,而且性能也高,因为对于持久化存储append的性能很高。因此使用Commit Logging策略的系统,每次修改数据前,都先append log,log并不要求刷盘,事务里的所有数据都修改完了,append 一个commit标记到log中,然后对log进行刷盘,即事务完成提交了。对于事务提交后的部分持久化问题,可以通过在page处记录持久化时对page做修改的日志序号,避免重复做即可,或者把操作设计成保证幂等性。可以看到Commit Logging相比Shadow paging有不少优点:

  1. 不需要copy page,性能损耗小
  2. 提交事务,持久化的只是log,并且是append only,性能高
  3. mvcc好做,对于page内的每个记录一个版本号即可,不需要额外保存完整的page

但是Commit Logging也有一个明显的缺点,就是只有事务提交后,数据才能做持久化。这样在高并发常见下,可能不用充分利用硬盘的IO,而且对于大事务,所有数据都要在内存中hold住。为了改善这两点,就提出了Write-Ahead Logging。

Write-Ahead Logging

基本思想是这样的,对于问题1,如果事务不提交,持久化page的前提,是我记录下修改前的数据,那么脏数据就能恢复了,这个log称为undo log;对于问题2,解决方法和Commit Logging一样,这个log称为redo log。因此使用WAL的系统,修改数据的流程是这样的,对于每个修改诗句,修改前先append一条undo log,再append一条redo log,然后修改数据,事务未提交前,有数据要持久化时需要保证对应的undo log已经持久化。所有数据修改完后,append 一个commit标记到log中,然后对log进行刷盘,即事务完成提交了。系统崩溃服务重启,对数据进行恢复时,先不管三七二十一,把redo log里所有明确有提交的事务重放一边,然后在redo log里所有没提交的事务,去undo log那找log,把脏页的数据回滚回去。可以看到和Commit Logging相比,优点是:

  1. 充分利用硬盘IO,释放内存空间
  2. 大事务不需要把所有数据都hold在内存

理论化

我们将何时持久化变动数据,按照事务提交时点为界,划分为 FORCE 和 STEAL 两类情况:

  • FORCE:当事务提交时,要求变动数据必须同时完成写入则称为 FORCE,如果不强制变动数据必须同时完成写入则称为 NO-FORCE。
  • STEAL:在事务提交前,允许变动数据提前写入则称为 STEAL,不允许则称为 NO-STEAL。


    image.png

Shadow Paging FORCE + NO-STEAL。

Commit Logging NO-FORCE+ NO-STEAL。

Write-Ahead Logging NO-FORCE + STEAL。

现实中绝大多数数据库采用的都是 NO-FORCE 策略,因为只要有了日志,变动数据随时可以持久化,从优化磁盘 I/O 性能考虑,没有必要强制数据写入立即进行。从优化磁盘 I/O 性能考虑,允许数据提前写入,有利于利用空闲 I/O 资源,也有利于节省数据库缓存区的内存。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,219评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,363评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,933评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,020评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,400评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,640评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,896评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,597评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,327评论 1 244
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,581评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,072评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,399评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,054评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,849评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,672评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,585评论 2 270

推荐阅读更多精彩内容