PostgreSQL数据库事务出现未知状态的处理方法
背景
数据库的事务是原子操作,要么成功,要么失败。但是实际上在客户端的视角,可能有第三种状态: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,查询数据库中是否存在这条记录。
如果不存在,说明事务提交失败。
如果存在,说明事务提交成功。(因为数据库的事务是原子操作)
我想要获取技术服务或软件
服务范围:MySQL、ORACLE、SQLSERVER、MongoDB、PostgreSQL 、程序问题
服务方式:远程服务、电话支持、现场服务,沟通指定方式服务
技术标签:数据恢复、安装配置、数据迁移、集群容灾、异常处理、其它问题
本站部分文章参考或来源于网络,如有侵权请联系站长。
数据库远程运维 PostgreSQL数据库事务出现未知状态的处理方法
相关文章
- postgresql 数据库中的 序列nextval 使用方法详解
- 查看postgresql数据库用户系统权限、对象权限的方法
- mysql left join 右表数据不唯一的情况解决方法详解数据库
- PostgreSQL连接python,postgresql在python 连接,创建表,创建表内容,插入操作,选择操作,更新操作,删除操作。详解数据库
- 『PostgreSQL:强大而友好的数据库』(postgresql特点)
- 深入了解Oracle数据库的基本使用方法(如何查看Oracle库)
- 库解决MySQL数据库完全清空的方法(清空mysql数据)
- PostgreSQL登录:体验自由融洽的数据库访问(postgresql登陆)
- 中跳出跳出PostgreSQL循环的实践方法(postgresql循环)
- Postgresql数据库备份实践:简单而又必要(postgresql数据库备份)
- 玩转PostgreSQL数据库:学习如何处理除法(postgresql除法)
- Linux服务器主从mysql数据库配置方法
- 探索PostgreSQL客户端工具,优化数据库管理(postgresql客户端工具)
- PostgreSQL接口:轻松连接数据库(postgresql接口)
- Oracle数据库查询当天日期的方法(oracle查询当天)
- PostgreSQL中文手册详解数据库操作技巧(postgresql中文手册)
- 深入了解PostgreSQL数据类型:解决您的数据库存储难题(postgresql数据类型)
- PostgreSQL:轻松入门的开源数据库(postgresql介绍)
- PHP连接MSSQL数据库的方法和步骤(php如何连接mssql)
- 学习PostgreSQL数据库必备!观看高质量视频教程(postgresql视频)
- Postgresql游标的使用方法和注意事项(postgresql游标)
- Oracle数据库中修改字段名称的简单方法(oracle修改字段名称)
- 深入了解 PostgreSQL 数据库结构(postgresql结构)
- 类型Oracle数据库中的日期数据类型细节(oracle中日期数据)
- Oracle数据库中添加主外键的方法(oracle中加主外键)
- PHP远程连接MYSQL数据库非常慢的解决方法
- c#asp.net动态创建sql数据库表的方法
- C#Access数据库增删查改的简单方法
- SQLSEVER数据库重建索引的方法
- PostgreSQL数据库服务端监听设置及客户端连接方法教程