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,查询数据库中是否存在这条记录。 
如果不存在,说明事务提交失败。 
如果存在,说明事务提交成功。(因为数据库的事务是原子操作)

(0)

相关推荐

  • SQL Server数据迁移至PostgreSQL出错的解释以及解决方案

    问题重现: 1.PG客户端: postgres=# create table text_test (id int,info text); CREATE TABLE postgres=# insert into text_test values (1,E'\0x00'); ERROR: invalid byte sequence for encoding "UTF8": 0x00 2.SQL Server产生数据 create table test_varchar(id int,name

  • Windows下PostgreSQL安装图解

    现在谈起免费数据库,大多数人首先想到的可能是MySQL,的确MySQL目前已经应用在国内很多领域,尤其是网站架设方面.但是,实际上功能最强大.特性最丰富和最复杂的免费数据库应该是PostgreSQL.它的很多特性正是当今许多商业数据库例如Oracle.DB2等的前身. 其实笔者最近也是因为项目需要,接触了一点PostgreSQL的皮毛,最近PostgreSQL又刚发布了8.1版本,笔者结合网上各位高手的经验谈一点自己的安装心得,和才开始接触PostgreSQL的新手朋友共同学习. 从Postgr

  • 15个postgresql数据库实用命令分享

    最初是想找postgresql数据库占用空间命令发现的这篇blog,发现其中提供的几 条命令很有用(但也有几条感觉是充数的=.=),于是就把它翻译过来了.另外这篇文章是09年的,所以里面的内容可能有点过时,我收集了原文中有用的评论放在了最后面. 现在有不少开源软件都在使用postgreSQL作为它们的数据库系统.但公司可能不会招一些全职的postgreSQL DBA来维护它(piglei: 在国内基本也找不到).而会让一些比如说Oracle DBA.Linux系统管理员或者程序员去 维护.在这篇

  • Windows下Postgresql数据库的下载与配置方法

    注意下载的是二进制版,不是带Windows Installer的. http://www.enterprisedb.com/products-services-training/pgbindownload x86下载http://get.enterprisedb.com/postgresql/postgresql-9.2.4-1-windows-binaries.zip x64下载http://get.enterprisedb.com/postgresql/postgresql-9.2.4-1-

  • PostgreSQL 角色与用户管理介绍

    一.角色与用户的区别 角色就相当于岗位:角色可以是经理,助理.用户就是具体的人:比如陈XX经理,朱XX助理,王XX助理.在PostgreSQL 里没有区分用户和角色的概念,"CREATE USER" 为 "CREATE ROLE" 的别名,这两个命令几乎是完全相同的,唯一的区别是"CREATE USER" 命令创建的用户默认带有LOGIN属性,而"CREATE ROLE" 命令创建的用户默认不带LOGIN属性(CREATE U

  • 解决PostgreSQL服务启动后占用100% CPU卡死的问题

    进程中有N个postgres.exe(此为正常,见官方文档),却有一个始终占满CPU(由于本机是双核,占用了50%的资源).自带的pgAdmin III连接会死掉. 此问题在网上搜索没找到答案. 查看日志发现有这样一条错误信息: %t LOG:  could not receive data from client: An operation was attempted on something that is not a socket. 根据错误提示,在HP的官网找到了答案(应该是win的问题

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

    背景 数据库的事务是原子操作,要么成功,要么失败.但是实际上在客户端的视角,可能有第三种状态:unknown状态. 当客户端提交事务结束(rollback , commit , prepare xact , rollback pxact , commit pxact)的请求后,数据库收到请求,数据库可能执行失败,也可能执行成功,不管怎样都要写对于的WAL日志,还有CLOG,然后数据库要将执行结果返回给客户端ACK. 这里存在几种可能,导致客户端不知道执行到底怎么样了? 收到客户端请求后,数据库没

  • PostgreSQL数据库事务实现方法分析

    本文实例讲述了PostgreSQL数据库事务实现方法.分享给大家供大家参考,具体如下: 事务简介 事务管理器:有限状态机 日志管理器 CLOG:事务的执行结果 XLOG:undo/redo日志 锁管理器:实现并发控制,读阶段采用MVCC,写阶段采用锁控制实现不同的隔离级别 事务是所有数据库系统的一个基本概念. 一次事务的要点就是它把多个步骤捆绑成了一个单一的,不成功则成仁的操作. 其它并发的事务是看不到在这些步骤之间的中间状态的,并且如果发生了一些问题, 导致该事务无法完成,那么所有这些步骤都完

  • PostgreSQL数据库事务插入删除及更新操作示例

    目录 INSERT DELETE UPDATE 事务 INSERT 使用INSERT语句可以向表中插入数据. 创建一个表: CREATE TABLE ProductIns (product_id CHAR(4) NOT NULL, product_name VARCHAR(100) NOT NULL, product_type VARCHAR(32) NOT NULL, sale_price INTEGER DEFAULT 0, purchase_price INTEGER , regist_d

  • 解决postgresql 数据库 update更新慢的原因

    ;大约140000条数据) 竟然运行了一个小时还没有完成 下面是我的几点解决方案 我的update 语句 是从一个临时表更新值到另一个正式表 因为具体数据需要保密,我就不截图了 只说说大体思路,与方法 1.查看语句是否有问题 复制俩个一模一样的表 和数据 手动执行语句 发现不到一分钟就运行成功了 这样就可以确认语句没有问题 2.查找影响updata的因素 我的第一反应是不是有锁 有锁的情况会导致等待或者死锁 查询锁 select w1.pid as 等待进程, w1.mode as 等待锁模式,

  • PostgreSQL长事务与失效的索引查询浅析介绍

    最近刚写了一篇文章介绍了下长事务,以及一些长事务常见的危害,如无法及时的垃圾回收导致表膨胀之类的问题,最近刚好又碰到一个问题也是长事务所导致的. 上周六早上接到同事电话,说某个库CPU一直很高,看了下全是某张大表的全表扫描导致,但是奇怪的是相关的查询都有用到索引列,不知道为啥查询全部都没走索引. 当我连上去查看时发现确实如此,如果只是某个查询不走索引那可能是SQL本身写的有问题,但是这张表相关的所有SQL都不走索引,那自然会想到是索引本身的原因了.那是不是索引失效了呢?经过检查发现这张表上的索引

  • Python连接PostgreSQL数据库的方法

    前言 其实在Python中可以用来连接PostgreSQL的模块很多,这里比较推荐psycopg2.psycopg2安装起来非常的简单(pip install psycopg2),这里主要重点介绍下如何使用. 连接数据库: import psycopg2 conn = psycopg2.connect(host="10.100.157.168",user="postgres",password="postgres",database="

  • C# 操作PostgreSQL 数据库的示例代码

    什么是PostgreSQL? PostgreSQL是一个功能强大的开源对象关系数据库管理系统(ORDBMS). 用于安全地存储数据; 支持最佳做法,并允许在处理请求时检索它们. PostgreSQL(也称为Post-gress-Q-L)由PostgreSQL全球开发集团(全球志愿者团队)开发. 它不受任何公司或其他私人实体控制. 它是开源的,其源代码是免费提供的. PostgreSQL是跨平台的,可以在许多操作系统上运行,如Linux,FreeBSD,OS X,Solaris和Microsoft

  • 详解使用navicat连接远程linux mysql数据库出现10061未知故障

    使用使用navicat连接远程linux mysql数据库出现10061未知故障,设置使用ssh连接后出现2013故障 本机环境:win10 navicat premium mysql数据库主机环境:Linux version 4.15.0-42-generic (buildd@lgw01-amd64-023) (gcc version 7.3.0 (Ubuntu 7.3.0-16ubuntu3)) #45-Ubuntu SMP Thu Nov 15 19:32:57 UTC 2018 mysq

  • MySQL数据库事务与锁深入分析

    一.基本概念 事务是指满足ACID特性的的一组操作,可以通过Commit提交事务,也可以也可以通过Rollback进行回滚.会存在中间态和一致性状态(也是真正在数据库表中存在的状态) 二.ACID Atomicity[原子性]:事务被视为不可分割的最小单元,事务的所有操作要么全部提交成功,要么全部失败回滚.回滚可以用回滚日志(undo Log)来实现,回滚日志记录着事务所执行的修改操作,在回滚时反向执行这些修改操作即可 undoLog:为了满足事务的原子性,在操作任何数据之前,首先将数据备份到U

随机推荐