PostgreSQL状态变迁

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启动以及关闭或运行过程中的状态包括以上七种。在pg_controldata获取的内容Database cluster state一栏显示的是DB的状态。其中:

西和网站制作公司哪家好,找创新互联!从网页设计、网站建设、微信开发、APP开发、成都响应式网站建设公司等网站项目制作,到程序开发,运营维护。创新互联公司2013年成立到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选创新互联。

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

新闻标题:PostgreSQL状态变迁
网站地址:https://www.cdcxhl.com/article6/jsgdig.html

成都网站建设公司_创新互联,为您提供标签优化定制网站响应式网站企业网站制作虚拟主机静态网站

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

h5响应式网站建设