初步学习pg_control文件之十四
看如下几个:
/*
* Parameter settings that determine if the WAL can be used for archival
* or hot standby.
*/
int wal_level;
int MaxConnections;
int max_prepared_xacts;
int max_locks_per_xact;
PostgreSQL中多次用到了函数数组:
/*
* Method table for resource managers.
*
* RmgrTable[] is indexed by RmgrId values (see rmgr.h).
*/
typedef struct RmgrData
{
const char *rm_name;
void (*rm_redo) (XLogRecPtr lsn, XLogRecord *rptr);
void (*rm_desc) (StringInfo buf, uint8 xl_info, char *rec);
void (*rm_startup) (void);
void (*rm_cleanup) (void);
bool (*rm_safe_restartpoint) (void);
} RmgrData; const RmgrData RmgrTable[RM_MAX_ID + ] = {
{"XLOG", xlog_redo, xlog_desc, NULL, NULL, NULL},
{"Transaction", xact_redo, xact_desc, NULL, NULL, NULL},
{"Storage", smgr_redo, smgr_desc, NULL, NULL, NULL},
{"CLOG", clog_redo, clog_desc, NULL, NULL, NULL},
{"Database", dbase_redo, dbase_desc, NULL, NULL, NULL},
{"Tablespace", tblspc_redo, tblspc_desc, NULL, NULL, NULL},
{"MultiXact", multixact_redo, multixact_desc, NULL, NULL, NULL},
{"RelMap", relmap_redo, relmap_desc, NULL, NULL, NULL},
{"Standby", standby_redo, standby_desc, NULL, NULL, NULL},
{"Heap2", heap2_redo, heap2_desc, NULL, NULL, NULL},
{"Heap", heap_redo, heap_desc, NULL, NULL, NULL},
{"Btree", btree_redo, btree_desc, btree_xlog_startup, btree_xlog_cleanup, btree_safe_restartpoint},
{"Hash", hash_redo, hash_desc, NULL, NULL, NULL},
{"Gin", gin_redo, gin_desc, gin_xlog_startup, gin_xlog_cleanup, gin_safe_restartpoint},
{"Gist", gist_redo, gist_desc, gist_xlog_startup, gist_xlog_cleanup, NULL},
{"Sequence", seq_redo, seq_desc, NULL, NULL, NULL}
};
看代码:
/*
* This must be called ONCE during postmaster or standalone-backend startup
*/
void
StartupXLOG(void)
{
…
/*
* Check whether we need to force recovery from WAL. If it appears to
* have been a clean shutdown and we did not have a recovery.conf file,
* then assume no recovery needed.
*/
if (XLByteLT(checkPoint.redo, RecPtr))
{
if (wasShutdown)
ereport(PANIC,
(errmsg("invalid redo record in shutdown checkpoint")));
InRecovery = true;
}
else if (ControlFile->state != DB_SHUTDOWNED)
InRecovery = true;
else if (InArchiveRecovery)
{
/* force recovery due to presence of recovery.conf */
InRecovery = true;
} /* REDO */
if (InRecovery)
{
…
/*
* Find the first record that logically follows the checkpoint --- it
* might physically precede it, though.
*/
if (XLByteLT(checkPoint.redo, RecPtr))
{
/* back up to find the record */
record = ReadRecord(&(checkPoint.redo), PANIC, false);
}
else
{
/* just have to read next record after CheckPoint */
record = ReadRecord(NULL, LOG, false);
} if (record != NULL)
{
bool recoveryContinue = true;
bool recoveryApply = true;
bool recoveryPause = false;
ErrorContextCallback errcontext;
TimestampTz xtime; InRedo = true; ereport(LOG,
(errmsg("redo starts at %X/%X",
ReadRecPtr.xlogid, ReadRecPtr.xrecoff))); /*
* main redo apply loop
*/
do
{
#ifdef WAL_DEBUG
if (XLOG_DEBUG ||
(rmid == RM_XACT_ID && trace_recovery_messages <= DEBUG2) ||
(rmid != RM_XACT_ID && trace_recovery_messages <= DEBUG3))
{
StringInfoData buf; initStringInfo(&buf);
appendStringInfo(&buf, "REDO @ %X/%X; LSN %X/%X: ",
ReadRecPtr.xlogid, ReadRecPtr.xrecoff,
EndRecPtr.xlogid, EndRecPtr.xrecoff);
xlog_outrec(&buf, record);
appendStringInfo(&buf, " - ");
RmgrTable[record->xl_rmid].rm_desc(&buf,
record->xl_info,
XLogRecGetData(record));
elog(LOG, "%s", buf.data);
pfree(buf.data);
}
#endif /* Handle interrupt signals of startup process */
HandleStartupProcInterrupts(); /* Allow read-only connections if we're consistent now */
CheckRecoveryConsistency(); /*
* Have we reached our recovery target?
*/
if (recoveryStopsHere(record, &recoveryApply))
{
/*
* Pause only if users can connect to send a resume
* message
*/
if (recoveryPauseAtTarget && standbyState == STANDBY_SNAPSHOT_READY)
{
SetRecoveryPause(true);
recoveryPausesHere();
}
reachedStopPoint = true; /* see below */
recoveryContinue = false;
if (!recoveryApply)
break;
} /* Setup error traceback support for ereport() */
errcontext.callback = rm_redo_error_callback;
errcontext.arg = (void *) record;
errcontext.previous = error_context_stack;
error_context_stack = &errcontext; /* nextXid must be beyond record's xid */
if (TransactionIdFollowsOrEquals(record->xl_xid,
ShmemVariableCache->nextXid))
{
ShmemVariableCache->nextXid = record->xl_xid;
TransactionIdAdvance(ShmemVariableCache->nextXid);
} /*
* Update shared replayEndRecPtr before replaying this record,
* so that XLogFlush will update minRecoveryPoint correctly.
*/
SpinLockAcquire(&xlogctl->info_lck);
xlogctl->replayEndRecPtr = EndRecPtr;
recoveryPause = xlogctl->recoveryPause;
SpinLockRelease(&xlogctl->info_lck); /*
* Pause only if users can connect to send a resume message
*/
if (recoveryPause && standbyState == STANDBY_SNAPSHOT_READY)
recoveryPausesHere(); /*
* If we are attempting to enter Hot Standby mode, process
* XIDs we see
*/
if (standbyState >= STANDBY_INITIALIZED &&
TransactionIdIsValid(record->xl_xid))
RecordKnownAssignedTransactionIds(record->xl_xid); RmgrTable[record->xl_rmid].rm_redo(EndRecPtr, record); /* Pop the error context stack */
error_context_stack = errcontext.previous; /*
* Update shared recoveryLastRecPtr after this record has been
* replayed.
*/
SpinLockAcquire(&xlogctl->info_lck);
xlogctl->recoveryLastRecPtr = EndRecPtr;
SpinLockRelease(&xlogctl->info_lck); LastRec = ReadRecPtr; record = ReadRecord(NULL, LOG, false);
} while (record != NULL && recoveryContinue); /*
* end of main redo apply loop
*/ ereport(LOG,
(errmsg("redo done at %X/%X",
ReadRecPtr.xlogid, ReadRecPtr.xrecoff))); xtime = GetLatestXTime();
if (xtime)
ereport(LOG,
(errmsg("last completed transaction was at log time %s",
timestamptz_to_str(xtime))));
InRedo = false;
}
else
{
/* there are no WAL records following the checkpoint */
ereport(LOG,
(errmsg("redo is not required")));
}
} …
}
经过分析可以发现,在Startup_XLOG函数中,通过 RmgrTable[record->xl_rmid].rm_redo(EndRecPtr, record);
调用了各个redo函数,其中包括: xlog_redo:
/*
* XLOG resource manager's routines
*
* Definitions of info values are in include/catalog/pg_control.h, though
* not all record types are related to control file updates.
*/
void
xlog_redo(XLogRecPtr lsn, XLogRecord *record)
{
…
if (info == XLOG_NEXTOID)
{
…
}
…
else if (info == XLOG_PARAMETER_CHANGE)
{
xl_parameter_change xlrec; /* Update our copy of the parameters in pg_control */
memcpy(&xlrec, XLogRecGetData(record), sizeof(xl_parameter_change)); LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
ControlFile->MaxConnections = xlrec.MaxConnections;
ControlFile->max_prepared_xacts = xlrec.max_prepared_xacts;
ControlFile->max_locks_per_xact = xlrec.max_locks_per_xact;
ControlFile->wal_level = xlrec.wal_level;
…
UpdateControlFile();
LWLockRelease(ControlFileLock); /* Check to see if any changes to max_connections give problems */
CheckRequiredParameterValues();
}
}
看这段话:是说找到checkpoint 后面开始的第一条记录的位置。
/*
* Find the first record that logically follows the checkpoint --- it
* might physically precede it, though.
*/
初步学习pg_control文件之十四的更多相关文章
- 初步学习pg_control文件之十五
接前文 初步学习pg_control文件之十四 再看如下这个: int MaxConnections; 应该说,它是一个参考值,在global.c中有如下定义 /* * Primary determ ...
- 初步学习pg_control文件之十二
接前问,初步学习pg_control文件之十一,再来看下面这个 XLogRecPtr minRecoveryPoint; 看其注释: * minRecoveryPoint is updated to ...
- 初步学习pg_control文件之十
接前文 初步学习pg_control文件之九 看下面这个 XLogRecPtr checkPoint; /* last check point record ptr */ 看看这个pointer究竟保 ...
- 初步学习pg_control文件之十三
接前文,初步学习pg_control文件之十二 看这个: * backupStartPoint is the redo pointer of the backup start checkpoint, ...
- 初步学习pg_control文件之十一
接前文 初步学习pg_control文件之十,再看这个 XLogRecPtr prevCheckPoint; /* previous check point record ptr */ 发生了che ...
- 初步学习pg_control文件之九
接前文,初步学习pg_control文件之八 来看这个: pg_time_t time; /* time stamp of last pg_control update */ 当初初始化的时候,是这样 ...
- 初步学习pg_control文件之八
接前文 初步学习pg_control文件之七 继续 看:catalog_version_no 代码如下: static void WriteControlFile(void) { ... /* * ...
- 初步学习pg_control文件之七
接前文 初步学习pg_control文件之六 看 pg_control_version 以PostgreSQL9.1.1为了,其HISTORY文件中有如下的内容: Release Release ...
- 初步学习pg_control文件之六
接前文:初步学习pg_control文件之五 ,DB_IN_ARCHIVE_RECOVERY何时出现? 看代码:如果recovery.conf文件存在,则返回 InArchiveRecovery = ...
随机推荐
- IIS环境搭建
IIS环境搭建 IIS环境搭建首先是建立在一个干净的.无毒的系统上,再进行相应操作.本文用到的是windows 2003的镜像文件,有条件的用户也可以使用windows的系统安装光盘. 下面进入操作步 ...
- oozie调用java实例------shell action
Oozie提供了一个方便的方式来运行任何命令.这可能是Unix命令,Perl或Python脚本,甚至java程序都可以通过Unix shell调用.shell命令运行在任意的Hadoop集群节点上,并 ...
- bzoj 2179 FFT
求两个高精度的乘法. 根据高位低位,填入多项式的系数,求两个卷积,然后进位操作.
- 使用metasploit自带模块进行端口扫描
搜索模块: 选择查看: 设置&扫描:
- java 注解annotation的使用,以及反射如何获取注解
一.注解基本知识 1.元注解 元注解是指注解的注解.包括 @Retention @Target @Document @Inherited四种. 1. Annotation型定义为@interfac ...
- Entity Framework 四
实体框架支持三种类型的查询:1)LINQ to Entities,2)Entity SQL,3)Native SQL LINQ方法语法: LINQ查询语法: 实体SQL: 这种可以简单的了解,不必深入 ...
- DB2表空间重定向恢复数据库实战
DB2的备份恢复有点坑,当源系统和目标系统的路径设置不同时,要手动进行重定向恢复,本文是我一次实战操作之后总结的过程,仅供参考. 一.发出重定向恢复命令 DB2 RESTORE DB TO " ...
- Xadmin使用二
1:修改site-title和site-footer,增加菜单折叠效果 在adminx.py中增加下面代码: class GlobalSetting(object): # 设置Title site_t ...
- 如何安全地跨窗体调用Timer控件 从一个窗体调用控制另外一个窗体的控件
具体的情况是Form1中有一个Timer2时钟,Timer2时钟事件弹出Warning窗体,点击Warning窗体上面的按钮,重新激活一下Form1中的Timer2.从而实现了从一个窗体调用另外一个窗 ...
- Eclipse中各种文件的注释与取消注释的快捷键
Eclipse中各种文件的注释与取消注释的快捷键 Java文件: 注释和取消注释的快捷键都是:CTRL + / 或 Shift+Ctrl+C JS文件: 注释和取消注释的快捷键都是:CTRL + / ...