# 大云海山数据库(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 重放

- 检查恢复是否正在进行中
首先调用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.")));
- 检查是否触发了提升(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()")));
- 恢复(继续)WAL 重放
如果上述两个检查都通过,函数会调用SetRecoveryPause(false)来设置恢复进程不再暂停,即恢复或继续WAL的重放
SetRecoveryPause(false);
- 返回
函数通过PG_RETURN_VOID(); 返回,表示没有返回值
PG_RETURN_VOID(); }
函数调用栈

时间点恢复——pg_is_wal_replay_paused
- 检查恢复是否正在进行中
函数首先调用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.")));
- 返回结果
函数通过PG_RETURN_BOOL返回一个布尔值,表示WAL重放是否暂停。如果WAL重放暂停了,则返回true;否则,返回false
PG_RETURN_BOOL(GetRecoveryPauseState() != RECOVERY_NOT_PAUSED);
函数调用栈

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

- 检查恢复是否正在进行中
首先调用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.")));
- 检查是否触发了提升(
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()")));
- 设置恢复暂停状态
如果上述两个检查都通过,函数会调用SetRecoveryPause(true)来设置恢复暂停状态。这意味着后续的WAL重放将被暂停,直到恢复过程被明确恢复
SetRecoveryPause(true)
- 唤醒恢复进程
函数通过调用WakeupRecovery()来唤醒恢复进程。这是必要的,因为恢复进程可能在等待新的WAL数据或处于某种休眠状态。唤醒恢复进程可以确保它尽快处理暂停请求
WakeupRecovery();
- 返回
最后,函数通过PG_RETURN_VOID(); 返回,表示没有返回值
PG_RETURN_VOID();
函数调用栈

作者介绍
周雨慧 中移(苏州)软件技术有限公司 数据库内核开发工程师
PG_RETURN_VOID();
函数调用栈
[外链图片转存中…(img-eSnOughD-1731654888416)]
作者介绍
周雨慧 中移(苏州)软件技术有限公司 数据库内核开发工程师
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




