6_PostgreSQL WAL文件名解析
内容概述
WAL 是"Write Ahead Logging"简称,和Oracle数据库中的Redo Log功能一样,用于记录数据库中的事务日志,本小节解析WAL文件名?
WAL存储位置
WAL文件存储在 $PGDATA/pg_wal目录下,默认大小16M,文件名由24位16进制数字组成。 [postgres@enmo pgdata]$ ls -ltr $PGDATA/pg_wal/ total 1048576 drwx------ 2 postgres dba 6 Oct 25 11:08 archive_status -rw------- 1 postgres dba 16777216 Oct 25 11:21 00000001000000020000007A -rw------- 1 postgres dba 16777216 Oct 25 11:21 00000001000000020000007B -rw------- 1 postgres dba 16777216 Oct 25 11:21 00000001000000020000007C -rw------- 1 postgres dba 16777216 Oct 25 11:21 00000001000000020000007D -rw------- 1 postgres dba 16777216 Oct 25 11:21 00000001000000020000007E -rw------- 1 postgres dba 16777216 Oct 25 11:21 00000001000000020000007F -rw------- 1 postgres dba 16777216 Oct 25 11:21 000000010000000200000080 -rw------- 1 postgres dba 16777216 Oct 25 11:21 000000010000000200000081 -rw------- 1 postgres dba 16777216 Oct 25 11:21 000000010000000200000082 -rw------- 1 postgres dba 16777216 Oct 25 11:26 000000010000000200000083 [postgres@enmo pgdata]$
获取当前WAL日志
postgres=# select pg_current_wal_lsn(); pg_current_wal_lsn -------------------- 2/830045B0 (1 row) postgres=# select pg_walfile_name('2/830045B0'); pg_walfile_name -------------------------- 000000010000000200000083 (1 row) postgres=# SELECT pg_walfile_name(pg_current_wal_lsn()); pg_walfile_name -------------------------- 000000010000000200000083 (1 row) postgres=#
如何通过LSN获取WAL文件名

timelineID: 时间线,前32bit长的16进制数,类似于Oracle中的incarnation。 LogId: 中间32bit长的16进制数,实际为LSN的高32bit。LogSeg进位时加1。 LogSeg: 后32bit长的16进制数,实际为LSN的低32bit再除以WAL大小的结果。取值为000000-0000FF
pg_walfile_name源码执行过程
pg_walfile_name函数
* Compute an xlog file name given a WAL location,
* such as is returned by pg_backup_stop() or pg_switch_wal().
*/
Datum
pg_walfile_name(PG_FUNCTION_ARGS)
{
XLogSegNo xlogsegno;
//根据输入LSN计算locationpoint: typedef uint64 XLogRecPtr;
XLogRecPtr locationpoint = PG_GETARG_LSN(0);
char xlogfilename[MAXFNAMELEN];
if (RecoveryInProgress())
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("recovery is in progress"),
errhint("%s cannot be executed during recovery.",
"pg_walfile_name()")));
//根据locationpoint和wal_segment_size求xlogsegno值
XLByteToPrevSeg(locationpoint, xlogsegno, wal_segment_size);
//根据xlogsegno/wal_segment_size/GetWALInsertionTimeLine(),获取xlogfilename
XLogFileName(xlogfilename, GetWALInsertionTimeLine(), xlogsegno,
wal_segment_size);
PG_RETURN_TEXT_P(cstring_to_text(xlogfilename));
}
GetWALInsertionTimeLine函数
/*
* GetWALInsertionTimeLine -- Returns the current timeline of a system that
* is not in recovery.
*/
TimeLineID
GetWALInsertionTimeLine(void)
{
Assert(XLogCtl->SharedRecoveryState == RECOVERY_STATE_DONE);
/* Since the value can't be changing, no lock is required. */
return XLogCtl->InsertTimeLineID;
}
XLogFileName函数
/*
* Generate a WAL segment file name. Do not use this macro in a helper
* function allocating the result generated.
*/
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes) \
snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli, \
(uint32) ((logSegNo) / XLogSegmentsPerXLogId(wal_segsz_bytes)), \
(uint32) ((logSegNo) % XLogSegmentsPerXLogId(wal_segsz_bytes)))
最后修改时间:2022-11-15 21:20:34
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




