海山数据库(He3DB)源码详解:海山MySQL redo日志-写入过程

56 阅读5分钟

大云海山数据库(He3DB)源码详解:主备复制pg_wal_replay_resume、pg_is_wal_replay_paused

背景

He3DB 采用了先进的存储引擎和查询优化技术,能够快速处理大量数据和复杂查询。无论是 OLTP(在线事务处理)还是 OLAP(在线分析处理)场景,都能提供出色的性能表现。He3DB 具备完善的数据备份和恢复机制,能够在系统故障或数据损坏时快速恢复数据,确保业务的连续性。He3DB 支持水平扩展和垂直扩展,可以轻松应对不断增长的数据需求。He3DB 提供了严格的访问控制和数据加密功能,确保数据的安全性和隐私性。

主备复制

时间点恢复——pg_wal_replay_resume

pg_wal_replay_resume函数在数据库处于恢复过程且未触发备用服务器提升操作时,恢复或继续 WAL 重放

image.png

  1. 检查恢复是否正在进行中 首先调用RecoveryInProgress()函数来确认当前数据库是否处于恢复模式。如果数据库不是在恢复模式下运行(即,它是一个正常运行的主数据库或已经完成了恢复过程的备用数据库),则函数会抛出一个错误 错误信息会明确指出“recovery is not in progress”,并给出提示,说明这些恢复控制函数只能在恢复过程中执行
Datum
pg_wal_replay_resume(PG_FUNCTION_ARGS)
{
	if (!RecoveryInProgress())
		ereport(ERROR,
				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
				 errmsg("recovery is not in progress"),
				 errhint("Recovery control functions can only be executed during recovery.")));
  1. 检查是否触发了提升(Promote)操作 函数检查是否触发了将备用数据库提升为主数据库的操作。这是通过调用PromoteIsTriggered()函数来完成的 如果已经触发了提升操作,函数会抛出一个错误,指出“standby promotion is ongoing”。同时,给出提示,说明在提升操作被触发后,pg_wal_replay_resume() 函数不能被执行
if (PromoteIsTriggered())
		ereport(ERROR,
				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
				 errmsg("standby promotion is ongoing"),
				 errhint("%s cannot be executed after promotion is triggered.",
						 "pg_wal_replay_resume()")));
  1. 恢复(继续)WAL 重放 如果上述两个检查都通过,函数会调用SetRecoveryPause(false)来设置恢复进程不再暂停,即恢复或继续WAL的重放
SetRecoveryPause(false);
  1. 返回 函数通过PG_RETURN_VOID(); 返回,表示没有返回值
	PG_RETURN_VOID();
}

函数调用栈

image-1.png

时间点恢复——pg_is_wal_replay_paused

  1. 检查恢复是否正在进行中 函数首先调用RecoveryInProgress()函数来确认当前数据库是否处于恢复模式。这是执行任何恢复控制函数的前提条件 如果数据库不是在恢复模式下运行(即,它是一个正常运行的主数据库或已经完成了恢复过程的备用数据库),则函数会抛出一个错误 错误信息会明确指出“recovery is not in progress”,并给出提示,说明这些恢复控制函数只能在恢复过程中执行
Datum
pg_is_wal_replay_paused(PG_FUNCTION_ARGS)
{
	if (!RecoveryInProgress())
		ereport(ERROR,
				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
				 errmsg("recovery is not in progress"),
				 errhint("Recovery control functions can only be executed during recovery.")));
  1. 返回结果 函数通过PG_RETURN_BOOL返回一个布尔值,表示WAL重放是否暂停。如果WAL重放暂停了,则返回true;否则,返回false
	PG_RETURN_BOOL(GetRecoveryPauseState() != RECOVERY_NOT_PAUSED);

函数调用栈

image-2.png

时间点恢复——pg_wal_replay_pause

pg_wal_replay_pause在数据库恢复过程中暂停 WAL 回放,如果数据库未处于恢复状态或备用服务器晋升正在进行中则报错,设置恢复暂停标志并唤醒恢复进程后返回。

image-3.png

  1. 检查恢复是否正在进行中 首先调用RecoveryInProgress()函数来检查当前数据库是否处于恢复模式。如果数据库不是在恢复模式下运行(即,它是一个正常运行的主数据库或已经完成了恢复过程的备用数据库),则函数会抛出一个错误 错误信息会明确指出“recovery is not in progress”,并给出提示,说明这些恢复控制函数只能在恢复过程中执行
	if (!RecoveryInProgress())
		ereport(ERROR,
				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
				 errmsg("recovery is not in progress"),
				 errhint("Recovery control functions can only be executed during recovery.")));
  1. 检查是否触发了提升(Promote)操作 接下来,函数检查是否触发了将备用数据库提升(Promote)为主数据库的操作。这是通过调用PromoteIsTriggered()函数来完成的 如果已经触发了提升操作,函数会抛出一个错误,指出“standby promotion is ongoing”。同时,给出提示,说明在提升操作被触发后,pg_wal_replay_pause()函数不能被执行
if (PromoteIsTriggered())
		ereport(ERROR,
				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
				 errmsg("standby promotion is ongoing"),
				 errhint("%s cannot be executed after promotion is triggered.",
						 "pg_wal_replay_pause()")));
  1. 设置恢复暂停状态 如果上述两个检查都通过,函数会调用SetRecoveryPause(true)来设置恢复暂停状态。这意味着后续的WAL重放将被暂停,直到恢复过程被明确恢复
SetRecoveryPause(true)
  1. 唤醒恢复进程 函数通过调用WakeupRecovery()来唤醒恢复进程。这是必要的,因为恢复进程可能在等待新的WAL数据或处于某种休眠状态。唤醒恢复进程可以确保它尽快处理暂停请求
WakeupRecovery();
  1. 返回 最后,函数通过PG_RETURN_VOID(); 返回,表示没有返回值
PG_RETURN_VOID();

函数调用栈

image-4.png

作者介绍

周雨慧 中移(苏州)软件技术有限公司 数据库内核开发工程师