PostgreSQL/解析

アーカイブ

データベースをPITR(ポイントタイムリカバリ)で任意の地点に復旧させるのにデータベースの先行書き込みログ(WAL)が必要となる。アーカイブ設定を行なうことで、PostgreSQLの機能により、walディレクトリのWALを定期的にバックアップ領域に保存できるようになる。PITRでは、ファイルシステムレベルのバックアップ(ex: pg_basebackup)とWALバックアップを用いて復旧させる。

Archiver

archiver.png

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

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

参考

pg_switch_wal()

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

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

参考

SWITCH切り替え時、WALセグメントはセグメントサイズまで消費される。

引用 backend/access/transam/xlog.c#CopyXLogRecordToWAL()

/*
 * XLogArchiveNotify
 *
 * Create an archive notification file
 *
 * The name of the notification file is the message that will be picked up
 * by the archiver, e.g. we write 0000000100000001000000C6.ready
 * and the archiver then knows to archive XLOGDIR/0000000100000001000000C6,
 * then when complete, rename it to 0000000100000001000000C6.done
 */
void
XLogArchiveNotify(const char *xlog)
{
	char		archiveStatusPath[MAXPGPATH];
	FILE	   *fd;

	/* insert an otherwise empty file called <XLOG>.ready */
	StatusFilePath(archiveStatusPath, xlog, ".ready");
	fd = AllocateFile(archiveStatusPath, "w");
	if (fd == NULL)
	{
		ereport(LOG,
				(errcode_for_file_access(),
				 errmsg("could not create archive status file \"%s\": %m",
						archiveStatusPath)));
		return;
	}
	if (FreeFile(fd))
	{
		ereport(LOG,
				(errcode_for_file_access(),
				 errmsg("could not write archive status file \"%s\": %m",
						archiveStatusPath)));
		return;
	}

	/* Notify archiver that it's got something to do */
	if (IsUnderPostmaster)
		SendPostmasterSignal(PMSIGNAL_WAKEN_ARCHIVER);
}

/*
 * Convenience routine to notify using segment number representation of filename
 */
void
XLogArchiveNotifySeg(XLogSegNo segno)
{
	char		xlog[MAXFNAMELEN];

	XLogFileName(xlog, ThisTimeLineID, segno);
	XLogArchiveNotify(xlog);
}

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

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

以下はバックトレース(master: pg12)。

-- Archiverの統計情報確認
SELECT * FROM pg_stat_archiver
-[ RECORD 1 ]------+------------------------------
archived_count     | 1
last_archived_wal  | 000000010000000000000001
last_archived_time | 2019-03-20 21:44:59.918306+09
failed_count       | 0
last_failed_wal    | 
last_failed_time   | 
stats_reset        | 2019-03-20 21:42:17.409563+09

-- リセット
SELECT pg_stat_reset_shared('archiver')
-[ RECORD 1 ]--------+-
pg_stat_reset_shared | 

-- リセットした後
SELECT * FROM pg_stat_archiver
-[ RECORD 1 ]------+------------------------------
archived_count     | 0
last_archived_wal  | 
last_archived_time | 
failed_count       | 0
last_failed_wal    | 
last_failed_time   | 
stats_reset        | 2019-04-20 21:46:54.795811+09

XLogArchiveNotify関数でpostmasterにシグナルが送られていることが分かる。

引用 backend/access/transam/xlog.c#XLogInsertRecord()

-- 失敗
SELECT * FROM pg_stat_archiver
-[ RECORD 1 ]------+------------------------------
archived_count     | 0
last_archived_wal  | 
last_archived_time | 
failed_count       | 36
last_failed_wal    | 000000010000000000000002
last_failed_time   | 2019-03-21 23:28:10.222111+09
stats_reset        | 2019-03-20 21:46:54.795811+09

-- 失敗
-- failed_countは +3
-- last_failed_timeは、+62 (sec)
SELECT * FROM pg_stat_archiver
-[ RECORD 1 ]------+------------------------------
archived_count     | 0
last_archived_wal  | 
last_archived_time | 
failed_count       | 39
last_failed_wal    | 000000010000000000000002
last_failed_time   | 2019-03-21 23:29:12.234861+09
stats_reset        | 2019-03-20 21:46:54.795811+09

... 省略

-- 成功
-- archived_countは、溜まっていたWALファイルの数で6
SELECT * FROM pg_stat_archiver
-[ RECORD 1 ]------+------------------------------
archived_count     | 6
last_archived_wal  | 000000010000000000000007
last_archived_time | 2019-03-21 23:31:14.954457+09
failed_count       | 42
last_failed_wal    | 000000010000000000000002
last_failed_time   | 2019-03-21 23:30:14.245314+09
stats_reset        | 2019-03-20 21:46:54.795811+09

引用 backend/access/transam/xlog.c#XLogWrite()

# SELECT pg_switch_wal();を実行している

postgres=# \watch 14/20 17:38:51 2019 (every 1s)

 pg_switch_wal 
---------------
 0/45000078
(1 ROW)4/20 17:38:55 2019 (every 1s)

 pg_switch_wal 
---------------
 0/46000078
(1 ROW)4/20 17:38:56 2019 (every 1s)

 pg_switch_wal 
---------------
 0/47000000
(1 ROW)4/20 17:38:57 2019 (every 1s)

 pg_switch_wal 
---------------
 0/47000000
(1 ROW)4/20 17:38:58 2019 (every 1s)

 pg_switch_wal 
---------------
 0/47000000
(1 ROW)4/20 17:38:59 2019 (every 1s)

 pg_switch_wal 
---------------
 0/47000000
(1 ROW)4/20 17:39:00 2019 (every 1s)

 pg_switch_wal 
---------------
 0/47000000
(1 ROW)
 

参考

参考リンク


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