PostgreSQL数据库事务出现未知状态的处理方法

所属分类: 数据库 / PostgreSQL 阅读数: 227
收藏 0 赞 0 分享

背景

数据库的事务是原子操作,要么成功,要么失败。但是实际上在客户端的视角,可能有第三种状态:unknown状态。

当客户端提交事务结束(rollback , commit , prepare xact , rollback pxact , commit pxact)的请求后,数据库收到请求,数据库可能执行失败,也可能执行成功,不管怎样都要写对于的WAL日志,还有CLOG,然后数据库要将执行结果返回给客户端ACK。

这里存在几种可能,导致客户端不知道执行到底怎么样了?

收到客户端请求后,数据库没有返回任何ACK给客户端,客户端对这次请求很茫然,它只能人为数据库处于UNKNOWN的状态。

UNKNOWN 事务的处理

unknown事务,就是客户端没有收到commit/rollback ACK的事务。不知道是成功还是失败。

多节点(quorum based sync replication)与单节点都可能出现UNKNOWN事务,效果、形态一致。

如何处理unknown事务呢?

unknown事务分为以下几种情况.

rollback , commit , prepare xact , rollback pxact , commit pxact 几种情况的unknown处理方法:

1、两阶段解决unknown状态问题

prepare 阶段unknown, 切换leader后,客户端通过pg_prepared_xacts视图检查prepare xact状态,如果没有prepare xact则说明失败了,那么整个事务重新发起即可。如果prepare xact存在,说明prepare xact成功了。

commit or rollback prepare xact阶段unknown, 切换后检查prepare xact状态,存在则重试commit or rollback prepare xact。不存在则说明已经成功(我们认为2PC是一定成功的),无须处理。

2、非两阶段事务,rollback unknown无须处理,rollback失败或成功对于客户端来说结果是一样的。因为不管怎样都会回滚掉,这是数据库原子性保障的。

3、非两阶段事务,commit unknown处理,极度严谨的场景,程序可以设计事务状态可回溯,例如:

事务开始时,记录事务号或唯一流水号,事务号在数据库中是一个唯一的流水,可以根据事务号查询它的状态,比如postgresql。

但是并不是所有数据库都有这种接口,比如非物理流式复制的数据库,则可以在事务中增加全局唯一流水号来查看事务是否提交。这里利用了事务的原子特性,既要么全成功要么全失败。可以举个使用例子。

使用业务流水实现事务状态判断的例子:

begin; 
生成唯一业务流水ID, 写入到某个流水表,同时在程序或其他数据库中记录这个流水号,备查。 
执行事务 
提交事务; 
 
-- 出现unknown 
 
通过唯一业务流水ID,查询数据库中是否存在这条记录。 
如果不存在,说明事务提交失败。 
如果存在,说明事务提交成功。(因为数据库的事务是原子操作) 

更多精彩内容其他人还在看

PostgreSQL教程(三):表的继承和分区表详解

这篇文章主要介绍了PostgreSQL教程(三):表的继承和分区表详解,本文讲解了多表继承、 继承和权限、什么是分区表、分区表实现、分区和约束排除等内容,需要的朋友可以参考下
收藏 0 赞 0 分享

PostgreSQL教程(四):数据类型详解

这篇文章主要介绍了PostgreSQL教程(四):数据类型详解,本文讲解了数值类型、字符类型、布尔类型、位串类型、数组、复合类型等数据类型,需要的朋友可以参考下
收藏 0 赞 0 分享

PostgreSQL教程(五):函数和操作符详解(1)

这篇文章主要介绍了PostgreSQL教程(五):函数和操作符详解(1),本文讲解了逻辑操作符、比较操作符、数学函数和操作符、三角函数列表、字符串函数和操作符等内容,需要的朋友可以参考下
收藏 0 赞 0 分享

PostgreSQL教程(六):函数和操作符详解(2)

这篇文章主要介绍了PostgreSQL教程(六):函数和操作符详解(2),本文讲解了模式匹配、数据类型格式化函数、时间/日期函数和操作符等内容,需要的朋友可以参考下
收藏 0 赞 0 分享

PostgreSQL教程(七):函数和操作符详解(3)

这篇文章主要介绍了PostgreSQL教程(七):函数和操作符详解(3),本文讲解了序列操作函数、条件表达式、数组函数和操作符、系统信息函数、系统管理函数等内容,需要的朋友可以参考下
收藏 0 赞 0 分享

PostgreSQL教程(八):索引详解

这篇文章主要介绍了PostgreSQL教程(八):索引详解,本文讲解了索引的类型、复合索引、组合多个索引、唯一索引、表达式索引、部分索引等内容,需要的朋友可以参考下
收藏 0 赞 0 分享

PostgreSQL教程(九):事物隔离介绍

这篇文章主要介绍了PostgreSQL教程(九):事物隔离介绍,本文主要针对读已提交和可串行化事物隔离级别进行说明和比较,需要的朋友可以参考下
收藏 0 赞 0 分享

PostgreSQL教程(十):性能提升技巧

这篇文章主要介绍了PostgreSQL教程(十):性能提升技巧,本文讲解了使用EXPLAIN、批量数据插入、关闭自动提交、使用COPY、 删除索引、删除外键约束等技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

PostgreSQL教程(十一):服务器配置

这篇文章主要介绍了PostgreSQL教程(十一):服务器配置,本文讲解了服务器进程的启动和关闭、服务器配置、内存相关的参数配置等内容,需要的朋友可以参考下
收藏 0 赞 0 分享

PostgreSQL教程(十二):角色和权限管理介绍

这篇文章主要介绍了PostgreSQL教程(十二):角色和权限管理介绍,本文讲解了数据库角色、角色属性、权限、角色成员,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多