2022年4月发布的Percona Backup for MongoDB(PBM)的1.7.0版本开始支持物理备份。
pbm的物理备份是基于backupCursors feature of PSMDB实现的,这也即意味着要想使用物理备份,你必须使用Percona Server for Mongodb。
备份
在每个复制集上,pbm使用$backupCursor来遍历需要拷贝归档备份的文件列表。获得列表后,下一步是确保集群一致。每个复制集发布一个观察到的最新操作的集群时间。备份leader选出最近的一个。这就是备份元数据中的备份时间戳(last_write_ts)。在备份时间上达成一致后,pbm-agent在每个集群节点上打开$backupCursorExtend。这个游标只有在该节点到达给定时间戳才会返回结果。因此,返回的日志列表(hournals)会包含一致的备份时间戳。至此,我们就有了要备份的文件列表。在每个节点拷贝到存储中,保存元数据,关闭游标,这就是备份的过程。如果想了解备份游标,可以参看https://www.percona.com/blog/2021/06/07/experimental-feature-backupcursorextend-in-percona-server-for-mongodb/
当然,pbm内部做的了更多的工作,选择恰当的节点做备份,在集群之间操作的协调,记录日志,错误处理等等。
备份的恢复时间戳
还原任何一个备份,pbm会将集群返回到一个特定的时间点。这里讨论的时间,不是墙上时钟,而是mongodb集群的逻辑时钟。因此,基于时间点的点,在所有节点上都是一致的。逻辑备份或物理备份,时间被记录在pbm status输出的pbm list的conplete部分。比如:
2022-04-19T15:36:14Z 22.29GB <physical> [complete: 2022-04-19T15:36:16]
2022-04-19T14:48:40Z 10.03GB <logical> [complete: 2022-04-19T14:58:38]
这个时间不是备份结束的时间,而是集群状态被捕获的时间。在pbm的逻辑备份中,恢复时间戳接近于备份完成时间。为了定义这些,pbm需要等待,直到所有节点上的快照结束。然后,从备份开始时间开始,启动捕获oplog。
保持游标打开,可以确保在备份期间检查点数据不会变化。这样pbm可以提前定义正确的完成时间。
还原
恢复需要考虑一些点。
首先,备份中的文件可能包含一些目标时间(commonBackupTimestamp)之外的文件。要处理这个问题,pbm使用复制子系统的一个特殊的函数,设置oplog被还原的限制,通过设置oplogTruncateAfterPoint的值,该变量在local db的replset.oplogTruncateAfterPoint集合中。
除了oplogTruncateAfterPoint之外,数据库需要做一些其他的修改,在启动前清理干净。这需要多次以standalone的模式重启psmdb。
这反过来又给pbm操作带来了一些麻烦。为了在所有代理之间通信和协调其工作,PBM依赖于PSMDB本身。但是一旦集群被关闭,PBM必须切换到通过存储进行通信。此外,在standalone运行期间,PBM无法将其日志存储在数据库中。因此,在还原期间的某个时间点,pbm-agent日志仅在agent的stderr中可用。而且pbm日志将无法访问它们。我们计划通过物理备份GA来解决这个问题。
此外,我们必须决定副本集中的恢复策略。一种方法是恢复一个节点,然后删除其余节点上的所有数据,让PSMDB复制完成这项工作。尽管它更容易一些,但这意味着在InitialSync完成之前,集群将几乎没有用处。此外,此阶段的逻辑复制几乎忽略了物理还原为表带来的所有速度优势(稍后)。因此,我们着手恢复副本集中的每个节点。并确保在集群启动后,没有节点会发现任何差异并且不会启动ReSync。
与PBM的逻辑备份一样,当前可以将物理一次恢复到具有相同拓扑的集群,这意味着备份中的副本集名称应该与目标集群匹配。虽然从下一个 PBM 版本开始的逻辑备份不会成为问题。稍后此功能也将扩展到物理备份。除此之外,集群中的副本集数量可能会多于备份中的副本集,反之亦然。这意味着应该恢复备份中的所有数据。
性能评审
使用以下环境:
·三节点的复制集。每个节点都是mongod+pbm-agent,16GB,8vCPU
·存储:nyc3.digitaloceanspaces.com
·数据量:随机产生的,大小1mb的文档
一般来说,逻辑备份对小型数据库(几百兆)更有利。由于在这样的规模上,物理文件带来的数据之上的额外开销仍然会产生影响。基本上,在逻辑备份期间仅读取/写入用户数据意味着需要通过网络传输的数据更少。但是随着数据库的增长,逻辑读取(select)和写入(insert)的开销成为逻辑备份的瓶颈。至于物理备份,速度几乎总是只受限于进出远程存储的网络带宽。在我们的测试中,物理备份的恢复时间与数据集大小呈线性相关,而逻辑恢复时间呈非线性增长。拥有的数据越多,replay所有数据和重建索引所需的时间就越长。例如,对于600GB 数据集,物理还原所用时间比逻辑还原少 5 倍。
但在较小的数据库大小上,差异可以忽略不计——几分钟。因此,逻辑备份的主要好处不仅仅在于性能。这是灵活性。逻辑备份允许部分备份/恢复数据库(在 PBM 的路线图上)。可以选择要使用的特定数据库和/或集合。由于物理备份直接与数据库存储引擎文件一起使用,它们在一个全有或全无的框架中运行。
练习
pbm配置
从1.7.0版本开始,运行首先将pbm-agent进程的用户必须要能读写psmdb的数据目录。从1.7.0版本开始,将用户从pbm换成了mongod。
此外,要记住,要想使用物理备份,psmdb的版本必须是 4.2.15-16、4.4.6-8或者更高的版本。从这些版本才引入热备份和备份游标。
创建备份
新版本的pbm,用户可以指定是物理备份还是逻辑备份。缺省是逻辑备份:
> pbm backup
Starting backup '2022-04-20T11:12:53Z'....
Backup '2022-04-20T11:12:53Z' to remote store 's3://https://storage.googleapis.com/pbm-bucket' has started
> pbm backup -t physical
Starting backup '2022-04-20T12:34:06Z'....
Backup '2022-04-20T12:34:06Z' to remote store 's3://https://storage.googleapis.com/pbm-bucket' has started
> pbm status -s cluster -s backups
Cluster:
========
rs0:
- rs0/mongo1.perconatest.com:27017: pbm-agent v1.7.0 OK
- rs0/mongo2.perconatest.com:27017: pbm-agent v1.7.0 OK
- rs0/mongo3.perconatest.com:27017: pbm-agent v1.7.0 OK
Backups:
========
S3 us-east-1 s3://https://storage.googleapis.com/pbm-bucket
Snapshots:
2022-04-20T12:34:06Z 797.38KB <physical> [complete: 2022-04-20T12:34:09]
2022-04-20T11:12:53Z 13.66KB <logical> [complete: 2022-04-20T11:12:58]
基于时间点恢复
当前仅支持逻辑备份的时间点恢复。这意味着pbm-agent需要一个逻辑备份快照才能开始定期保存oplog的连续切片。仍然可以在启用PITR时进行物理备份,它不会破坏或更改oplog保存过程。
到特定时间点的恢复过程还将使用相应的逻辑备份快照和oplog切片,这些切片将在备份之上重放。
检查日志
在物理备份期间,pbm日志可以通过pbm logs命令查看
> pbm logs -e backup/2022-04-20T12:34:06Z
2022-04-20T12:34:07Z I [rs0/mongo2.perconatest.com:27017] [backup/2022-04-20T12:34:06Z] backup started
2022-04-20T12:34:12Z I [rs0/mongo2.perconatest.com:27017] [backup/2022-04-20T12:34:06Z] uploading files
2022-04-20T12:34:54Z I [rs0/mongo2.perconatest.com:27017] [backup/2022-04-20T12:34:06Z] uploading done
2022-04-20T12:34:56Z I [rs0/mongo2.perconatest.com:27017] [backup/2022-04-20T12:34:06Z] backup finished
至于restore,pbm logs命令不提供有关从物理备份restore的信息。这是由restore过程的特殊性引起的,将在即将推出的PBM版本中得到改进。但是,pbm-agent 仍然在本地保存日志,因此可以检查有关每个节点上的还原过程的信息:
> sudo journalctl -u pbm-agent.service | grep restore
pbm-agent[12560]: 2022-04-20T19:37:56.000+0000 I [restore/2022-04-20T12:34:06Z] restore started
.......
pbm-agent[12560]: 2022-04-20T19:38:22.000+0000 I [restore/2022-04-20T12:34:06Z] copying backup data
.......
pbm-agent[12560]: 2022-04-20T19:38:39.000+0000 I [restore/2022-04-20T12:34:06Z] preparing data
.......
pbm-agent[12560]: 2022-04-20T19:39:12.000+0000 I [restore/2022-04-20T12:34:06Z] restore finished <nil>
pbm-agent[12560]: 2022-04-20T19:39:12.000+0000 I [restore/2022-04-20T12:34:06Z] restore finished successfully
从备份中还原
从物理备份还原过程类似于逻辑备份,但在PBM完成还原后需要几个额外的步骤。
> pbm restore 2022-04-20T12:34:06Z
Starting restore from '2022-04-20T12:34:06Z'.....Restore of the snapshot from '2022-04-20T12:34:06Z' has started. Leader: mongo1.perconatest.com:27017/rs0
启动还原过程后,pbm cli会返回leader节点的id,这样可以通过检查pbm-agent leader节点的日志来跟踪还原过程。此外,状态被写入远程存储的元数据文件。状态文件被创建在存储的根路径,格式为:
.pbm.restore/<restore_timestamp>.json
在还原期间也可以用-w标记,这样会阻塞当前的shell会话等待还原过程结束。
> pbm restore 2022-04-20T12:34:06Z -w
Starting restore from '2022-04-20T12:34:06Z'....Started physical restore. Leader: mongo2.perconatest.com:27017/rs0
Waiting to finish...........................Restore successfully finished!
在还原结束后,需要完成以下步骤:
·重启所有的mongod节点
·重启pbm-agent
·运行以下命令,重新同步存储的备份列表
$ pbm config --force-resync