91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PostgreSQL備機checkpoint

發布時間:2020-05-17 10:20:09 來源:網絡 閱讀:745 作者:yzs的專欄 欄目:數據庫

? 數據庫異常關閉時,數據庫關閉時來不及或者沒機會做checkpoint,則需要從上一個一致性檢查的開始恢復。

? ? PostgreSQL備機checkpoint是不能產生checkpoint WAL的,因為如果寫這樣類型的checkpoint的話,就會將接收的WAL打亂,那么日志將混亂,回放會出問題。

? ? 那么問題來了,備機支持checkpoint嗎?他的checkpoint怎么做的?

? ? PostgreSQL為了縮短恢復時間,備機上也支持checkpoint,即CreateRestartPoint。但是其pg_control文件的checkpoint記錄的位點是從主機傳過來WAL里面的checkpoint記錄位置。

1、備機回放

StartupXLOG
    do{
        ...
        RmgrTable[record->xl_rmid].rm_redo(xlogreader);//回放
        ...
        record = ReadRecord(xlogreader, InvalidXLogRecPtr, LOG, false);//讀取一個xlog
    } while (record != NULL);

2、回放函數

void
xlog_redo(XLogReaderState *record)
{
    ...
    else if (info == XLOG_CHECKPOINT_SHUTDOWN){
        ...
        memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
        ...
        RecoveryRestartPoint(&checkPoint);
    }else if (info == XLOG_CHECKPOINT_ONLINE){
        ...
        memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
        ...
        RecoveryRestartPoint(&checkPoint);
    }
    ...
}

3、RecoveryRestartPoint

static void
RecoveryRestartPoint(const CheckPoint *checkPoint)
{
    ...
    SpinLockAcquire(&XLogCtl->info_lck);
    XLogCtl->lastCheckPointRecPtr = ReadRecPtr;//ReadRecPtr為讀取checkpoint記錄后的位置
    XLogCtl->lastCheckPointEndPtr = EndRecPtr;
    XLogCtl->lastCheckPoint = *checkPoint;
    SpinLockRelease(&XLogCtl->info_lck);
}

4、ReadRecPtr賦值

ReadRecord
    for (;;)
    {
        char       *errormsg;

        record = XLogReadRecord(xlogreader, RecPtr, &errormsg);
        ReadRecPtr = xlogreader->ReadRecPtr;
        EndRecPtr = xlogreader->EndRecPtr;
        ...
    }

5、備機createcheckpoint

bool
CreateRestartPoint(int flags)
{

    LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);

    /* Get a local copy of the last safe checkpoint record. */
    SpinLockAcquire(&XLogCtl->info_lck);
    lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;//checkpoint的位置來自XLogCtl->lastCheckPointRecPtr
    lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
    lastCheckPoint = XLogCtl->lastCheckPoint;
    SpinLockRelease(&XLogCtl->info_lck);

    ...

    if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) || lastCheckPoint.redo <= ControlFile->checkPointCopy.redo){
        //回放了最后一個checkpoint記錄后,備機再次手動執行checkpoint命令
        UpdateMinRecoveryPoint(InvalidXLogRecPtr, true);
        if (flags & CHECKPOINT_IS_SHUTDOWN){
            LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
            ControlFile->state = DB_SHUTDOWNED_IN_RECOVERY;
            ControlFile->time = (pg_time_t) time(NULL);
            UpdateControlFile();
            LWLockRelease(ControlFileLock);
        }
        LWLockRelease(CheckpointLock);
        return false;
    }
    ...
    LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
    if (ControlFile->state == DB_IN_ARCHIVE_RECOVERY && ControlFile->checkPointCopy.redo < lastCheckPoint.redo){
        ControlFile->prevCheckPoint = ControlFile->checkPoint;
        ControlFile->checkPoint = lastCheckPointRecPtr;//checkpoint的位置
        ControlFile->checkPointCopy = lastCheckPoint;
        ControlFile->time = (pg_time_t) time(NULL);
        ...
        if (flags & CHECKPOINT_IS_SHUTDOWN)
            ControlFile->state = DB_SHUTDOWNED_IN_RECOVERY;
        UpdateControlFile();
    }
    ...

    return true;
}

6、備機shutdown

void
ShutdownXLOG(int code, Datum arg)
{
    /*
     * Signal walsenders to move to stopping state.
     */
    WalSndInitStopping();

    /*
     * Wait for WAL senders to be in stopping state.  This prevents commands
     * from writing new WAL.
     */
    WalSndWaitStopping();

    if (RecoveryInProgress())//備機寫checkpoint
        CreateRestartPoint(CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_IMMEDIATE);
    else
    {
        /*
         * If archiving is enabled, rotate the last XLOG file so that all the
         * remaining records are archived (postmaster wakes up the archiver
         * process one more time at the end of shutdown). The checkpoint
         * record will go to the next XLOG file and won't be archived (yet).
         */
        if (XLogArchivingActive() && XLogArchiveCommandSet())
            RequestXLogSwitch(false);

        CreateCheckPoint(CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_IMMEDIATE);
    }
    ShutdownCLOG();
    ShutdownCommitTs();
    ShutdownSUBTRANS();
    ShutdownMultiXact();
}

7、總結

PostgreSQL備庫也可以寫檢查點,目的是避免每次重啟備庫都需要從上一個檢查點(由主庫產生,在WAL中回放出來的)APPLY后面所有的WAL。但是他記錄的checkpoint位點是從主庫傳過來的。這樣的話就有問題了,如果主機很長時間都沒有做checkpoint了,備機即使正常關閉,重啟時,也會從上一個checkpoint開始恢復,這樣也會恢復很長時間;并且多次重啟也需要從上一次checkpoint開始重復恢復。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

郧西县| 嘉祥县| 丽江市| 泰顺县| 中卫市| 屏东市| 高雄县| 云林县| 武宣县| 云龙县| 古蔺县| 双桥区| 偃师市| 马鞍山市| 阿荣旗| 墨竹工卡县| 青铜峡市| 德安县| 酒泉市| 上犹县| 青岛市| 宝兴县| 山西省| 滕州市| 河源市| 邯郸县| 金湖县| 平邑县| 乐山市| 资源县| 北流市| 高密市| 广南县| 大新县| 广东省| 永福县| 监利县| 棋牌| 绥江县| 鄢陵县| 广西|