簡體   English   中英

PostgresQL:整個事務是否總是寫入復制槽?

[英]PostgresQL: Is an entire transaction always written to a replication slot?

我創建了一個復制槽:

SELECT * FROM pg_create_logical_replication_slot('boxoffice_slot', 'test_decoding');

事務中的每個步驟在復制槽中都有自己的行。 下面是一個例子:

     lsn     |   xid   |     data
-------------+---------+---------------
 34A/7000028 | 1311904 | BEGIN 1311904
 34A/70020E0 | 1311904 | table cad.purchases: INSERT: id[integer]:754862
 34A/70020E1 | 1311904 | table cad.purchases: INSERT: id[integer]:754863
 34A/7000028 | 1311904 | COMMIT 1311904

問題:
在事務生命周期的哪個點,事務步驟開始寫入復制槽?

是否有可能在提交事務之前將事務步驟寫入復制槽?

換句話說,是否有可能在任何給定時間只將一半事務寫入復制槽,如下所示:

     lsn     |   xid   |     data
-------------+---------+---------------
 34A/7000028 | 1311904 | BEGIN 1311904
 34A/70020E0 | 1311904 | table cad.purchases: INSERT: id[integer]:754862

非常感謝您對此的見解。

事務根本不會寫入復制槽。 它們被寫入 WAL。 肯定會發生只有部分事務寫入 WAL 的情況,例如,如果處理被中斷。

部分寫入的事務將在會話結束時(或在服務器崩潰的恢復期間)自動標記為回滾。

復制槽所容納的數據並不多於 LSN(日志序列號)。 它們是在 WAL 中標記位置的持久數據結構。 這樣主服務器就不會丟棄消費者仍然需要的任何 WAL。 當消費者處理 WAL 時,它會推進復制槽的 LSN,以便主服務器可以丟棄已經消耗的 WAL。

事務中的所有內容都在發生時寫入復制槽。 如果事務回滾,則將回滾輸入 WAL。 如果流在事務中間中斷,則事務不會在訂閱者端提交,至少在重新建立連接之前不會提交。

一種測試方法是創建一個復制槽,然后在另一個終端中,使用pg_recvlogical查看更改:

pg_recvlogical -d postgres --slot <slot_name> --start --verbose -f -

如果您BEGIN事務,創建一個表並插入一百萬行到它,你會看到write up toflush to值都在增加,即使交易沒有得到提交/回滾。 這告訴我們更改正在傳播到接收器端:

# pg_recvlogical -d postgres --slot regression_slot --start --verbose -f -
pg_recvlogical: starting log streaming at 0/0 (slot regression_slot)
pg_recvlogical: streaming initiated
pg_recvlogical: confirming write up to 0/0, flush to 0/0 (slot regression_slot)
pg_recvlogical: confirming write up to 0/DF5E620, flush to 0/DF5E620 (slot regression_slot)
pg_recvlogical: confirming write up to 0/DF5E620, flush to 0/DF5E620 (slot regression_slot)
pg_recvlogical: confirming write up to 0/12E01AB8, flush to 0/12E01AB8 (slot regression_slot)
pg_recvlogical: confirming write up to 0/12E01AF0, flush to 0/12E01AF0 (slot regression_slot)

此外,如果您在交易結束前后在終端中查看pg_current_wal_lsn() ,您將看到 LSN 增加,即使您回滾:

 pg_current_wal_lsn 
--------------------
 0/DF5E620
(1 row)

postgres=# begin;
BEGIN
postgres=# select pg_current_wal_lsn();
 pg_current_wal_lsn 
--------------------
 0/DF5E620
(1 row)

postgres=# insert into abc values (generate_series(1,1000000),'foobar');
INSERT 0 1000000
postgres=# select pg_current_wal_lsn();
 pg_current_wal_lsn 
--------------------
 0/1243C000
(1 row)

postgres=# rollback;
ROLLBACK
postgres=# select pg_current_wal_lsn();
 pg_current_wal_lsn 
--------------------
 0/12E01AB8
(1 row)

基於以下測試,我得出結論,只有在提交事務后才將事務插入到復制槽中。

testing=# BEGIN;
BEGIN
testing=# SELECT * FROM pg_logical_slot_get_changes('testing_slot', NULL, NULL);
 lsn | xid | data
-----+-----+------
(0 rows)

testing=# insert into person values (generate_series(1,10));
INSERT 0 10
testing=# SELECT * FROM pg_logical_slot_get_changes('testing_slot', NULL, NULL);
 lsn | xid | data
-----+-----+------
(0 rows)

testing=# COMMIT;
COMMIT
testing=# SELECT * FROM pg_logical_slot_get_changes('testing_slot', NULL, NULL);
    lsn     |   xid    |                           data
------------+----------+-----------------------------------------------------------
 D/23426BC0 | 16171153 | BEGIN 16171153
 D/23426BC0 | 16171153 | table public.person: INSERT: name[character varying]:'1'
 D/23427078 | 16171153 | table public.person: INSERT: name[character varying]:'2'
 D/234270B8 | 16171153 | table public.person: INSERT: name[character varying]:'3'
 D/234270F8 | 16171153 | table public.person: INSERT: name[character varying]:'4'
 D/23427138 | 16171153 | table public.person: INSERT: name[character varying]:'5'
 D/23427178 | 16171153 | table public.person: INSERT: name[character varying]:'6'
 D/234271B8 | 16171153 | table public.person: INSERT: name[character varying]:'7'
 D/234271F8 | 16171153 | table public.person: INSERT: name[character varying]:'8'
 D/23427238 | 16171153 | table public.person: INSERT: name[character varying]:'9'
 D/23427278 | 16171153 | table public.person: INSERT: name[character varying]:'10'
 D/23427320 | 16171153 | COMMIT 16171153
(12 rows)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM