#author("2019-04-19T17:49:44+00:00","default:haikikyou","haikikyou")
[[PostgreSQL/解析]]

* archiver [#uad4ce3c]
&ref(./archiver.png,100%);
-  WALアーカイブを実行しているのは、archiverプロセスである。
- archiverプロセスは、起動後はメインループ内でアーカイブコピーを繰り返し行なう。
- メインループはLatchでwaitし、およそ&code(){PGARCH_AUTOWAKE_INTERVAL};(60秒)ごとにループ内の処理を実行する。Latchのタイムアウトは以下で計算される。
 PGARCH_AUTOWAKE_INTERVAL - (curtime - last_copy_time)
- archive_statusディレクトリから、.readyがサフィックスであるファイルを探す。~
historyファイルが存在する場合はそれが優先され、複数のhistoryファイルが存在する場合は、最も古いhistoryファイルが優先される。


アーカイブコピーの契機は以下。

- Latchでタイムアウト秒経過する
- シグナル(SIGUSR1)を受けとる
-- postmasterのsigusr1_handlerでPMSIGNAL_WAKEN_ARCHIVERのシグナルであることを確認し、postmasterがarchiverにSIGUSR1を送る

アーカイブコピーの処理の流れは以下。

- archive_statusディレクトリに.readyファイルがあるかチェックする
- archive_commandがセットされているか確認する、セットされていない場合はアーカイブを実行しない。WARNINGが出る。
-- archive_mode enabled, yet archive_command is not set
-  walディレクトリから、.readyで示されるwalログファイルを探す。該当するファイルが存在しない場合、孤児となった.readyを消す。消すのに失敗した場合、1秒のインターバルで&code(){NUM_ORPHAN_CLEANUP_RETRIES};(3回)失敗するまで試行する。
- アーカイブする。
-- アーカイブは、&code(){archive_command};で指定されるコマンドを&code(){system};関数でキックする。
-- アーカイブに成功した場合は、.readyを.doneにする。
- 統計情報コレクタに、archiverの統計情報を送る(pg_stat_archiverビュー)。

&label(warn){参考}; 

- [[backend/postmaster/pgarch.c>https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/postmaster/pgarch.c;h=dc2739bf36db4bbc318a82dba42f8e34d58b68ef;hb=refs/heads/REL_10_STABLE]] - &size(11){&color(gray){https://git.postgresql.org/gitweb/?p=postgresql.git;a=shortlog;h=refs/heads/REL_10_STABLE};};
- [[pg_stat_archiverビュー>https://www.postgresql.jp/document/10/html/monitoring-stats.html#PG-STAT-ARCHIVER-VIEW]] - &size(11){&color(gray){on https://www.postgresql.jp/document/10/html/monitoring-stats.html#PG-STAT-ARCHIVER-VIEW};};
* pg_switch_wal() [#o8c5fda8]

&code(){pg_switch_wal};関数は、強制的にWALログの切り替えを行なう。~
&code(){pg_waldump};でWALの内部を解析すると、XLOG rmgrのinfo値で&code(){XLOG_SWITCH};という種別のWALが書き込まれる。

#geshi{{{
rmgr: XLOG        len (rec/tot):     24/    24, tx:          0, lsn: 0/18000060, prev 0/18000028, desc: SWITCH 
}}}

&label(warn){参考};
- [[9.26.3. バックアップ制御関数>https://www.postgresql.jp/document/10/html/functions-admin.html]] - https://www.postgresql.jp/document/10/html/functions-admin.html

また、強制切り替えを行なった後、切り替わりでSWITCHが書き込まれたWALログは、即座にアーカイブできるようにする。内部的にはPostmasterに対し、archiverを起こすためのシグナルが送られている。(&code(){PMSIGNAL_WAKEN_ARCHIVER};)


#geshi{{{
postgres=# select pg_switch_wal();
 pg_switch_wal 
---------------
 0/18000078
(1 row)

}}}

以下はバックトレース。

#geshi{{{
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 17.1
  * frame #0: 0x0000000106fe89ed postgres`XLogArchiveNotify(xlog="000000010000000000000019") at xlogarchive.c:531
    frame #1: 0x0000000106fe8afd postgres`XLogArchiveNotifySeg(segno=25) at xlogarchive.c:543
    frame #2: 0x0000000106fd1015 postgres`XLogWrite(WriteRqst=(Write = 436207616, Flush = 436207616), flexible=false) at xlog.c:2540
    frame #3: 0x0000000106fd027b postgres`XLogFlush(record=436207616) at xlog.c:2921
    frame #4: 0x0000000106fcf34d postgres`XLogInsertRecord(rdata=0x000000010783d1d0, fpw_lsn=0, flags='\0') at xlog.c:1150
    frame #5: 0x0000000106febd0f postgres`XLogInsert(rmid='\0', info='@') at xloginsert.c:462
    frame #6: 0x0000000106fdf8a5 postgres`RequestXLogSwitch(mark_unimportant=false) at xlog.c:9387
    frame #7: 0x0000000106fe9c79 postgres`pg_switch_wal(fcinfo=0x00007f8848808880) at xlogfuncs.c:292
    frame #8: 0x00000001071927ac postgres`ExecInterpExpr(state=0x00007f8848808798, econtext=0x00007f8848808488, isnull=0x00007ffee8d3d81f) at execExprInterp.c:625
    frame #9: 0x0000000107191b92 postgres`ExecInterpExprStillValid(state=0x00007f8848808798, econtext=0x00007f8848808488, isNull=0x00007ffee8d3d81f) at execExprInterp.c:1769
    frame #10: 0x00000001071e2a3b postgres`ExecEvalExprSwitchContext(state=0x00007f8848808798, econtext=0x00007f8848808488, isNull=0x00007ffee8d3d81f) at executor.h:312
    frame #11: 0x00000001071e29be postgres`ExecProject(projInfo=0x00007f8848808790) at executor.h:346
    frame #12: 0x00000001071e26f3 postgres`ExecResult(pstate=0x00007f8848808370) at nodeResult.c:136
    frame #13: 0x00000001071aa5d2 postgres`ExecProcNodeFirst(node=0x00007f8848808370) at execProcnode.c:445
    frame #14: 0x00000001071a3332 postgres`ExecProcNode(node=0x00007f8848808370) at executor.h:244
    frame #15: 0x000000010719ecf1 postgres`ExecutePlan(estate=0x00007f8848808118, planstate=0x00007f8848808370, use_parallel_mode=false, operation=CMD_SELECT, sendTuples=true, numberTuples=0, direction=ForwardScanDirection, dest=0x00007f8847823650, execute_once=true) at execMain.c:1643
    frame #16: 0x000000010719ebb2 postgres`standard_ExecutorRun(queryDesc=0x00007f8848802d18, direction=ForwardScanDirection, count=0, execute_once=true) at execMain.c:362
    frame #17: 0x000000010719e982 postgres`ExecutorRun(queryDesc=0x00007f8848802d18, direction=ForwardScanDirection, count=0, execute_once=true) at execMain.c:306
    frame #18: 0x00000001073eb006 postgres`PortalRunSelect(portal=0x00007f8847061518, forward=true, count=0, dest=0x00007f8847823650) at pquery.c:929
    frame #19: 0x00000001073ea9bc postgres`PortalRun(portal=0x00007f8847061518, count=9223372036854775807, isTopLevel=true, run_once=true, dest=0x00007f8847823650, altdest=0x00007f8847823650, completionTag="") at pquery.c:770
    frame #20: 0x00000001073e5fe8 postgres`exec_simple_query(query_string="select pg_switch_wal();") at postgres.c:1215
    frame #21: 0x00000001073e5188 postgres`PostgresMain(argc=1, argv=0x00007f8847025538, dbname="postgres", username="t-moriyasu") at postgres.c:4247
    frame #22: 0x0000000107321aa0 postgres`BackendRun(port=0x00007f8846d01720) at postmaster.c:4401
    frame #23: 0x0000000107320ea5 postgres`BackendStartup(port=0x00007f8846d01720) at postmaster.c:4092
    frame #24: 0x000000010731fdfa postgres`ServerLoop at postmaster.c:1705
    frame #25: 0x000000010731d6b9 postgres`PostmasterMain(argc=3, argv=0x00007f8846c03270) at postmaster.c:1378
    frame #26: 0x0000000107221339 postgres`main(argc=3, argv=0x00007f8846c03270) at main.c:228
    frame #27: 0x00007fff508df015 libdyld.dylib`start + 1
}}}

&code(){XLogArchiveNotify};関数でpostmasterにシグナルが送られていることが分かる。

&label(warn){参考};

- [[backend/access/transam/xlogarchive.c>https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/access/transam/xlogarchive.c;h=7825cfe532e2436115f26feee8d9502a24f340e1;hb=refs/heads/REL_10_STABLE#l491]] - &size(11){&color(gray){https://git.postgresql.org/gitweb/?p=postgresql.git;a=shortlog;h=refs/heads/REL_10_STABLE};};
* 参考リンク [#p7aa34cf]

- [[PostgreSQLのarchiverの挙動を調べた>https://qiita.com/U_ikki/items/dd9a58857a4ffb84f97d]] - &size(11){&color(gray){on https://qiita.com/U_ikki/items/dd9a58857a4ffb84f97d]};};

トップ   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
目次
ダブルクリックで閉じるTOP | 閉じる
GO TO TOP