PostgreSQL如何判斷idleintransaction的事務中有沒有東西要提交
標籤
PostgreSQL , idle in transaction , 事務快照 , 修改 , xid
背景
如何判斷idle in transaction的事務中有沒有東西要提交?
比如在一些情況下,你可能發現資料庫中很多idle in transaction的事務,可能是一些殭屍事務,也可能是一些應用框架引起的,連線建立後就開啟一個事務,實際上裡面啥也沒有。
postgres=# select pid, state from pg_stat_activity ;
pid | state
-------+---------------------
33231 |
33233 |
50650 | active
50723 | active
50801 | active
54168 | idle in transaction
51197 | idle
51983 | active
33229 |
33228 |
33230 |
(11 rows)
那麼如果你需要清理掉一些事務時,如何讓他優雅的退出,或者如何快速的清退那些沒有什麼影響的事務呢?
那就需要判斷idle in transaction的事務中有沒有東西要提交?
通過pg_stat_activity會話判斷
pg_stat_activity會話中有兩個欄位,backend_xid,backend_xmin用來表示會話是否申請了事務號,以及會話的快照ID。
if (TransactionIdIsValid(local_beentry->backend_xid))
values[15] = TransactionIdGetDatum(local_beentry->backend_xid);
else
nulls[15] = true;
if (TransactionIdIsValid(local_beentry->backend_xmin))
values[16] = TransactionIdGetDatum(local_beentry->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;
例子1:
1、開啟一個read committed事務
postgres=# begin;
BEGIN
postgres=# select 1;
?column?
----------
1
(1 row)
postgres=# select pg_backend_pid();
pg_backend_pid
----------------
3497
(1 row)
2、查詢它的事務狀態
postgres=# select * from pg_stat_activity where pid=3497;
-[ RECORD 1 ]----+------------------------------
datid | 16461
datname | postgres
pid | 3497
usesysid | 10
usename | postgres
application_name | psql
client_addr |
client_hostname |
client_port | -1
backend_start | 2018-02-07 13:09:44.506794+08
xact_start | 2018-02-07 13:12:48.322815+08
query_start | 2018-02-07 13:13:03.454437+08
state_change | 2018-02-07 13:13:03.454926+08
wait_event_type | Client
wait_event | ClientRead
state | idle in transaction
backend_xid |
backend_xmin |
query | select pg_backend_pid();
backend_type | client backend
可以看到這個會話的backend_xid和backend_xmin都沒有值,因為它沒有對資料庫有任何寫操作所以不需要申請事務號,因此backend_xid為空。
並且它當前沒有SQL在執行,並且它是read committed的事務隔離級別,因此目前沒有事務快照資訊,backend_xmin為空。
如果後面有QUERY正在執行中,那麼backend_xmin會有一個值,即這條QUERY啟動時的事務快照ID。
例子2:
1、開啟一個repeatable read事務
postgres=# begin isolation level repeatable read ;
BEGIN
postgres=# select 1;
?column?
----------
1
(1 row)
2、查詢它的事務狀態
postgres=# select * from pg_stat_activity where pid=3497;
-[ RECORD 1 ]----+------------------------------
datid | 16461
datname | postgres
pid | 3497
usesysid | 10
usename | postgres
application_name | psql
client_addr |
client_hostname |
client_port | -1
backend_start | 2018-02-07 13:09:44.506794+08
xact_start | 2018-02-07 13:16:30.995233+08
query_start | 2018-02-07 13:16:40.65339+08
state_change | 2018-02-07 13:16:40.653504+08
wait_event_type | Client
wait_event | ClientRead
state | idle in transaction
backend_xid |
backend_xmin | 152207375
query | select 1;
backend_type | client backend
可以看到這個會話的backend_xid沒有值,因為它沒有對資料庫有任何寫操作所以不需要申請事務號,因此backend_xid為空。
它是repeatable read的事務隔離級別,因此在它執行了第一條SQL後,就會獲得一個事務快照,並且跟隨它到事務結束,因此backend_xmin不為空,並且對於rr以上隔離級別的事務,在整個事務過程中backend_xmin是一個不變的值。
例子3:
1、前面提到的任意一個事務,執行一個INSERT。
postgres=# insert into a values (2);
INSERT 0 1
2、查詢它的事務狀態
postgres=# select * from pg_stat_activity where pid=3497;
-[ RECORD 1 ]----+------------------------------
datid | 16461
datname | postgres
pid | 3497
usesysid | 10
usename | postgres
application_name | psql
client_addr |
client_hostname |
client_port | -1
backend_start | 2018-02-07 13:09:44.506794+08
xact_start | 2018-02-07 13:16:30.995233+08
query_start | 2018-02-07 13:18:07.129475+08
state_change | 2018-02-07 13:18:07.13004+08
wait_event_type | Client
wait_event | ClientRead
state | idle in transaction
backend_xid | 152207375
backend_xmin | 152207375
query | insert into a values (2);
backend_type | client backend
可以看到這個會話的backend_xid和backend_xmin都有值了,因為寫入操作要申請事務號,因此backend_xid不為空。
它是repeatable read的事務隔離級別,因此在它執行了第一條SQL後,就會獲得一個事務快照,並且跟隨它到事務結束,因此backend_xmin也不為空。
小結
如何判斷idle in transaction的事務中有沒有東西要提交?
pg_stat_activity.backend_xid不為空的,即說明這個事務有東西要提交。
相關文章
- 斷言的東西如果是有延遲的要怎麼處理?
- 檢視mysql沒提交的事務MySql
- 如何判斷沒有字尾的檔案型別?型別
- 如何判斷一個元素沒有任何內容
- postgresql如何判斷表是否存在SQL
- 漫話:給女朋友解釋GC如何判斷什麼東西可以回收?GC
- 探究MySQL的DML提交事務的意義和DQL是否有必要提交事務MySql
- win10桌面沒東西如何解決_win10桌面的東西都沒有了怎麼辦Win10
- 事務可見性的判斷和事務隔離級別,PostgreSQL和MySQL實現上有啥區別MySql
- 如何判斷企業有沒有精益生產執行力?
- 事務中有webservice的控制Web
- Oracle 如何判斷一個死事務transaction的恢復進度Oracle
- php中有沒有物件PHP物件
- InnoDB事務鎖之行鎖-判斷是否有隱式鎖原理圖
- 判斷裝置驅動有沒有被載入的方法
- spring事務增強,事務回滾如何判斷?希望在前端上有個提示Spring前端
- 如何判斷一份工作有沒有前途?值不值得做?
- Linux 3.16 核心中有什麼新東西?Linux
- flutter engine 那些沒被釋放的東西Flutter
- 怎樣判斷anaconda安裝成功沒有
- 通過 find 命令找到你要找的東西
- Android,你要掌握的一些東西Android
- jQuery 3 有哪些新東西jQuery
- PostgreSQL:事務SQL
- c盤明明沒東西卻爆滿怎麼辦 win10c盤沒東西但是滿了Win10
- PostgreSQL MVCC可見性判斷SQLMVC
- postgresql判斷是否為數字的方法SQL
- 學習PHP到底要學習哪些東西?PHP
- MySQL事務還沒提交,Canal就能讀到訊息了?MySql
- PostgreSQL 原始碼解讀(123)- MVCC#8(提交事務-實際提交過程)SQL原始碼MVCC#
- spring+springMVC中使用@Transcational方式管理事務的必須要配的東西。SpringMVC
- c盤沒東西但顯示滿了win10怎麼辦_win10系統c盤沒東西但是滿了如何處理Win10
- 模擬微任務 判斷是否有對應的apiAPI
- oracle plsql儲存過程_if判斷與事務commitOracleSQL儲存過程MIT
- 如何判斷一項技術是否有前途?
- PostgreSQL的事務隔離分析SQL
- MySQL事務兩段式提交MySql
- MySQL 事務提交過程MySql