PostgreSQL长事务概念解析(post的过去分词)学会了吗

随心笔谈2年前发布 编辑
161 0
🌐 经济型:买域名、轻量云服务器、用途:游戏 网站等 《腾讯云》特点:特价机便宜 适合初学者用 点我优惠购买
🚀 拓展型:买域名、轻量云服务器、用途:游戏 网站等 《阿里云》特点:中档服务器便宜 域名备案事多 点我优惠购买
🛡️ 稳定型:买域名、轻量云服务器、用途:游戏 网站等 《西部数码》 特点:比上两家略贵但是稳定性超好事也少 点我优惠购买



我们在很多地方应该都听到过长事务的危害,比方说长事务会导致表膨胀之类的。那么在PostgreSQL中什么才算是长事务呢?

首先,在PostgreSQL的官方文档中并没有所谓“长事务”这一定义,似乎大家约定俗称的把一个执行了很长却没有提交的事务认为是“长事务”了,而在不同的数据库中关于长事务的定义往往也不尽相同,那么在PostgreSQL中什么是长事务呢?

打个比方,如下所示,我在一个会话中通过begin开启一个事务,然后执行了个简单的查询语句后迟迟不提交,这算不算长事务呢?

bill=# begin;

BEGIN

bill=*# select 1;

 ?column?

———-

        1

(1 row)

bill=*#

为了搞清楚这个问题,我们不妨想想,为什么我们会提到长事务呢。这是因为pg中的长事务会影响表中垃圾回收,会导致表的年龄增长无法freeze。而我们上面这个会话开启的事务会有影响吗?实际上并不会,我们可以通过pg_stat_activity视图观察:

bill=# select * from pg_stat_activity where pid=26192;

-[ RECORD 1 ]—-+——————————

datid            | 16385

datname          | bill

pid              | 26192

leader_pid       |

usesysid         | 16384

usename          | bill

application_name | psql

client_addr      |

client_hostname  |

client_port      | -1

backend_start    | 2022-03-02 11:49:49.433165+08

xact_start       | 2022-03-02 14:34:04.494416+08

query_start      | 2022-03-02 14:34:06.946754+08

state_change     | 2022-03-02 14:34:06.947207+08

wait_event_type  | Client

wait_event       | ClientRead

state            | idle in transaction

backend_xid      |

backend_xmin     |

query            | select 1;

backend_type     | client backend

之所以会导致表膨胀之类的问题,主要是在于backend_xid和backend_xmin两个字段,而上面的事务这两个字段均是空的。

typedef struct LocalPgBackendStatus
{

PgBackendStatus backendStatus;

TransactionId backend_xid;

TransactionId backend_xmin;
} LocalPgBackendStatus;

backend_xid表示已申请事务号的事务,例如有增删改,DLL等操作的事务。backend_xid从申请事务号开始持续到事务结束。

backend_xmin表示SQL执行时的snapshot,即可见的最大已提交事务。

而表膨胀的原因是什么呢?当数据库中存在未结束的SQL语句或者未结束的持有事务ID的事务,在此事务过程中,或在此SQL执行时间范围内产生垃圾的话,这些垃圾无法回收,导致数据库膨胀。

也就是判断当前数据库中backend_xid和backend_xmin最小的值,凡是超过这个最小值的事务产生的垃圾都不能回收。

因此,我们如果想要监控长事务该怎么写呢?以超过1小时的长事务为例:

select count(*) from pg_stat_activity where state <> ‘idle’
and (backend_xid is not null or backend_xmin is not null)
and now()-xact_start > interval ‘3600 sec’::interval;

所以,对于事务而言,只有当执行了一些DML或者DDL操作后才能算是我们通常说的长事务。否则只能算是我们常说的长连接,当然长连接也有很多弊端,例如占用内存、cpu等资源。

在实际应用中,我们应当做好对长事务的监控,并尽可能的避免其发生。例如一些批量的操作可能会比较容易导致长事务,我们可以尽量将其安排在业务低峰期执行,同时,如果我们的应用中关闭了自动提交,也要在执行完之后加上提交。

到此这篇关于PostgreSQL长事务概念解析的文章就介绍到这了,更多相关PostgreSQL长事务内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:PostgreSQL游标与索引选择实例详细介绍PostgreSQL长事务与失效的索引查询浅析介绍

© 版权声明

相关文章