一则 MongoDB 副本集迁移实操案例
文中详细阐述了通过全量 + 增量 Oplog 的迁移方式,完成一套副本集 MongoDB 迁移的全过程。
作者:张然,DBA 数据库技术爱好者~
爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
本文约 900 字,预计阅读需要 3 分钟。
背景介绍
客户要将生产环境上一套副本集架构的 MongoDB 进行迁移,数据量 240GB 左右。经过测试,全量备份耗时 3.5 小时,恢复耗时 4.5小时。
为了减少割接时间,采取全量 + 增量 Oplog 的迁移方式。提前一天进行全备,割接当天只需备份增量的 Oplog 恢复即可,可大幅减少割接窗口。
实操过程
查看 Oplog 信息
检查并评估生产环境 Oplog 的产生信息,以防全量和增量备份期间产生的 Oplog 被覆盖掉。
mongo> db.getReplicationInfo() { "logSizeMB" : 20480, "usedMB" : 20374.38, "timeDiff" : 7074665, "timeDiffHours" : 1965.18, "tFirst" : "Fri Feb 24 2023 18:36:32 GMT+0800 (CST)", "tLast" : "Wed May 17 2023 15:47:37 GMT+0800 (CST)", "now" : "Wed May 17 2023 15:47:43 GMT+0800 (CST)" }
可以看出在 1965.18h 的运行中,产生了 10374.38MB 大小的 Oplog。
全量备份
全量备份并拷贝备份期间产生的 Oplog 用来增量还原。
#!/bin/bash user=admin password=123 host=127.0.0.1 port=27017 outputdir=/data/mongobak_`date +%F` authenticationdatabase=admin start_time=`date +%s` mongodump -u$user --host $host --port $port -p$password --authenticationDatabase $authenticationdatabase --oplog --gzip -o $outputdir stop_time=`date +%s` duration=$((stop_time-start_time)) echo "Spend times: $duration seconds"
全量恢复
利用全备进行数据恢复。
#!/bin/bash start_time=`date +%s` user=admin password=123 host=127.0.0.1 port=27017 authenticationdatabase=admin mongorestore -u$user --host $host --port $port -p$password --authenticationDatabase $authenticationdatabase --oplogReplay --gzip /data/mongobak_2023-07-17 stop_time=`date +%s` duration=$((stop_time-start_time)) echo "Spend times: $duration seconds"
提取增量备份开始的时间点
全备备份出来的 Oplog,可以利用 bsondump
工具将 bson 转换为 json 格式,查看备份时间产生的最后的 Oplog 的时间戳,根据此时间戳来进行增量的 Oplog 备份。
shell> cd /data/ mongobak_2023-07-17 shell> mv oplog.bson oplog.bson.gz shell> gzip -d oplog.bson.gz shell> bsondump --pretty oplog.bson > op.json
查看 op.json
文件,找出增量备份开始的时间点。
"ts": { "$timestamp": { "t": 1686669429, "i": 4 } },
增量备份
备份 Oplog(时间戳大于上一次全备结束时的时间)。
#!/bin/bash user=admin password=123 host=127.0.0.1 port=27017 outputdir=/tmp/oplog_`date +%F` authenticationdatabase=admin start_time=`date +%s` mongodump -u$user --host $host --port $port -p$password --authenticationDatabase $authenticationdatabase -d local -c oplog.rs -q '{"ts":{"$gt": {"$timestamp":{"t":1686669429, "i":4}}}}' -o $outputdir stop_time=`date +%s` duration=$((stop_time-start_time)) echo "Spend times: $duration seconds"
增量恢复
#!/bin/bash user=admin password=123 host=127.0.0.1 port=27017 authenticationdatabase=admin start_time=`date +%s` mongorestore -u$user --host $host --port $port -p$password --authenticationDatabase $authenticationdatabase --oplogReplay /data/oplog_2023-07-17 stop_time=`date +%s` duration=$((stop_time-start_time)) echo "Spend times: $duration seconds"
增量迁移后业务文档数量对比
分别在源端和目标端运行脚本,检查迁移完成后业务数据库下文档数量是否一致。
#!/bin/bash user=admin password=123 host=127.0.0.1 port=27017 authenticationdatabase=admin mpid=`pidof mongod` tooldir=`dirname $(ls -l /proc/$mpid/exe | awk '{print $11}')` database=$(echo "show dbs" | $tooldir/mongo -uadmin --host $host --port $port -p$password --authenticationDatabase $authenticationdatabase --quiet |awk '{print $1}'| sed -E '/^admin$|^config$|^local$/d') for db in $database do collections=$(echo -e "use $db\n show collections" | $tooldir/mongo -u $user --host $host --port $port -p $password $authenticationdatabase --quiet | sed '/switched to db/d') for table in $collections do count=$(echo -e "use $db\n db.$table.count()" | $tooldir/mongo -u $user --host $host --port $port -p $password --authenticationDatabase $authenticationdatabase --quiet | sed '/switched to db/d') echo "$db.$table have $count documents" done done
源端运行结果:
目标端运行结果:
注意事项
- 使用 secondary 备份时,在割接停止业务后,增量备份前,首先检查下从库与主库的延时,确保主从没有延时,防止备份出的数据和主库不一致。
- 如果全备时指定了 gzip,在提取时间戳时要重命名
oplog.bson
为oplog.bson.gz
,然后解压,再利用bsondump
工具解析 bson 文件,否则会报错。
更多技术文章,请访问:https://opensource.actionsky.com/
关于 SQLE
SQLE 是一款全方位的 SQL 质量管理平台,覆盖开发至生产环境的 SQL 审核和管理。支持主流的开源、商业、国产数据库,为开发和运维提供流程自动化能力,提升上线效率,提高数据质量。
SQLE 获取
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
存储成本最高降至原来的5%,PolarDB分布式冷数据归档的业务实践
背景 国内某家兼具投资理财、文化旅游、票务为一体的大型综合型集团公司,2015年成立至今,由于业务高速发展,业务数据增长非常快,数据库系统屡次不堪重负。该公司数据库运维总监介绍,他们目前业务压力比较大的是票务和订单系统,他们的平台每天新增几千万的订单数据,订单的数据来自于各个终端,近几年每个月以300G的数据规模在高速增长,由于数据不断增加,数据库系统迄今为止迭代过了3次。 第一阶段:自建单机MySQL,开始单机MySQL还能满足业务的增长,所有的票务数据都可以放在MySQL数据库里头,但是数据越来越多的时候,我们发现有些单表的数据早已超过2000w,熟悉MySQL的朋友应该知道,表数据超过2000w后,性能变差。数据库变慢,开始我们的业务方还能接受,到后来越来越慢,最终我们只能删数据,删数据后,必须做Optimize Table才会释放空间,每次操作都非常紧张。但后来公司的业务做了升级,要求保留过往所有的票务数据和订单数据,就意味着不能删除老数据了。所以我们在18年年底做了一次数据库系统升级。 第二阶段:利用开源中间件+MySQL我们自建了一套分库分表的数据库,极大缓解了我们业务增长...
- 下一篇
MySQL 与主流分支版本上执行 ANALYZE TABLE 安全么?
有时,需要使用 ANALYZE TABLE 命令手动更新表和索引统计信息。在不进一步探讨这种需求的原因的情况下,我想就与在生产系统上运行命令相关的开销来聊聊这个话题。然而,这里讨论的开销与深入表行收集统计信息的通常成本无关,我们可以通过设置样本页数 来控制。 五年前,我的同事 Sveta 发布了一篇不错的博客文章,介绍了 Percona Server for MySQL 中引入的一项改进,以解一些不必要的等待: 《ANALYZE TABLE 不再是阻塞操作》 从历史上看,在 MySQL 中运行 ANALYZE TABLE 命令的问题是查询需要在表的表定义缓存条目上使用排他锁。这使得查询等待任何长时间运行的查询完成,但也可能触发级联等待其他传入请求。简而言之,ANALYZE 可能会导致高负载生产环境中出现较高得延时。 从那时起,MySQL/Percona/MariaDB 都发生了一些变化,但今天仍然存在许多生产系统会受影响的版本。让我们回顾一下这些年来情况的演变。 MySQL 该问题适用于 MySQL 8.0.23 之前的所有版本。5.7 系列没有任何改进(顺便说一句,本月将达到 EOL...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2全家桶,快速入门学习开发网站教程
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS6,7,8上安装Nginx,支持https2.0的开启