接前文 初步学习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文件之十四相关推荐

  1. 初步学习pg_control文件之三

    接前文,初步学习pg_control文件之二 继续学习: 研究 DBState,先研究 DB_IN_PRODUCTION ,看它如何出现: 它出现在启动Postmaster时运行的函数处: /* * ...

  2. 初步学习pg_control文件之八

    接前文  初步学习pg_control文件之七  继续 看:catalog_version_no 代码如下: static void WriteControlFile(void) {.../** In ...

  3. 初步学习pg_control文件之六

    接前文:初步学习pg_control文件之五 ,DB_IN_ARCHIVE_RECOVERY何时出现? 看代码:如果recovery.conf文件存在,则返回 InArchiveRecovery = ...

  4. 异常处理程序和软件异常——Windows核心编程学习手札之二十四

    异常处理程序和软件异常 --Windows核心编程学习手札之二十四 CPU负责捕捉无效内存访问和用0除一个数值这种错误,并相应引发一个异常作为对错误的反应,CPU引发的异常称为硬件异常(hardwar ...

  5. 深度学习入门笔记(十四):Softmax

    欢迎关注WX公众号:[程序员管小亮] 专栏--深度学习入门笔记 声明 1)该文章整理自网上的大牛和机器学习专家无私奉献的资料,具体引用的资料请看参考文献. 2)本文仅供学术交流,非商用.所以每一部分具 ...

  6. 深度学习之图像分类(十四)--ShuffleNetV2 网络结构

    深度学习之图像分类(十四)ShuffleNetV2 网络结构 目录 深度学习之图像分类(十四)ShuffleNetV2 网络结构 1. 前言 2. Several Practical Guidelin ...

  7. mysql循环查询一个表中的数据并进行修改_JavaScript学习笔记(二十四)-- MYSQL基础操作...

    MYSQL mysql 是一个数据库的名字 和 php 合作的比较好的数据库 之前我们说过一个问题,前端向后端索要数据,后端就是去数据库中查询数据,返回给前端 接下来就聊聊使用 php 操作数据库 M ...

  8. 深度学习入门(二十四)卷积神经网络——填充和步幅

    深度学习入门(二十四)卷积神经网络--填充和步幅 前言 卷积神经网络--填充和步幅 课件 填充 步幅 总结 课本 1 填充 2 步幅 3 小结 前言 核心内容来自博客链接1博客连接2希望大家多多支持作 ...

  9. Slicer学习笔记(五十四)slicer分割结果3D显示

    Slicer学习笔记(五十四)slicer分割结果3D显示 1.Create a segmentation from a labelmap volume and display in 3D 2.Exp ...

最新文章

  1. 27岁华裔小伙一战成名!搞出美国新冠最准预测模型,一人干翻专业机构,彭博:Superstar...
  2. android英文文献翻译,有关android技术英文文献翻译
  3. 当退出python时是否释放全部内存_Python面试题:高级特性考察
  4. 树形结构:迭代方式遍历树,宽度优先,先序遍历,中序遍历,后序遍历
  5. 腾讯物联网开发者社区平台Tencent Things Network发布 让IoT应用开发快速安全
  6. 土木计算机2级,请教各位,我是学土木的,考计算机二级的哪个比较好?
  7. Diango博客--24.单元测试:测试评论应用
  8. Django构建简介
  9. 一套代码在不同的电脑执行快慢_电脑如何选配之硬盘篇
  10. TSC条码打印机C#例程(tsclib.dll调用)
  11. 解决Ubuntu 9.04无线网络的不稳定问题-转
  12. 软件工程经济学作业5-7
  13. android room 简书,Android Room 的坑
  14. 家庭养花的资料大全-春雷转
  15. 安装phpnow服务[Apache_pn]提示失败的解决方法
  16. 白天 996, 我还能晚上669!
  17. HTML哪个单位是角度,html5 CSS角度单位:deg、grad、rad、turn --------transform用法
  18. 修改“IP属地“,我们说不
  19. Bootstrap3 缩略图( thumbnail )
  20. 文字格斗游戏2.0(随机数值)

热门文章

  1. linux下安装mysql5.7.11全纪录_简单几步在Linux环境下安装MySQL5.7(附踩坑记录)
  2. R语言基础入门,看这里!
  3. r语言热图对列不进行聚类_R语言:手把手教你画pheatmap热图
  4. cad2017怎么改变选择方式_诠网科技|企业网络推广方式要怎么选择?
  5. c语言实现克鲁斯卡尔算法,跪求C语言代码纠错,急~~~,克鲁斯卡尔算法
  6. h5如何上传文件二进制流_Hadoop如何将TB级大文件的上传性能优化上百倍?
  7. 光流(二)--光流算法
  8. java 集合工具类_Java集合中Collections工具类总结
  9. 适配器模式的原理与实现
  10. Spark Row对象入门到熟悉