分布式事务内幕(1)

简介: 分布式事务内幕(1)

本文节选自《数据库系统内幕》第13章——分布式事务

为了在分布式系统中维持秩序,我们至少要保证一定程度的一致性。在11.5节中,我们讨论了单个对象、单个操作的一致性模型,这些模型帮助我们论证单个操作的正确性。但是,在数据库中我们经常需要原子地执行多个操作。


原子操作可以用状态转移来解释:在启动某个事务之前,数据库处于状态A;当事务完成的时候,状态从A变成B。从操作的角度看这很容易理解,因为事务没有附带一个事先确定好的状态。相反,事务从某个时间点开始将操作应用于数据记录。这使我们在调度和执行方面具有一定的灵活性:事务可以被重新排序甚至重试。


事务处理主要关注的是决定一个合法的执行历史,以建模和表示可能的交错执行方案。在这种情况下,历史代表一个依赖关系图:哪些事务在当前事务之前执行。如果一个执行历史与事务的某一串行历史等效(即具有相同的依赖关系图),则称它为可串行化的。你可以回顾5.3.1节执行历史的概念、历史的等效性、可串行化以及其他概念。总的来看,本章是第5章在分布式系统中的对应,第5章中我们讨论了节点本地的事务处理。

单分区事务可以使用我们在第5章中讨论过的悲观(基于锁或跟踪)或乐观(尝试并验证)并发控制方案,但是这些方法无法解决多分区事务的问题,因为多分区事务需要实现不同服务器之间的协调、分布式提交和回滚协议。


一般来说,从一个账户向另一个账户转账时,你希望同时完成扣减第一个账户余额和增加第二个账户余额这两个操作。但是,如果我们将事务分解为若干独立步骤,即便是扣减或增加余额操作乍一看也不是原子的:我们需要读取旧的余额,加上或减去所需的金额,然后保存该结果。这些子步骤中的每一步又涉及多个操作:节点收到请求、解析请求、在磁盘上找到数据、进行写操作、最终确认请求。即便如此也仍是一个相当高层的视角:哪怕执行一个简单的写入,我们也要做上百个小步骤。


这就意味着我们必须先执行事务,然后再让结果可见。在此之前,我们需要先定义什么是事务。事务是一组操作,一个原子的执行单元。事务的原子性意味着:要么它的全部结果都变得可见,要么全都不可见。例如,如果我们在一个事务内修改了几行甚至几张表,要么所有修改都被应用了,要么全都不被应用。


为了保证原子性,事务必须是可恢复的。换句话说,如果事务无法完成、被中止或超时,则其结果必须完全回滚。一个不可恢复的、部分执行的事务会让数据库处于不一致状态。总而言之,在事务执行失败的情况下,必须将数据库恢复到之前的状态,就像从未做过该事务一样。


另一个重要的方面是网络分区和节点故障:系统中的节点独立地发生故障并恢复,但是它们的状态必须保持一致。这意味着原子性要求不仅适用于本地操作,还适用于在其他节点上执行的操作:事务的修改必须要么持久化地传播到事务涉及的所有节点,要么一个都不传播[LAMPSON79]。


1 多个操作的原子性


为了让多个操作看起来是原子的,尤其是当其中一些是远程操作时,我们需要使用一类称为原子提交(atomic commitment)的算法。原子提交不允许参与者之间出现分歧:只要有一个参与者投票反对,事务就不能提交。同时,这意味着发生故障的进程也必须与其他参与者达成共识。它的另一个重要含义是,如果存在拜占庭故障,原子提交算法无法正常工作:这时进程可能会撒谎或是决定一个任意值,而这会破坏全体的共识[HADZILACOS05]。


原子提交试图解决的问题就是要对以下问题达成共识:是否要执行当前被提议的事务?事务参与者不能选择、影响或修改被提议的事务,更不能提出另一个事务,它们只能对自己是否愿意执行此事务进行投票[ROBINSON08]。


原子提交算法没有对准备(prepare)、提交(commit)和回滚(rollback)这些操作做出严格的语义限制,数据库开发者需要决定:


何时可以认为数据已准备好提交,这时只要交换一

个指针便可以让修改对外可见。

如何执行提交本身,以让事务结果在最短的时间内变得

可见。

如果算法决定不提交,如何回滚事务所做的更改。


第5章中,我们讨论了节点本地上的事务实现。


许多分布式系统使用原子提交算法,例如MySQL(用于分布式事务)和Kafka(用于生产者和消费者的交互[MEHTA17])。


在数据库中,分布式事务是由一个通常叫作事务管理器的组件执行的。事务管理器是负责调度、协调、执行和跟踪事务的子系统。在分布式环境中,事务管理器负责确保节点本地的可见性保证与分布式原子操作规定的可见性相符合。换句话说,事务提交发生在所有分区以及所有副本之中。


我们将讨论两种原子提交算法:两阶段提交(它解决了提交的问题,但不允许协调者发生故障)和三阶段提交[SKEEN83](它解决了非阻塞原子提交问题注1,即使协调者发生故障时,参与者也可以继续提交)[BABAOGLU93]。


2 两阶段提交


让我们从最简单的分布式提交协议开始,该协议能够保证多分区原子更新(关于分区的更多信息请参考13.6节)。两阶段提交(2PC)是数据库事务中的一个重要概念。2PC分为两个阶段:第一阶段中分发决定的值并收集投票;第二阶段,节点仅仅翻转开关,让第一阶段的结果变得可见。


2PC假定存在一个领导者(leader)或协调者(coordinator)负责保存状态、收集投票,并作为协商的主要参考依据。其余节点称为参与者(cohort)。通常情况下,每个参与者负责一个分区(即互不相交的数据集合),在这些数据上执行事务。协调者和每个参与者都会为所有执行过的步骤保留本地操作日志。参与者投票接受或拒绝协调者提议的某个值。通常来说,这个值就是要执行的分布式事务的标识符,但是2PC也可以用在其他场景下。


协调者可以是接收事务请求的节点,可以是用选主算法随机选出来的,可以是手动分配的,甚至可以是在系统的整个生命周期内都保持固定的。协议本身对协调者角色没有任何限制。出于可靠性或性能的原因,可以将该角色转移给其他参与者。


顾名思义,两阶段提交的执行分为两个步骤:


准备(prepare)阶段


       协调者通过发送Propose消息告诉参与者关于新事务的提议。参与者要决定它们是否可以提交自己那部分事务。如果参与者决定可以提交,就向协调者投赞成票。否则,它会要求协调者中止事务。所有参与者的决定都保留在协调者的日志中,并且每个参与者也会在本地保留一份它的决定。


提交(commit)/中止(abort)阶段


       事务中的操作可以修改多个分区上的状态(每个参与者代表一个分区)。但凡有一个参与者投票中止事务,则协调者也会向所有的参与者发送Abort消息。仅当所有参与者都投赞成票时,协调者才会向他们发送最终的Commit消息。


上述过程如图13-1所示。


准备阶段中,协调者分发提议的值,并收集各个参与者的投票:这个提议的值是否应该被提交。参与者可以选择拒绝协调者的提案,例如,当另一个冲突的事务已经提交了一个不同值的时候。


image.png


协调者收集投票之后,可以决定要提交事务还是中止事务。如果所有参与者均投了赞成票,它会决定提交并发送Commit消息通知它们。否则,协调者会向各个参与者发送Abort消息,事务将被回滚。换句话说,如果任意一个节点拒绝该提案,则整个流程将会中止。


每个步骤中,协调者和参与者都必须将各个操作的结果写入持久性存储中,以便能够在发生本地故障的情况下重建状态并恢复,并且可以将结果转发给其他参与者使其能够重放操作。


在数据库的语境下,每次2PC通常负责一个事务。在准备阶段,事务内容(操作、标识符和其他元数据)从协调者发送给参与者。参与者在本地执行事务,并停留在部分提交状态(也称为预提交状态),以让协调者在下一阶段通过提交或中止来完成执行。事务提交时,其内容已持久地存储到所有其他节点上[BERNSTEIN09]。

相关文章
|
19天前
|
人工智能 自然语言处理 Shell
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
本教程指导用户在开源AI助手Clawdbot中集成阿里云百炼API,涵盖安装Clawdbot、获取百炼API Key、配置环境变量与模型参数、验证调用等完整流程,支持Qwen3-max thinking (Qwen3-Max-2026-01-23)/Qwen - Plus等主流模型,助力本地化智能自动化。
32198 117
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
|
9天前
|
应用服务中间件 API 网络安全
3分钟汉化OpenClaw,使用Docker快速部署启动OpenClaw(Clawdbot)教程
2026年全新推出的OpenClaw汉化版,是基于Claude API开发的智能对话系统本土化优化版本,解决了原版英文界面的使用壁垒,实现了界面、文档、指令的全中文适配。该版本采用Docker容器化部署方案,开箱即用,支持Linux、macOS、Windows全平台运行,适配个人、企业、生产等多种使用场景,同时具备灵活的配置选项和强大的扩展能力。本文将从项目简介、部署前准备、快速部署、详细配置、问题排查、监控维护等方面,提供完整的部署与使用指南,文中包含实操代码命令,确保不同技术水平的用户都能快速落地使用。
4721 4
|
15天前
|
人工智能 安全 机器人
OpenClaw(原 Clawdbot)钉钉对接保姆级教程 手把手教你打造自己的 AI 助手
OpenClaw(原Clawdbot)是一款开源本地AI助手,支持钉钉、飞书等多平台接入。本教程手把手指导Linux下部署与钉钉机器人对接,涵盖环境配置、模型选择(如Qwen)、权限设置及调试,助你快速打造私有、安全、高权限的专属AI助理。(239字)
6821 18
OpenClaw(原 Clawdbot)钉钉对接保姆级教程 手把手教你打造自己的 AI 助手
|
14天前
|
人工智能 机器人 Linux
OpenClaw(Clawdbot、Moltbot)汉化版部署教程指南(零门槛)
OpenClaw作为2026年GitHub上增长最快的开源项目之一,一周内Stars从7800飙升至12万+,其核心优势在于打破传统聊天机器人的局限,能真正执行读写文件、运行脚本、浏览器自动化等实操任务。但原版全英文界面对中文用户存在上手门槛,汉化版通过覆盖命令行(CLI)与网页控制台(Dashboard)核心模块,解决了语言障碍,同时保持与官方版本的实时同步,确保新功能最快1小时内可用。本文将详细拆解汉化版OpenClaw的搭建流程,涵盖本地安装、Docker部署、服务器远程访问等场景,同时提供环境适配、问题排查与国内应用集成方案,助力中文用户高效搭建专属AI助手。
4780 11
|
16天前
|
人工智能 机器人 Linux
保姆级 OpenClaw (原 Clawdbot)飞书对接教程 手把手教你搭建 AI 助手
OpenClaw(原Clawdbot)是一款开源本地AI智能体,支持飞书等多平台对接。本教程手把手教你Linux下部署,实现数据私有、系统控制、网页浏览与代码编写,全程保姆级操作,240字内搞定专属AI助手搭建!
5679 21
保姆级 OpenClaw (原 Clawdbot)飞书对接教程 手把手教你搭建 AI 助手
|
12天前
|
人工智能 JavaScript 安全
Claude Code 安装指南
Claude Code 是 Anthropic 推出的本地 AI 编程助手,支持 Mac/Linux/WSL/Windows 多平台一键安装(Shell/PowerShell/Homebrew/NPM),提供 CLI 交互、代码生成、审查、Git 提交等能力,并内置丰富斜杠命令与自动更新机制。
4273 0
|
16天前
|
存储 人工智能 机器人
OpenClaw是什么?阿里云OpenClaw(原Clawdbot/Moltbot)一键部署官方教程参考
OpenClaw是什么?OpenClaw(原Clawdbot/Moltbot)是一款实用的个人AI助理,能够24小时响应指令并执行任务,如处理文件、查询信息、自动化协同等。阿里云推出的OpenClaw一键部署方案,简化了复杂配置流程,用户无需专业技术储备,即可快速在轻量应用服务器上启用该服务,打造专属AI助理。本文将详细拆解部署全流程、进阶功能配置及常见问题解决方案,确保不改变原意且无营销表述。
6239 6
|
18天前
|
人工智能 JavaScript 应用服务中间件
零门槛部署本地AI助手:Windows系统Moltbot(Clawdbot)保姆级教程
Moltbot(原Clawdbot)是一款功能全面的智能体AI助手,不仅能通过聊天互动响应需求,还具备“动手”和“跑腿”能力——“手”可读写本地文件、执行代码、操控命令行,“脚”能联网搜索、访问网页并分析内容,“大脑”则可接入Qwen、OpenAI等云端API,或利用本地GPU运行模型。本教程专为Windows系统用户打造,从环境搭建到问题排查,详细拆解全流程,即使无技术基础也能顺利部署本地AI助理。
7766 17