IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> PostgreSQL什么才算是长事务 -> 正文阅读

[大数据]PostgreSQL什么才算是长事务

我们在很多地方应该都听到过长事务的危害,比方说长事务会导致表膨胀之类的。那么在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两个字段,而上面的事务这两个字段均是空的。

/* ----------
 * LocalPgBackendStatus
 *
 * When we build the backend status array, we use LocalPgBackendStatus to be
 * able to add new values to the struct when needed without adding new fields
 * to the shared memory. It contains the backend status as a first member.
 * ----------
 */
typedef struct LocalPgBackendStatus
{
  /*
   * Local version of the backend status entry.
   */
  PgBackendStatus backendStatus;

  /*
   * The xid of the current transaction if available, InvalidTransactionId
   * if not.
   */
  TransactionId backend_xid;

  /*
   * The xmin of the current session if available, InvalidTransactionId if
   * not.
   */
  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等资源。

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

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-03-03 16:21:05  更:2022-03-03 16:23:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/28 4:23:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码