unify the translation of write skew

This commit is contained in:
Gang Yin 2022-10-29 10:34:18 +08:00
parent c7a97457da
commit 9576f0a847
3 changed files with 6 additions and 6 deletions

View File

@ -482,7 +482,7 @@ BEGIN TRANSACTION;
COMMIT;
```
[例 12-2]() 依赖于 `request_id` 列上的唯一约束。如果一个事务尝试插入一个已经存在的 ID那么 `INSERT` 失败,事务被中止,使其无法生效两次。即使在较弱的隔离级别下,关系数据库也能正确地维护唯一性约束(而在 “[写入偏斜与幻读](ch7.md#写入偏斜与幻读)” 中讨论过,应用级别的 **检查 - 然后 - 插入** 可能会在不可串行化的隔离下失败)。
[例 12-2]() 依赖于 `request_id` 列上的唯一约束。如果一个事务尝试插入一个已经存在的 ID那么 `INSERT` 失败,事务被中止,使其无法生效两次。即使在较弱的隔离级别下,关系数据库也能正确地维护唯一性约束(而在 “[写入偏差与幻读](ch7.md#写入偏差与幻读)” 中讨论过,应用级别的 **检查 - 然后 - 插入** 可能会在不可串行化的隔离下失败)。
除了抑制重复的请求之外,[例 12-2]() 中的请求表表现得就像一种事件日志,暗示着事件溯源的想法(请参阅 “[事件溯源](ch11.md#事件溯源)”)。更新账户余额事实上不必与插入事件发生在同一个事务中,因为它们是冗余的,而能由下游消费者从请求事件中衍生出来 —— 只要该事件被恰好处理一次,这又一次可以使用请求 ID 来强制执行。
@ -543,7 +543,7 @@ COMMIT;
该算法基本上与 “[使用全序广播实现线性一致的存储](ch9.md#使用全序广播实现线性一致的存储)” 中的算法相同。它可以简单地通过增加分区数伸缩至较大的请求吞吐量,因为每个分区都可以被独立处理。
该方法不仅适用于唯一性约束,而且适用于许多其他类型的约束。其基本原理是,任何可能冲突的写入都会路由到相同的分区并按顺序处理。正如 “[什么是冲突?](ch5.md#什么是冲突?)” 与 “[写入偏斜与幻读](ch7.md#写入偏斜与幻读)” 中所述,冲突的定义可能取决于应用,但流处理器可以使用任意逻辑来验证请求。这个想法与 Bayou 在 90 年代开创的方法类似【58】。
该方法不仅适用于唯一性约束,而且适用于许多其他类型的约束。其基本原理是,任何可能冲突的写入都会路由到相同的分区并按顺序处理。正如 “[什么是冲突?](ch5.md#什么是冲突?)” 与 “[写入偏差与幻读](ch7.md#写入偏差与幻读)” 中所述,冲突的定义可能取决于应用,但流处理器可以使用任意逻辑来验证请求。这个想法与 Bayou 在 90 年代开创的方法类似【58】。
#### 多分区请求处理
@ -657,7 +657,7 @@ ACID 事务通常既提供及时性(例如线性一致性)也提供完整性
#### 维护完整性尽管软件有Bug
除了这些硬件问题之外,总是存在软件 Bug 的风险,这些错误不会被较低层次的网络、内存或文件系统校验和所捕获。即使广泛使用的数据库软件也有 Bug即使像 MySQL 与 PostgreSQL 这样稳健、口碑良好、多年来被许多人充分测试过的软件,就我个人所见也有 Bug比如 MySQL 未能正确维护唯一约束【65】以及 PostgreSQL 的可串行化隔离等级存在特定的写偏斜异常【66】。对于不那么成熟的软件来说情况可能要糟糕得多。
除了这些硬件问题之外,总是存在软件 Bug 的风险,这些错误不会被较低层次的网络、内存或文件系统校验和所捕获。即使广泛使用的数据库软件也有 Bug即使像 MySQL 与 PostgreSQL 这样稳健、口碑良好、多年来被许多人充分测试过的软件,就我个人所见也有 Bug比如 MySQL 未能正确维护唯一约束【65】以及 PostgreSQL 的可串行化隔离等级存在特定的写入偏差异常【66】。对于不那么成熟的软件来说情况可能要糟糕得多。
尽管在仔细设计,测试,以及审查上做出很多努力,但 Bug 仍然会在不知不觉中产生。尽管它们很少,而且最终会被发现并被修复,但总会有那么一段时间,这些 Bug 可能会损坏数据。

4
ch9.md
View File

@ -140,7 +140,7 @@
>
> ***线性一致性***
>
> **线性一致性Linearizability** 是读取和写入寄存器(单个对象)的 **新鲜度保证**。它不会将操作组合为事务,因此它也不会阻止写入偏差等问题(请参阅 “[写入偏差和幻读](ch7.md#写入偏与幻读)”),除非采取其他措施(例如 [物化冲突](ch7.md#物化冲突))。
> **线性一致性Linearizability** 是读取和写入寄存器(单个对象)的 **新鲜度保证**。它不会将操作组合为事务,因此它也不会阻止写入偏差等问题(请参阅 “[写入偏差和幻读](ch7.md#写入偏与幻读)”),除非采取其他措施(例如 [物化冲突](ch7.md#物化冲突))。
>
> 一个数据库可以提供可串行化和线性一致性,这种组合被称为严格的可串行化或 **强的单副本可串行化strong-1SR**【4,13】。基于两阶段锁定的可串行化实现请参阅 “[两阶段锁定](ch7.md#两阶段锁定)” 一节)或 **真的串行执行**(请参阅 “[真的串行执行](ch7.md#真的串行执行)”一节)通常是线性一致性的。
>
@ -318,7 +318,7 @@ CAP 定理的正式定义仅限于很狭隘的范围【30】它只考虑了
* [图 5-9](img/fig5-9.png) 中出现了类似的模式,我们看到三位领导者之间的复制,并注意到由于网络延迟,一些写入可能会 “压倒” 其他写入。从其中一个副本的角度来看,好像有一个对尚不存在的记录的更新操作。这里的因果意味着,一条记录必须先被创建,然后才能被更新。
* 在 “[检测并发写入](ch5.md#检测并发写入)” 中我们观察到,如果有两个操作 A 和 B则存在三种可能性A 发生在 B 之前,或 B 发生在 A 之前,或者 A 和 B**并发**。这种 **此前发生happened before** 关系是因果关系的另一种表述:如果 A 在 B 前发生,那么意味着 B 可能已经知道了 A或者建立在 A 的基础上,或者依赖于 A。如果 A 和 B 是 **并发** 的,那么它们之间并没有因果联系;换句话说,我们确信 A 和 B 不知道彼此。
* 在事务快照隔离的上下文中(“[快照隔离和可重复读](ch7.md#快照隔离和可重复读)”),我们说事务是从一致性快照中读取的。但此语境中 “一致” 到底又是什么意思?这意味着 **与因果关系保持一致consistent with causality**如果快照包含答案它也必须包含被回答的问题【48】。在某个时间点观察整个数据库与因果关系保持一致意味着因果上在该时间点之前发生的所有操作其影响都是可见的但因果上在该时间点之后发生的操作其影响对观察者不可见。**读偏差read skew** 意味着读取的数据处于违反因果关系的状态(不可重复读,如 [图 7-6](img/fig7-6.png) 所示)。
* 事务之间 **写偏差write skew** 的例子(请参阅 “[写入偏斜与幻读](ch7.md#写入偏斜与幻读)”)也说明了因果依赖:在 [图 7-8](img/fig7-8.png) 中,爱丽丝被允许离班,因为事务认为鲍勃仍在值班,反之亦然。在这种情况下,离班的动作因果依赖于对当前值班情况的观察。[可串行化快照隔离](ch7.md#可串行化快照隔离) 通过跟踪事务之间的因果依赖来检测写偏差。
* 事务之间 **写偏差write skew** 的例子(请参阅 “[写入偏差与幻读](ch7.md#写入偏差与幻读)”)也说明了因果依赖:在 [图 7-8](img/fig7-8.png) 中,爱丽丝被允许离班,因为事务认为鲍勃仍在值班,反之亦然。在这种情况下,离班的动作因果依赖于对当前值班情况的观察。[可串行化快照隔离](ch7.md#可串行化快照隔离) 通过跟踪事务之间的因果依赖来检测写偏差。
* 在爱丽丝和鲍勃看球的例子中([图 9-1](img/fig9-1.png)),在听到爱丽丝惊呼比赛结果后,鲍勃从服务器得到陈旧结果的事实违背了因果关系:爱丽丝的惊呼因果依赖于得分宣告,所以鲍勃应该也能在听到爱丽斯惊呼后查询到比分。相同的模式在 “[跨信道的时序依赖](#跨信道的时序依赖)” 一节中,以 “图像大小调整服务” 的伪装再次出现。
因果关系对事件施加了一种 **顺序**:因在果之前;消息发送在消息收取之前。而且就像现实生活中一样,一件事会导致另一件事:某个节点读取了一些数据然后写入一些结果,另一个节点读取其写入的内容,并依次写入一些其他内容,等等。这些因果依赖的操作链定义了系统中的因果顺序,即,什么在什么之前发生。

View File

@ -205,7 +205,7 @@
各分区负载不平衡,例如某些分区有大量请求或数据,而其他分区则少得多。也被称为热点。请参阅“[负载偏斜和热点消除](ch6.md#负载偏斜和热点消除)”和“[处理偏斜](ch10.md#处理偏斜)”。
时间线异常导致事件以不期望的顺序出现。 请参阅“[快照隔离和可重复读](ch7.md#快照隔离和可重复读)”中的关于读取偏斜的讨论,“[写入偏斜与幻读](ch7.md#写入偏斜与幻读)”中的写入偏斜以及“[有序事件的时间戳](ch8.md#有序事件的时间戳)”中的时钟偏斜。
时间线异常导致事件以不期望的顺序出现。 请参阅“[快照隔离和可重复读](ch7.md#快照隔离和可重复读)”中的关于读取偏差的讨论,“[写入偏差与幻读](ch7.md#写入偏差与幻读)”中的写入偏差以及“[有序事件的时间戳](ch8.md#有序事件的时间戳)”中的时钟偏斜。
* **脑裂split brain**