openGauss源码解析(212)

openGauss源码解析:备份恢复机制(3)

10.2.3 gs_probackup备份恢复流程

gs_probackup工具在备份之前需要先进行备份目录初始化,然后进行数据库实例的全量备份,在全量备份的基础上才能进行增量备份。类似地,增量恢复也必须以某个全量备份为基础进行恢复。gs_probackup除了支持本地备份外,也支持通过SSH进行远程备份。下面是几个主要的步骤。

(1) 初始化备份目录。在指定的目录下创建backups/和wal/子目录,分别用于存放备份文件和WAL文件,代码如下:

gs_probackup init -B backup_dir

(2) 初始化一个数据库实例的备份,代码如下:

gs_probackup add-instance -B backup_dir -D data_dir --instance instance_name [remote_options]

(3) 创建指定实例的备份。在进行增量备份之前,必须至少创建一次全量备份。全量还是增量由-b backup_mode参数控制,FULL表示创建全量备份,PTRACK表示创建PTRACK增量备份,代码如下:

gs_probackup backup -B backup_dir --instance instance_name -b backup_mode

(4) 从指定实例的备份中恢复数据,代码如下:

gs_probackup restore -B backup_dir --instance instance_name -i backup_id

如果进行远程备份和恢复,需要初始化备份目录和初始化一个数据库实例的备份,第一步、第二步和本地备份恢复是相同的,执行上文中的(1)和(2)即可。但第三步和第四步需要使用SSH的远程连接信息进行备份和恢复,步骤如下所示。

(1) 远程备份,代码如下:

gs_probackup backup -B backup_dir -b FULL --stream --instance=instance_name --remote-user=remote_user --remote-host=ip --remote-port=remote_port -d db -p port -U user

(2) 远程恢复,代码如下:

gs_probackup restore -B backup_dir --instance=instance_name --remote-user=remote_user --remote-host=ip --remote-port=remote_port --incremental-mode=checksum

下面介绍每个处理函数的详细实现。

(1) init命令的处理函数是do_init,在do_init函数中。

① 首先检查命令行输入的备份路径backup_dir是否为空目录,要求必须为空目录。如果backup_dir不存在,则创建。

② 在backup_dir下创建backups子目录,创建wal子目录。

(2) add-instance的处理函数为do_add_instance,在do_add_instance处理函数中。

① 创建backup_dir/backups/instance_name子目录,创建backup_dir/wal/instance_name子目录。

② 获取实例备份参数信息,包括system_identifier,xlog_seg_size,remote.host,remote.proto,remote.port,remote.path,remote.user,remote.ssh_options,remote.ssh_config等,通过调用函数do_set_config把这些实例备份信息写到backup_path/backups/instance_name/pg_probackup.conf配置文件中。

(3) backup的处理函数为do_backup,do_backup根据参数backup_mode是FULL还是PTRACK进行全量或者增量备份。全量备份和增量备份基本流程是一样的,唯一的区别是全量备份拷贝全部数据文件,增量备份只拷贝自上次备份以来的脏数据页。函数的处理流程如下。

① 调用pgNodeInit初始化备份数据库服务器节点的信息。

② 设置备份状态为BACKUP_STATUS_RUNNING和其他备份元数据,包括备份时间、当前版本、压缩算法、压缩级别和外部目录地址。

③ 调用pgBackupCreateDir创建备份路径,备份路径由pgBackupGetPath构造,路径为backup_dir/backups/instance_name/base36enc(backup->start_time),同时创建外部目录的备份地址,地址为backup_dir/backups/instance_name/ extern_direc。

④ 备份元数据写入到backup.control控制文件中。

⑤ 调用pgdata_basic_setup创建到数据库服务器的连接,检查校验备份工具的block_size、wal_block_size,checksum_version等和数据库服务器的版本是兼容的。调用check_system_identifiers校验系统标识符system_identifier是一致的。检查数据库服务器的ptrack版本是兼容的,并且开关是打开的。

⑥ 调用add_note把备份描述信息添加到备份元数据中。

⑦ 调用do_backup_instance进行数据库实例数据备份。

⑧ 更新备份元数据中的备份结束时间,备份状态为BACKUP_STATUS_DONE。更新备份的留存策略ttl或者expire_time。

⑨ 如果需要校验备份,则调用pgBackupValidate对备份数据进行校验。

⑩ 最后如果需要删除过期的备份或者合并备份,则调用do_retention把过期的备份删除。

(4) restore的处理函数为do_restore_or_validate,函数的处理流程如下。

① 检查如果data目录不为空,看是否为增量恢复,并且当前的增量和路径中存在的数据是否兼容。首先检查两者的system_identifier标识符是否一致,如果不一致,则恢复失败。然后检查目录中是否有备份标签文件,如果存在,则恢复失败。

② 调用catalog_get_backup_list获取实例的所有备份。在catalog_get_backup_list函数中,遍历实例所有的backup.control文件,获取所有backup_id,并且根据backup_id排序。所有增量备份和他们的祖先连接起来,备份元数据有一个parent_backup,指向的就是父备份ID。

/* Link incremental backups with their ancestors.*/

for (i = 0; i < parray_num(backups); i++)

{

pgBackup *curr = parray_get(backups, i);

pgBackup **ancestor;

pgBackup key;

if (curr->backup_mode == BACKUP_MODE_FULL)

continue;

key.start_time = curr->parent_backup;

ancestor = (pgBackup **) parray_bsearch(backups, &key,

pgBackupCompareIdDesc);

if (ancestor)

curr->parent_backup_link = *ancestor;

}

③ 在备份列表中,查找满足恢复条件的备份。如果指定了target_backup_id则根据backup_id进行匹配。如果指定了pgRecoveryTarget,则根据pgRecoveryTarget进行匹配,判断函数为satisfy_recovery_target。

④ 如果找到的备份是全量备份,那么当前backup_id就是满足要求的。如果找到的备份是增量备份,需要遍历整个增量备份链表查找之前所有备份都是正常的。

⑤ 检查表空间映射是正常的。

⑥ 如果是INCR_LSN恢复,确定恢复链中的恢复位置。

⑦ 如果恢复前需要验证文件正确性,则调用pgBackupValidate和validate_wal验证数据文件和日志文件正确性。

⑧ 调用restore_chain根据备份链进行恢复。

⑨ 根据传入的恢复参数调用create_recovery_conf创建recovery.conf恢复文件。整个恢复结束。

其他的一些流程处理如下。

(5) help的help_pg_probackup和help_command,这两个函数的处理都在help.cpp中。

① help_pg_probackup命令没有输入参数,就是打印整个工具的命令行使用帮助信息。

② help_command(char *command)有一个输入参数command,根据command参数指定的子命令分别调用相应子命令的帮助处理函数。

(6) del-instance删除实例的处理函数为do_delete_instance,在do_delete_instance处理函数中。

① 调用catalog_get_backup_list获取实例。backup_dir/backups/instance_name子目录下的所有数据备份。遍历删除这些数据备份。

② 删除backup_dir/wal/instance_name子目录下的所有WAL日志文件。

③ 删除实例备份配置文件backup_dir/backups/instance_name/pg_probackup.conf。

④ 删除实例backup_dir/backups/instance_name子目录本身,删除backup_path/wal/instance_name子目录本身。

(7) 设置实例备份配置文件backup_dir/backups/instance_name/pg_probackup.conf的处理函数为do_set_config,do_set_config的根据解析的命令行参数,以name = value的形式把新值设置到配置文件中。pg_probackup.conf是文本文件,为了避免文件写坏,先把内容写到一个pg_probackup.conf.tmp临时文件,最后再重命名为正式文件。
(8) 显示实例备份配置文件backup_dir/backups/instance_name/pg_probackup.conf的处理函数为do_show_config,do_show_config函数根据命令行要求是json还是普通格式把参数以name=value的方式显示出来。
posted @ 2024-05-07 09:33  openGauss-bot  阅读(22)  评论(0编辑  收藏  举报