zoukankan      html  css  js  c++  java
  • 初步学习pg_control文件之十

    接前文 初步学习pg_control文件之九 看下面这个

    XLogRecPtr    checkPoint;        /* last check point record ptr */

    看看这个pointer究竟保留了什么

    初始化的时候:

    /*                            
     * This func must be called ONCE on system install.  It creates pg_control                            
     * and the initial XLOG segment.                            
     */                            
    void                            
    BootStrapXLOG(void)                            
    {                            
                                
        …                        
        /*                        
         * Set up information for the initial checkpoint record                        
         *                        
         * The initial checkpoint record is written to the beginning of the WAL                        
         * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not                        
         * used, so that we can use 0/0 to mean "before any valid WAL segment".                        
         */                        
        checkPoint.redo.xlogid = 0;                        
        checkPoint.redo.xrecoff = XLogSegSize + SizeOfXLogLongPHD;                        
                                
        ...                    
        /* Now create pg_control */                        
                                
        memset(ControlFile, 0, sizeof(ControlFileData));                        
                                
        /* Initialize pg_control status fields */                        
        ControlFile->system_identifier = sysidentifier;                        
        ControlFile->state = DB_SHUTDOWNED;                        
        ControlFile->time = checkPoint.time;                        
                                
        ControlFile->checkPoint = checkPoint.redo;                        
        ControlFile->checkPointCopy = checkPoint;                        
                                
        …                        
        WriteControlFile();                        
        …                        
    }                            

    运行的时候:

    /*                                
     * ProcLastRecPtr points to the start of the last XLOG record inserted by the 
     * current backend.  It is updated for all inserts.  XactLastRecEnd points to
     * end+1 of the last record, and is reset when we end a top-level transaction, 
     * or start a new one; so it can be used to tell if the current transaction has 
     * created any XLOG records.                                
     */                                
    static XLogRecPtr ProcLastRecPtr = {0, 0};                                
    …                                
                                    
                                    
    /*                                
     * Insert an XLOG record having the specified RMID and info bytes,                                
     * with the body of the record being the data chunk(s) described by                                
     * the rdata chain (see xlog.h for notes about rdata).                                
     *                                
     * Returns XLOG pointer to end of record (beginning of next record).                                
     * This can be used as LSN for data pages affected by the logged action.                                
     * (LSN is the XLOG point up to which the XLOG must be flushed to disk                                
     * before the data page can be written out.  This implements the basic                                
     * WAL rule "write the log before the data".)                                
     *                                
     * NB: this routine feels free to scribble on the XLogRecData structs,                                
     * though not on the data they reference.  This is OK since the XLogRecData                                
     * structs are always just temporaries in the calling code.                                
     */                                
    XLogRecPtr                                
    XLogInsert(RmgrId rmid, uint8 info, XLogRecData *rdata)                                
    {                                
        …                            
        /*                            
         * In bootstrap mode, we don't actually log anything but XLOG resources;                            
         * return a phony record pointer.                            
         */                            
        if (IsBootstrapProcessingMode() && rmid != RM_XLOG_ID)                            
        {                            
            RecPtr.xlogid = 0;                        
            RecPtr.xrecoff = SizeOfXLogLongPHD;        /* start of 1st chkpt record */                
            return RecPtr;                        
        }                            
                                    
        …                            
        /* Record begin of record in appropriate places */                            
        ProcLastRecPtr = RecPtr;                            
        Insert->PrevRecord = RecPtr;                            
        …                            
    }                                

    关闭的时候:

    /*                                
     * Perform a checkpoint --- either during shutdown, or on-the-fly                                
     *                                
     * flags is a bitwise OR of the following:                                
     *    CHECKPOINT_IS_SHUTDOWN: checkpoint is for database shutdown.                            
     *    CHECKPOINT_END_OF_RECOVERY: checkpoint is for end of WAL recovery.                            
     *    CHECKPOINT_IMMEDIATE: finish the checkpoint ASAP,                            
     *        ignoring checkpoint_completion_target parameter.                        
     *    CHECKPOINT_FORCE: force a checkpoint even if no XLOG activity has occured                            
     *        since the last one (implied by CHECKPOINT_IS_SHUTDOWN or                        
     *        CHECKPOINT_END_OF_RECOVERY).                        
     *                                
     * Note: flags contains other bits, of interest here only for logging purposes.                                
     * In particular note that this routine is synchronous and does not pay                                
     * attention to CHECKPOINT_WAIT.                                
     */                                
    void                                
    CreateCheckPoint(int flags)                                
    {                                
        …                            
        /*                            
         * Update the control file.                            
         */                            
        LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);                            
        if (shutdown)                            
            ControlFile->state = DB_SHUTDOWNED;                        
        ControlFile->prevCheckPoint = ControlFile->checkPoint;                            
        ControlFile->checkPoint = ProcLastRecPtr;                            
        ControlFile->checkPointCopy = checkPoint;                            
        ControlFile->time = (pg_time_t) time(NULL);                            
        /* crash recovery should always recover to the end of WAL */                            
        MemSet(&ControlFile->minRecoveryPoint, 0, sizeof(XLogRecPtr));                            
        UpdateControlFile();                            
        LWLockRelease(ControlFileLock);                            
        …                            
    }                                

    RecoveryMode或者Stand by 的时候:

    /*                                
     * Establish a restartpoint if possible.                                
     *                                
     * This is similar to CreateCheckPoint, but is used during WAL recovery                                
     * to establish a point from which recovery can roll forward without                                
     * replaying the entire recovery log.                                
     *                                
     * Returns true if a new restartpoint was established. We can only establish                                
     * a restartpoint if we have replayed a safe checkpoint record since last                                
     * restartpoint.                                
     */                                
    bool                                
    CreateRestartPoint(int flags)                                
    {                                
        XLogRecPtr        lastCheckPointRecPtr;                    
        CheckPoint    lastCheckPoint;                        
        uint32        _logId;                    
        uint32        _logSeg;                    
        TimestampTz xtime;                            
                                    
        /* use volatile pointer to prevent code rearrangement */                            
        volatile XLogCtlData *xlogctl = XLogCtl;                            
                                    
        /*                            
         * Acquire CheckpointLock to ensure only one restartpoint or checkpoint                            
         * happens at a time.                            
         */                            
        LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);                            
                                    
        /* Get a local copy of the last safe checkpoint record. */                            
        SpinLockAcquire(&xlogctl->info_lck);                            
        lastCheckPointRecPtr = xlogctl->lastCheckPointRecPtr;                            
        memcpy(&lastCheckPoint, &XLogCtl->lastCheckPoint, sizeof(CheckPoint));                            
        SpinLockRelease(&xlogctl->info_lck);                            
                                    
        …                            
        /*                            
         * Update pg_control, using current time.  Check that it still shows                            
         * IN_ARCHIVE_RECOVERY state and an older checkpoint, else do nothing;                            
         * this is a quick hack to make sure nothing really bad happens if somehow                            
         * we get here after the end-of-recovery checkpoint.                            
         */                            
        LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);                            
        if (ControlFile->state == DB_IN_ARCHIVE_RECOVERY &&                            
            XLByteLT(ControlFile->checkPointCopy.redo, lastCheckPoint.redo))                        
        {                            
            ControlFile->prevCheckPoint = ControlFile->checkPoint;                        
            ControlFile->checkPoint = lastCheckPointRecPtr;                        
            ControlFile->checkPointCopy = lastCheckPoint;                        
            ControlFile->time = (pg_time_t) time(NULL);                        
            if (flags & CHECKPOINT_IS_SHUTDOWN)                        
                ControlFile->state = DB_SHUTDOWNED_IN_RECOVERY;                    
            UpdateControlFile();                        
        }                            
        LWLockRelease(ControlFileLock);                            
                                    
        …                            
    }                                

    启动的时候:

    /*                                
     * This must be called ONCE during postmaster or standalone-backend startup                                
     */                                
    void                                
    StartupXLOG(void)                                
    {                                
        …                            
        /*                            
         * Read control file and check XLOG status looks valid.                            
         *                            
         * Note: in most control paths, *ControlFile is already valid and we need                            
         * not do ReadControlFile() here, but might as well do it to be sure.                            
         */                            
        ReadControlFile();                            
                                    
        if (ControlFile->state < DB_SHUTDOWNED ||                            
            ControlFile->state > DB_IN_PRODUCTION ||                        
            !XRecOffIsValid(ControlFile->checkPoint.xrecoff))                        
            ereport(FATAL,                        
                    (errmsg("control file contains invalid data")));                
                                    
        …                            
        if (read_backup_label(&checkPointLoc, &backupEndRequired))                            
        {                            
            …                        
        }                            
        else                            
        {                                                            
            /*                        
             * Get the last valid checkpoint record.  If the latest one according                        
             * to pg_control is broken, try the next-to-last one.                        
             */                        
            checkPointLoc = ControlFile->checkPoint;                        
            RedoStartLSN = ControlFile->checkPointCopy.redo;                        
            record = ReadCheckpointRecord(checkPointLoc, 1);                        
            …                        
        }                            
        …                            
                                    
        /* REDO */                            
        if (InRecovery)                            
        {                            
            …                        
            ControlFile->prevCheckPoint = ControlFile->checkPoint;                        
            ControlFile->checkPoint = checkPointLoc;                        
            ControlFile->checkPointCopy = checkPoint;                        
            …                        
        }                            
                                    
        …                            
    }                                
  • 相关阅读:
    Thinking in Java——笔记(14)
    Thinking in Java——笔记(12)
    frp对http协议应用
    我收藏的连接
    linux下 .netcore 微服务注册到SpringClound
    linux 上使用libxls读和使用xlslib写excel的方法简介
    window下 ANSI Unicode utf8之间相互转换
    提取CString中的汉字及个数
    MFC通过sql访问excel的方法
    linux上安装mysql及简单的使用
  • 原文地址:https://www.cnblogs.com/gaojian/p/3229769.html
Copyright © 2011-2022 走看看