網站首頁 編程語言 正文
我們在很多地方應該都聽到過長事務的危害,比方說長事務會導致表膨脹之類的。那么在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等資源。
在實際應用中,我們應當做好對長事務的監控,并盡可能的避免其發生。例如一些批量的操作可能會比較容易導致長事務,我們可以盡量將其安排在業務低峰期執行,同時,如果我們的應用中關閉了自動提交,也要在執行完之后加上提交。
原文鏈接:https://foucus.blog.csdn.net/article/details/123230865
相關推薦
- 2022-10-12 詳解C++異常處理機制示例介紹_C 語言
- 2022-04-19 教你如何從正在運行的容器創建?Docker?映像_docker
- 2022-09-06 python?共現矩陣的實現代碼_python
- 2022-04-15 C語言?使用qsort函數來進行快速排序_C 語言
- 2023-12-21 JDBC中ResultSet的使用
- 2022-04-25 C#關于Func和Action委托的介紹詳解_C#教程
- 2022-07-13 4:thingsboard的實體與關系
- 2022-05-21 ASP.NET?MVC中兩個配置文件的作用詳解_基礎應用
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支