| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> Postgresql事务和Greenplum中的两阶段提交 -> 正文阅读 |
|
[大数据]Postgresql事务和Greenplum中的两阶段提交 |
PostgreSQL是当今最广泛应用的数据库系统(DBMS)之一。除了由于其具有优秀的性能、良好的兼容性之外,其完全开源的特性、完整的事务能力也是其中重要的原因。PostgreSQL支持完整的ACID特性,支持RC/RR/SSI等隔离级别。 Greenplum是一种广泛使用的,基于PG进行开发的MPP架构的分布式数据库。GP不仅高度兼容PG生态,还保持了PG包含支持完整事务的优点。GP本地事务的实现与PG基本一致,但为了保证多节点之间的事务状态一致性,GP引入两阶段提交协议来实现分布式事务。 本文主要简化的介绍PG的事务模型和Greenplum基于两阶段提交的分布式事务。具体地,本文会首先介绍单机事务、ACID特性,以及PG中的事务实现;然后介绍一种分布式事务协议——两阶段提交协议,分析其实现、优点和局限性,并简单介绍以3PC为代表的两阶段提交协议优化。 事务ACIDnothing or all atomic befor or after atomic看不到其他事务未提交的信息。 PG中的事务实现事务总体实现PG是进程模型,当postmaster接收到外部连接后,会fork出一个postgres进程,以处理外部请求。 每个Postgres进程会创建一个事务块(TransactionBlock)以处理这个进程中的所有事务。一个事务块处理多个事务。PG基于状态机去管理事务块和事物的状态,而状态转换往往是由外部命令(BEGIN/END/ROLLBACK/COMMIT/ABORT/DDL/DML)所触发的。 事务块状态转换事务块的基本操作函数包括StartTransactionCommand、CommitTransactionCommand和AbortCurrentTranscation。这些函数可能会在我们手动执行BEGIN、END、ROLLBACK命令时候显式调用,或者我们执行某些增删改查、使用某些UDF,或者使用某些数据库功能(分层存储、数据共享)的时候会自动调用。 当数据库开发者认为某些操作需要在一个事务中进行,就可能会添加一条StartTransactionCommand/CommitTransactionCommand指令让事务块进入开启/提交事务的状态。这些事务块进行状态转移的时候也会对应调用事务处理函数(StartTransaction、CommitTransaction等)对具体事务进行实际的处理。 事务状态转换:上述事务块操作主要是修改全局的状态量,并不会做日志持久化、文件IO等具体工作,这些具体工作是由事务操作函数StartTransaction、CommitTransaction、AbortTransaction等实际操作的。 事务也包含多种状态: TRANS_DEFAULT, /* idle */ 我们以事务提交(CommitTransaction)为例,介绍PG在一次事务提交的时候做了些什么: 1)检查当前事务状态,确保处于TRAN_INPROGRESS阶段; 2)触发所有延迟的触发器(AfterTriggerFireDeferred+AfterTriggerEndXact); 3)关闭所有大对象并释放内存(AtEOXact_LargeObject); 4)将事务状态修改为TRANS_COMMIT状态; 5)执行RecordTransactionCommit,记录xid、pendingdeletes信息、subtransaction到xlog、clog(记录事务状态日志)等; 6)释放资源,清理状态; 7)将事务状态改为TRANS_DEFAULT。 当我们在执行一次BEGIN/SELECT/INSERT/END的时候会做哪些事务相关的事情这里我们以一个最简单的场景: 1) BEGIN 为例,介绍过程中进程会对事务和事务块进行哪些处理: 事务块默认状态为TRANS_DEFAULT / StartTransactionCommand; 修改事务块状态为TBLOCK_STARTED; 分布式事务在分布式场景下,每个数据存储节点都需要进行资源的获取与释放、日志的持久化,一阶段提交很难保证整个分布式系统的一致性,很多分布式事务协议被提出以解决分布式场景下的事务问题。两阶段提交(Two Phase Commit)协议被提出以解决分布式系统的强一致性事务问题。 Two Phase Commit2PC是一个非常经典的强一致、中心化(协调节点、参与节点)的原子提交协议。它将事务的提交过程分成两个阶段:Prepare阶段和Commit阶段。下文中我们将实际执行具体操作的节点称为参与者,将协调事务进行的中心节点称为协调者。 Prepare阶段第一阶段主要分为3步 1)事务询问 协调者 向所有的 参与者 发送事务预处理请求,称之为Prepare,并开始等待各 参与者 的响应。 2)执行本地事务 各个 参与者 节点执行本地事务操作以及记录日志,但在执行完成后并不会真正提交更改并释放资源,而是先向协调者报告prepare完成情况,是否ready for commit。. 3)协调者接收响应,并决定是否继续完成提交。 第一阶段任一参与者没有正确回复将导致事务abort,协调者需要记录日志。 Commit阶段第二阶段主要分为三步: 1)协调者发出COMMIT请求 协调者 向 所有参与者 节点发出Commit请求. 2)事务提交 参与者 收到Commit请求之后,就会正式执行本地事务Commit操作并记录日志,在完成提交之后释放整个事务执行期间占用的事务资源。 3)协调者接收到所有节点的回复之后,记录日志并释放资源。 故障恢复(1)参与者故障 由于 协调者 无法收集到所有 参与者 的反馈,会陷入阻塞情况。协调者等参与者恢复后,根据处于的阶段决定进行abort或者retry commit; (2)协调者故障 无论处于哪个阶段,由于协调者宕机,无法发送提交请求,所有处于执行了操作但是未提交状态的参与者都会陷入阻塞情况。通常的解决方法是引入高可用机制(high availability),引入流复制、Raft或者Paxos以在单个协调者发生故障时快速转移和接管。 3)网络错误: coordinator和participant之间出现networking partitioning, 互不可达. 普遍解决方法是: 重试+幂等+超时。 GP中的2PC基础实现分布式事务提交GP采用状态机方式管理分布式事务: 这里以提交为例,阐述分布式事务的处理过程: Prepare阶段: 1、QD发起分布式事务,并并行dispatach DTX_PROTOCOL_COMMAND_PREPARE指令,并等待结果; 2、QE接收到指令,写入PREPARE类型xlog; 3、QE发送回复给QD; 4、QD接收到QE发来的prepare回复,本地写入一条DISTRIBUTED_COMMIT类型xlog;PREPARE阶段完成。 COMMIT阶段: 1、QD向所有QE并行dispatch DispatchDTX_PROTOCOL_COMMAND_COMMIT_PREPARED指令,并等待结果; 2、QE接收到指令,写入COMMIT_PREPARED类型xlog; 3、QE向QD回复,QE释放资源; 4、QD接收到QE发来的COMMIT回复。本地写入一条DISTRIBUTED_FORGET类型xlog; 5、QD释放资源,事务完成。 分布式事务恢复segment故障 如果Segment发生不可恢复的故障怎么处理? FTS 探测Segment,发现故障之后mirror--> 升级为primary Master继续Commit/Abort 事务 如何保证mirror升级为primary后,事务可以继续Commit/Abort? Prepare日志必须刷写到磁盘 Prepare日志,必须同步到mirror才完成prepare Master故障 2PC的局限性1、同步阻塞问题。 2、交互延迟:协调者要持久化事务的commit/abort状态后才能发送commit/abort命令,因此全程至少2次RPC延迟(prepare+commit),和3次持久化数据延迟(prepare写日志+协调者状态持久化+commit写日志)。 2PC本身是一个非常优秀的强一致性协议,Greenplum、Spanner等很多数据库都实现了2PC。针对以上一致性,其实很多研究者也提出了一些面向特定场景的改进协议,以提升2PC的性能。下面主要介绍一下3PC。 3PC三阶段提交(Three-phase commit),是二阶段提交(2PC)的改进版本。 与两阶段提交不同的是,三阶段提交有两个改动点。 1、引入超时机制。同时在协调者和参与者中都引入超时机制。 CanCommit阶段3PC的CanCommit阶段其实和2PC的Prepare阶段很像。协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应。 1.事务询问 协调者向参与者发送CanCommit请求。询问是否可以执行事务提交操作。然后开始等待参与者的响应。 这个阶段并不会加锁。 PreCommit阶段本阶段协调者会根据第一阶段的询盘结果采取相应操作: 情况1-假如协调者从所有的参与者获得的反馈都是Yes响应,那么就会执行事务的预执行: 1.发送预提交请求 协调者向参与者发送PreCommit请求。
1.发送中断请求 协调者向所有参与者发送abort请求。 doCommit阶段该阶段进行真正的事务提交,也可以分为以下两种情况。 情况1-执行提交 针对第一种情况,协调者向各个参与者发起事务提交请求,具体步骤如下: 1. 协调者向所有参与者发送事务commit通知 情况2-中断事务 协调者没有接收到参与者发送的ACK响应(可能是接受者发送的不是ACK响应,也可能响应超时),那么就会执行中断事务。具体步骤如下: 1. 发送中断请求 协调者向所有参与者发送事务rollback通知。 这一阶段中因为网络原因协调者与参与者断开通信, 参与者也会自动提交commit,这样防止了一直锁表的风险 相对于2PC,3PC主要解决的单点故障问题,并减少阻塞,因为一旦参与者无法及时收到来自协调者的信息之后,他会默认执行commit。而不会一直持有事务资源并处于阻塞状态。 在doCommit阶段,如果参与者无法及时接收到来自协调者的doCommit或者rebort请求时,会在等待超时之后,会继续进行事务的提交。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年3日历 | -2025/3/4 7:45:21- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |