您好,登錄后才能下訂單哦!
typedef enum DBState { DB_STARTUP = 0, DB_SHUTDOWNED, DB_SHUTDOWNED_IN_RECOVERY, DB_SHUTDOWNING, DB_IN_CRASH_RECOVERY, DB_IN_ARCHIVE_RECOVERY, DB_IN_PRODUCTION } DBState;
PostgreSQL啟動(dòng)以及關(guān)閉或運(yùn)行過程中的狀態(tài)包括以上七種。在pg_controldata獲取的內(nèi)容Database cluster state一欄顯示的是DB的狀態(tài)。其中:
DB_STARTUP:表示數(shù)據(jù)庫正在啟動(dòng)狀態(tài),實(shí)際上沒有使用該狀態(tài)。
DB_SHUTDOWNED:數(shù)據(jù)庫實(shí)例正常關(guān)閉(非standby)控制文件寫入的狀態(tài)就是這個(gè)狀態(tài)
DB_SHUTDOWNED_IN_RECOVERY:standby實(shí)例正常關(guān)閉,控制文件寫入的狀態(tài)是這個(gè)狀態(tài)。是由CreateRestartPoint修改該狀態(tài)。
DB_SHUTDOWNING:非standby實(shí)例在關(guān)閉時(shí),做checkpoint:CreateCheckPoint,開始做時(shí)修改為該狀態(tài),做完后修改為DB_SHUTDOWNED狀態(tài)。
DB_IN_CRASH_RECOVERY:實(shí)例異常關(guān)閉,重啟后,恢復(fù)時(shí)需要將實(shí)例先置為該狀態(tài)
DB_IN_ARCHIVE_RECOVERY:standby實(shí)例重啟后置為該狀態(tài)。
DB_IN_PRODUCTION:非standby實(shí)例正常重啟后就是這個(gè)狀態(tài),standby是DB_IN_ARCHIVE_RECOVERY
分析
1、DB_STARTUP
initdb->BootStrapXLOG: memset(ControlFile, 0, sizeof(ControlFileData)); ... ControlFile->state = DB_SHUTDOWNED; ... WriteControlFile();
初始化時(shí),首先將其狀態(tài)初始化為DB_STARTUP,然后立即置成DB_SHUTDOWNED并將其刷寫到磁盤。
2、StartupXLOG
StartupXLOG-> ReadControlFile(); ... readRecoveryCommandFile();-> |--... | for (item = head; item; item = item->next){ | if (strcmp(item->name, "restore_command") == 0){ | ... | }... | else if (strcmp(item->name, "standby_mode") == 0){ | if (!parse_bool(item->value, &StandbyModeRequested)) | }... | } | ... |-- ArchiveRecoveryRequested = true; ... if (ArchiveRecoveryRequested && (ControlFile->minRecoveryPoint != InvalidXLogRecPtr || ControlFile->backupEndRequired || ControlFile->backupEndPoint != InvalidXLogRecPtr || ControlFile->state == DB_SHUTDOWNED)){ InArchiveRecovery = true; if (StandbyModeRequested) StandbyMode = true; } ... record = ReadCheckpointRecord(xlogreader, checkPointLoc, 1, true); ... if (InRecovery){ if (InArchiveRecovery)//何時(shí)? ControlFile->state = DB_IN_ARCHIVE_RECOVERY; else ControlFile->state = DB_IN_CRASH_RECOVERY; ... UpdateControlFile(); replay... } ... LWLockAcquire(ControlFileLock, LW_EXCLUSIVE); ControlFile->state = DB_IN_PRODUCTION; UpdateControlFile(); LWLockRelease(ControlFileLock); ...
只要有recovery.conf文件,ArchiveRecoveryRequested即為TRUE->InArchiveRecovery = true,配置了standby_mode=on,那么StandbyMode=TRUE。這樣standby啟動(dòng)后,ControlFile->state為DB_IN_ARCHIVE_RECOVERY狀態(tài)。
3、checkpoint
CheckpointerMain-> for (;;){ ... if (shutdown_requested){ ShutdownXLOG(0, 0);-> |--if (RecoveryInProgress()){ | CreateRestartPoint(CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_IMMEDIATE); | }else{ | CreateCheckPoint(CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_IMMEDIATE); | } |--... proc_exit(0); } ... if (do_checkpoint){ do_restartpoint = RecoveryInProgress(); ... if (flags & CHECKPOINT_END_OF_RECOVERY)//flags從哪來? do_restartpoint = false; ... if (!do_restartpoint){ CreateCheckPoint(flags); ckpt_performed = true; } else ckpt_performed = CreateRestartPoint(flags); } }
備機(jī)上做checkpoint調(diào)用CreateRestartPoint,主機(jī)做checkpoint調(diào)用CreateCheckPoint
CreateCheckPoint(int flags)-> if (flags & (CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_END_OF_RECOVERY)) shutdown = true; else shutdown = false; ... if (shutdown){ LWLockAcquire(ControlFileLock, LW_EXCLUSIVE); ControlFile->state = DB_SHUTDOWNING; ControlFile->time = (pg_time_t) time(NULL); UpdateControlFile(); LWLockRelease(ControlFileLock); } ... LWLockAcquire(ControlFileLock, LW_EXCLUSIVE); if (shutdown) ControlFile->state = DB_SHUTDOWNED; ... UpdateControlFile(); LWLockRelease(ControlFileLock);
shutdown時(shí),先將狀態(tài)置為DB_SHUTDOWNING,最后將狀態(tài)置為DB_SHUTDOWNED
CreateRestartPoint(int flags)-> LWLockAcquire(CheckpointLock, LW_EXCLUSIVE); SpinLockAcquire(&XLogCtl->info_lck); lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr; lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr; lastCheckPoint = XLogCtl->lastCheckPoint; SpinLockRelease(&XLogCtl->info_lck); if (!RecoveryInProgress()){ LWLockRelease(CheckpointLock); return false; } ... if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) ||lastCheckPoint.redo <= ControlFile->checkPointCopy.redo){ 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){ ... if (flags & CHECKPOINT_IS_SHUTDOWN) ControlFile->state = DB_SHUTDOWNED_IN_RECOVERY; UpdateControlFile(); } LWLockRelease(ControlFileLock); ...
備機(jī)shutdown,將狀態(tài)置為DB_SHUTDOWNED_IN_RECOVERY
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。