PostgreSQL長事務(wù)概念解析
我們在很多地方應(yīng)該都聽到過長事務(wù)的危害,比方說長事務(wù)會(huì)導(dǎo)致表膨脹之類的。那么在PostgreSQL中什么才算是長事務(wù)呢?
首先,在PostgreSQL的官方文檔中并沒有所謂“長事務(wù)”這一定義,似乎大家約定俗稱的把一個(gè)執(zhí)行了很長卻沒有提交的事務(wù)認(rèn)為是“長事務(wù)”了,而在不同的數(shù)據(jù)庫中關(guān)于長事務(wù)的定義往往也不盡相同,那么在PostgreSQL中什么是長事務(wù)呢?
打個(gè)比方,如下所示,我在一個(gè)會(huì)話中通過begin開啟一個(gè)事務(wù),然后執(zhí)行了個(gè)簡單的查詢語句后遲遲不提交,這算不算長事務(wù)呢?
bill=# begin;
BEGIN
bill=*# select 1;
?column?
----------
1
(1 row)bill=*#
為了搞清楚這個(gè)問題,我們不妨想想,為什么我們會(huì)提到長事務(wù)呢。這是因?yàn)閜g中的長事務(wù)會(huì)影響表中垃圾回收,會(huì)導(dǎo)致表的年齡增長無法freeze。而我們上面這個(gè)會(huì)話開啟的事務(wù)會(huì)有影響嗎?實(shí)際上并不會(huì),我們可以通過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
之所以會(huì)導(dǎo)致表膨脹之類的問題,主要是在于backend_xid和backend_xmin兩個(gè)字段,而上面的事務(wù)這兩個(gè)字段均是空的。
/* ---------- * 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表示已申請事務(wù)號的事務(wù),例如有增刪改,DLL等操作的事務(wù)。backend_xid從申請事務(wù)號開始持續(xù)到事務(wù)結(jié)束。
backend_xmin表示SQL執(zhí)行時(shí)的snapshot,即可見的最大已提交事務(wù)。
而表膨脹的原因是什么呢?當(dāng)數(shù)據(jù)庫中存在未結(jié)束的SQL語句或者未結(jié)束的持有事務(wù)ID的事務(wù),在此事務(wù)過程中,或在此SQL執(zhí)行時(shí)間范圍內(nèi)產(chǎn)生垃圾的話,這些垃圾無法回收,導(dǎo)致數(shù)據(jù)庫膨脹。
也就是判斷當(dāng)前數(shù)據(jù)庫中backend_xid和backend_xmin最小的值,凡是超過這個(gè)最小值的事務(wù)產(chǎn)生的垃圾都不能回收。
因此,我們?nèi)绻胍O(jiān)控長事務(wù)該怎么寫呢?以超過1小時(shí)的長事務(wù)為例:
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;
所以,對于事務(wù)而言,只有當(dāng)執(zhí)行了一些DML或者DDL操作后才能算是我們通常說的長事務(wù)。否則只能算是我們常說的長連接,當(dāng)然長連接也有很多弊端,例如占用內(nèi)存、cpu等資源。
在實(shí)際應(yīng)用中,我們應(yīng)當(dāng)做好對長事務(wù)的監(jiān)控,并盡可能的避免其發(fā)生。例如一些批量的操作可能會(huì)比較容易導(dǎo)致長事務(wù),我們可以盡量將其安排在業(yè)務(wù)低峰期執(zhí)行,同時(shí),如果我們的應(yīng)用中關(guān)閉了自動(dòng)提交,也要在執(zhí)行完之后加上提交。
到此這篇關(guān)于PostgreSQL長事務(wù)概念解析的文章就介紹到這了,更多相關(guān)PostgreSQL長事務(wù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- PostgreSQL如何查看事務(wù)所占有的鎖實(shí)操指南
- PostgreSQL 存儲(chǔ)過程的進(jìn)階講解(含游標(biāo)、錯(cuò)誤處理、自定義函數(shù)、事務(wù))
- PostgreSQL長事務(wù)與失效的索引查詢淺析介紹
- PostgreSQL數(shù)據(jù)庫事務(wù)插入刪除及更新操作示例
- PostgreSQL事務(wù)回卷實(shí)戰(zhàn)案例詳析
- 基于Postgresql 事務(wù)的提交與回滾解析
- PostgreSQL數(shù)據(jù)庫事務(wù)實(shí)現(xiàn)方法分析
- PostgreSQL數(shù)據(jù)庫事務(wù)出現(xiàn)未知狀態(tài)的處理方法
- 深入理解PostgreSQL 事務(wù)處理
相關(guān)文章
詳解PostgreSQL 實(shí)現(xiàn)定時(shí)任務(wù)的 4 種方法
這篇文章主要介紹了PostgreSQL 實(shí)現(xiàn)定時(shí)任務(wù)的 4 種方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02postgresql如何查詢重復(fù)計(jì)數(shù)及去重查詢
這篇文章主要介紹了postgresql如何查詢重復(fù)計(jì)數(shù)及去重查詢問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11PostgreSQL 用戶名大小寫規(guī)則小結(jié)
PostgreSQL默認(rèn)不區(qū)分用戶名大小寫,創(chuàng)建和連接時(shí)自動(dòng)轉(zhuǎn)為小寫,使用雙引號可強(qiáng)制區(qū)分,下面就來介紹一下PostgreSQL 用戶名大小寫規(guī)則,感興趣的可以了解一下2025-06-06PGSQL 實(shí)現(xiàn)查詢今天,昨天的數(shù)據(jù),一個(gè)月之內(nèi)的數(shù)據(jù)
這篇文章主要介紹了PGSQL 實(shí)現(xiàn)查詢今天,昨天的數(shù)據(jù),一個(gè)月之內(nèi)的數(shù)據(jù),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01PostgreSQL 如何修改文本類型字段的存儲(chǔ)方式
這篇文章主要介紹了PostgreSQL 如何修改文本類型字段的存儲(chǔ)方式,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12PostgreSQL數(shù)據(jù)庫事務(wù)實(shí)現(xiàn)方法分析
這篇文章主要介紹了PostgreSQL數(shù)據(jù)庫事務(wù)實(shí)現(xiàn)方法,簡單講述了事務(wù)的概念、功能,并結(jié)合實(shí)例形式分析了PostgreSQL數(shù)據(jù)庫事務(wù)的定義方法及相關(guān)注意事項(xiàng),需要的朋友可以參考下2018-08-08postgres array_to_string和array的用法講解
這篇文章主要介紹了postgres array_to_string和array的用法講解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01