初步学习pg_control文件之十四
接前文 初步学习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 + 1] = { {"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. */
转载于:https://www.cnblogs.com/gaojian/p/3232181.html
初步学习pg_control文件之十四相关推荐
- 初步学习pg_control文件之三
接前文,初步学习pg_control文件之二 继续学习: 研究 DBState,先研究 DB_IN_PRODUCTION ,看它如何出现: 它出现在启动Postmaster时运行的函数处: /* * ...
- 初步学习pg_control文件之八
接前文 初步学习pg_control文件之七 继续 看:catalog_version_no 代码如下: static void WriteControlFile(void) {.../** In ...
- 初步学习pg_control文件之六
接前文:初步学习pg_control文件之五 ,DB_IN_ARCHIVE_RECOVERY何时出现? 看代码:如果recovery.conf文件存在,则返回 InArchiveRecovery = ...
- 异常处理程序和软件异常——Windows核心编程学习手札之二十四
异常处理程序和软件异常 --Windows核心编程学习手札之二十四 CPU负责捕捉无效内存访问和用0除一个数值这种错误,并相应引发一个异常作为对错误的反应,CPU引发的异常称为硬件异常(hardwar ...
- 深度学习入门笔记(十四):Softmax
欢迎关注WX公众号:[程序员管小亮] 专栏--深度学习入门笔记 声明 1)该文章整理自网上的大牛和机器学习专家无私奉献的资料,具体引用的资料请看参考文献. 2)本文仅供学术交流,非商用.所以每一部分具 ...
- 深度学习之图像分类(十四)--ShuffleNetV2 网络结构
深度学习之图像分类(十四)ShuffleNetV2 网络结构 目录 深度学习之图像分类(十四)ShuffleNetV2 网络结构 1. 前言 2. Several Practical Guidelin ...
- mysql循环查询一个表中的数据并进行修改_JavaScript学习笔记(二十四)-- MYSQL基础操作...
MYSQL mysql 是一个数据库的名字 和 php 合作的比较好的数据库 之前我们说过一个问题,前端向后端索要数据,后端就是去数据库中查询数据,返回给前端 接下来就聊聊使用 php 操作数据库 M ...
- 深度学习入门(二十四)卷积神经网络——填充和步幅
深度学习入门(二十四)卷积神经网络--填充和步幅 前言 卷积神经网络--填充和步幅 课件 填充 步幅 总结 课本 1 填充 2 步幅 3 小结 前言 核心内容来自博客链接1博客连接2希望大家多多支持作 ...
- Slicer学习笔记(五十四)slicer分割结果3D显示
Slicer学习笔记(五十四)slicer分割结果3D显示 1.Create a segmentation from a labelmap volume and display in 3D 2.Exp ...
最新文章
- 27岁华裔小伙一战成名!搞出美国新冠最准预测模型,一人干翻专业机构,彭博:Superstar...
- android英文文献翻译,有关android技术英文文献翻译
- 当退出python时是否释放全部内存_Python面试题:高级特性考察
- 树形结构:迭代方式遍历树,宽度优先,先序遍历,中序遍历,后序遍历
- 腾讯物联网开发者社区平台Tencent Things Network发布 让IoT应用开发快速安全
- 土木计算机2级,请教各位,我是学土木的,考计算机二级的哪个比较好?
- Diango博客--24.单元测试:测试评论应用
- Django构建简介
- 一套代码在不同的电脑执行快慢_电脑如何选配之硬盘篇
- TSC条码打印机C#例程(tsclib.dll调用)
- 解决Ubuntu 9.04无线网络的不稳定问题-转
- 软件工程经济学作业5-7
- android room 简书,Android Room 的坑
- 家庭养花的资料大全-春雷转
- 安装phpnow服务[Apache_pn]提示失败的解决方法
- 白天 996, 我还能晚上669!
- HTML哪个单位是角度,html5 CSS角度单位:deg、grad、rad、turn --------transform用法
- 修改“IP属地“,我们说不
- Bootstrap3 缩略图( thumbnail )
- 文字格斗游戏2.0(随机数值)
热门文章
- linux下安装mysql5.7.11全纪录_简单几步在Linux环境下安装MySQL5.7(附踩坑记录)
- R语言基础入门,看这里!
- r语言热图对列不进行聚类_R语言:手把手教你画pheatmap热图
- cad2017怎么改变选择方式_诠网科技|企业网络推广方式要怎么选择?
- c语言实现克鲁斯卡尔算法,跪求C语言代码纠错,急~~~,克鲁斯卡尔算法
- h5如何上传文件二进制流_Hadoop如何将TB级大文件的上传性能优化上百倍?
- 光流(二)--光流算法
- java 集合工具类_Java集合中Collections工具类总结
- 适配器模式的原理与实现
- Spark Row对象入门到熟悉