PostgreSQL/解析

WAL(Write Ahead Logging)

WALの構造

PostgreSQLでは、データベースクラスタの下のpg_wal(ver10以降、以前はpg_xlog)にWALログが書かれる。

論理構造

参考

WALログ内部構造

wal_internal.png

XLOGに関するマクロ

XLOGのバイトポジションやセグメント、ファイル名を求めるためのマクロがある。
以下、代表的なマクロの使用例である。

#define FRONTEND 1
#include "postgres.h"

#include "access/xlog_internal.h"

int
main(int argc, char **argv)
{
	uint32		xrecoff;
	XLogSegNo	segno;
	XLogRecPtr	xlogptr;
	TimeLineID	tli;
	char 		fname[MAXFNAMELEN];


	// XLogSegmentsPerXLogId(wal_segsz_bytes)
	printf("XLogSegmentsPerXLogId = %zu\n", XLogSegmentsPerXLogId(DEFAULT_XLOG_SEG_SIZE));

	// XLogSegNoOffsetToRecPtr(segno, offset, wal_segsz_bytes, dest)
	XLogSegNoOffsetToRecPtr(1, 0, DEFAULT_XLOG_SEG_SIZE, xlogptr);
	printf("XLogSegNoOffsetToRecPtr(1, 0, DEFAULT_XLOG_SEG_SIZE, xlogptr) = %zu\n", xlogptr);

	// XLogSegmentOffset(xlogptr, wal_segsz_bytes)
	xlogptr = DEFAULT_XLOG_SEG_SIZE + 24;
	xrecoff = XLogSegmentOffset(xlogptr, DEFAULT_XLOG_SEG_SIZE);
	printf("XLogSegmentOffset(DEFAULT_XLOG_SEG_SIZE + 24, DEFAULT_XLOG_SEG_SIZE): xrecoff = %u\n", xrecoff);

	// XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)
	xlogptr = DEFAULT_XLOG_SEG_SIZE * 2 - 1;
	XLByteToSeg(xlogptr, segno, DEFAULT_XLOG_SEG_SIZE);
	printf("LByteToSeg(DEFAULT_XLOG_SEG_SIZE * 2 - 1, segno, DEFAULT_XLOG_SEG_SIZE): segno = %zu\n", segno);

	xlogptr = DEFAULT_XLOG_SEG_SIZE * 2;
	XLByteToSeg(xlogptr, segno, DEFAULT_XLOG_SEG_SIZE);
	printf("XLByteToSeg(DEFAULT_XLOG_SEG_SIZE * 2, segno, DEFAULT_XLOG_SEG_SIZE): segno = %zu\n", segno);

	// XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes)
	xlogptr = DEFAULT_XLOG_SEG_SIZE * 2;
	XLByteToPrevSeg(xlogptr, segno, DEFAULT_XLOG_SEG_SIZE);
	printf("XLByteToPrevSeg(DEFAULT_XLOG_SEG_SIZE * 2, segno, DEFAULT_XLOG_SEG_SIZE): segno = %zu\n", segno);

	// XRecOffIsValid(xlrp);
	if (XRecOffIsValid(DEFAULT_XLOG_SEG_SIZE))
		printf("%s\n", "XRecOffIsValid(DEFAULT_XLOG_SEG_SIZE) is true");
	else
		printf("%s\n", "XRecOffIsValid(DEFAULT_XLOG_SEG_SIZE) is false");


	// XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
	XLogFileName(fname, 1, 1, DEFAULT_XLOG_SEG_SIZE);
	printf("XLogFileName(fname, 1, 1, DEFAULT_XLOG_SEG_SIZE): fname = %s\n", fname);

	XLogFileName(fname, 2, 2, DEFAULT_XLOG_SEG_SIZE);
	printf("XLogFileName(fname, 2, 2, DEFAULT_XLOG_SEG_SIZE): fname = %s\n", fname);

	// XLogFileNameById(fname, tli, log, seg)
	XLogFileNameById(fname, 1, 0, 1);
	printf("XLogFileNameById(fname, 1, 0, 1): fname = %s\n", fname);

	// IsXLogFileName(fname)
	strcpy(fname, "000000010000000000000001");
	if (IsXLogFileName(fname))
		printf("IsXLogFileName(\"%s\") is true\n", fname);
	else
		printf("IsXLogFileName(\"%s\") is false\n", fname);

	strcpy(fname, "00000001000000000000000#");
	if (IsXLogFileName(fname))
		printf("IsXLogFileName(\"%s\") is true\n", fname);
	else
		printf("IsXLogFileName(\"%s\") is false\n", fname);

	// IsPartialXLogFileName(fname)
	strcpy(fname, "000000010000000000000001.partial");
	if (IsPartialXLogFileName(fname))
		printf("IsPartialXLogFileName(\"%s\") is true\n", fname);
	else
		printf("IsPartialXLogFileName(\"%s\") is false\n", fname);

	// XLogFromFileName(fname, tli, logSegNo, wal_segsz_bytes)
	strcpy(fname, "0000000100000000000000FE");
	XLogFromFileName(fname, &tli, &segno, DEFAULT_XLOG_SEG_SIZE);
	printf("XLogFromFileName(fname, &tli, &segno, DEFAULT_XLOG_SEG_SIZE): fname = %s, tli = %u, segno = %zu\n",
		   fname, tli, segno);

	return EXIT_SUCCESS;
}





//  実行結果 ------------------
XLogSegmentsPerXLogId = 256
XLogSegNoOffsetToRecPtr(1, 0, DEFAULT_XLOG_SEG_SIZE, xlogptr) = 16777216
XLogSegmentOffset(DEFAULT_XLOG_SEG_SIZE + 24, DEFAULT_XLOG_SEG_SIZE): xrecoff = 24
LByteToSeg(DEFAULT_XLOG_SEG_SIZE * 2 - 1, segno, DEFAULT_XLOG_SEG_SIZE): segno = 1
XLByteToSeg(DEFAULT_XLOG_SEG_SIZE * 2, segno, DEFAULT_XLOG_SEG_SIZE): segno = 2
XLByteToPrevSeg(DEFAULT_XLOG_SEG_SIZE * 2, segno, DEFAULT_XLOG_SEG_SIZE): segno = 1
XRecOffIsValid(DEFAULT_XLOG_SEG_SIZE) is false
XLogFileName(fname, 1, 1, DEFAULT_XLOG_SEG_SIZE): fname = 000000010000000000000001
XLogFileName(fname, 2, 2, DEFAULT_XLOG_SEG_SIZE): fname = 000000020000000000000002
XLogFileNameById(fname, 1, 0, 1): fname = 000000010000000000000001
IsXLogFileName("000000010000000000000001") is true
IsXLogFileName("00000001000000000000000#") is false
IsPartialXLogFileName("000000010000000000000001.partial") is true
XLogFromFileName(fname, &tli, &segno, DEFAULT_XLOG_SEG_SIZE): fname = 0000000100000000000000FE, tli = 1, segno = 254

サンプル filexlog_macro_test.zip

WALレコードの読み取り

参考リンク


添付ファイル: filewal_internal.png 97件 [詳細] filexlog_macro_test.zip 77件 [詳細]

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