PostgreSQL启动以及关闭或运行过程中的状态包括以上七种。在pg_controldata获取的内容Database cluster state一栏显示的是DB的状态。其中:
成都创新互联公司是一家集网站建设,和政企业网站建设,和政品牌网站建设,网站定制,和政网站建设报价,网络营销,网络优化,和政网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。DB_STARTUP:表示数据库正在启动状态,实际上没有使用该状态。
DB_SHUTDOWNED:数据库实例正常关闭(非standby)控制文件写入的状态就是这个状态
DB_SHUTDOWNED_IN_RECOVERY:standby实例正常关闭,控制文件写入的状态是这个状态。是由CreateRestartPoint修改该状态。
DB_SHUTDOWNING:非standby实例在关闭时,做checkpoint:CreateCheckPoint,开始做时修改为该状态,做完后修改为DB_SHUTDOWNED状态。
DB_IN_CRASH_RECOVERY:实例异常关闭,重启后,恢复时需要将实例先置为该状态
DB_IN_ARCHIVE_RECOVERY:standby实例重启后置为该状态。
DB_IN_PRODUCTION:非standby实例正常重启后就是这个状态,standby是DB_IN_ARCHIVE_RECOVERY
分析
1、DB_STARTUP
initdb->BootStrapXLOG: memset(ControlFile, 0, sizeof(ControlFileData)); ... ControlFile->state = DB_SHUTDOWNED; ... WriteControlFile();初始化时,首先将其状态初始化为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)//何时? 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启动后,ControlFile->state为DB_IN_ARCHIVE_RECOVERY状态。
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); } }备机上做checkpoint调用CreateRestartPoint,主机做checkpoint调用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时,先将状态置为DB_SHUTDOWNING,最后将状态置为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); ...备机shutdown,将状态置为DB_SHUTDOWNED_IN_RECOVERY
另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。