记录MongoDB备份与还原知识点与个人站点的MongoDB备份脚本

备份

MongoDB数据备份的几种方式

  • mongodump命令
  • 系统快照
  • cp or rsync

官方参考文档:https://docs.mongodb.com/manual/core/backups/

Mongodump命令

在Mongodb中可以使用mongodump命令来备份MongoDB数据,mongodump命令可以从 MongoDB 数据库读取数据,并生成 BSON 文件,mongodump 适合用于备份和恢复数据量较小的 MongoDB 数据库,不适用于大数据量备份。

mongodump 仅备份数据库中的文档,不备份索引,所以还原数据后需要重新生成索引。

mongodump 备份过程中会对 mongod 服务的性能产生影响,建议在业务低峰期进行操作。

  • mongodump命令参数
# 命令格式
mongodump <options>


--host <hostname><:port>, -h <hostname><:port>  # 指定备份的主机ip和端口号,默认值localhost:27017
--port # 指定端口号 默认27017

--username <username>, -u <username> # 指定用户名
--password <password>, -p <password> # 指定密码
--authenticationDatabase <dbname> # 指定认证的数据库
--authenticationMechanism <name> # 指定认证的算法 ,默认值 SCRAM-SHA-1
--db <database>, -d <database> # 指定备份的数据库,未指定的话,备份所有的数据库,但不包含local库
--collection <collection>, -c <collection> # 指定备份的集合,未指定则备份指定库中的所有集合。
--query <json>, -q <json>  # 指定 json 作为查询条件。来备份我们过滤后的数据。
--queryFile <path>  # 指定 json 文档路径,以该文档的内容作为查询条件,来备份我们过滤后的数据。
--quit # 通过抑制 MongoDB的复制,连接等活动,来实现备份。
--gzip  # 开启压缩,3.2版本后可以使用,输出为文件的话会带有后缀.gz
--out <path>, -o <path>  # 输出的目录路径

--repir # 修复数据时使用 下面有详细介绍
--oplog # mongodump 会将 mongodump 执行期间的 oplog 日志 输出到文件 oplog.bson,这就意味着从备份开始到备份结束的数据操作我们都可以记录下来。
--archive <file> # 输出到单个存档文件或者是直接输出。


--dumpDbUsersAndRoles # 只有在 使用 --db 时才适用,备份数据库的包含的用户和角色。
--excludeCollection string # 排除指定的集合,如果要排除多个,使用多个--excludeCollection 
--numParallelCollections int, -j int # 并行导出的集合数,默认为4


--ssl  # 指定 TLS/SSL 协议
--sslCAFile filename # 指定认证文件名
--sslPEMKeyFile <filename>
--sslPEMKeyPassword <value>
--sslCRLFile <filename>
--sslAllowInvalidCertificates
--sslAllowInvalidHostnames
--sslFIPSMode

可以通过mongodump –help查看options

系统快照

如果MongoDB是部署在阿里云ECS之类的云服务器,可以利用系统快照与生成策略进行定时备份。

Cp or Rsync

直接使用cp或者rsync等工具进行mongodb的data文件复制,自复制多个文件不是一个原子操作,所以在复制前必须停止对 MongoDB 的操作。 否则复制的文件会处于无效状态。

还原

Mongorestore

在Mongodb中可以使用mongorestore 命令来恢复备份的数据。

mongorestore可以创建新的数据库或将数据添加到现有的数据库,但是 mongorestore 仅仅执行insert操作,不执行update操作。这就意味着如果将文档还原到现有的数据库,现有的数据库中的文档的_id的值和要还原的文档中的_id 值是一样的,是不会将数据库原有的值覆盖的。

  • restore命令参数
mongorestore <options> <directory or file to restore>
  
--help # 查看帮助
--quiet # 通过抑制 MongoDB的复制,连接等活动,来实现数据恢复。

--host <hostname><:port>, -h <hostname><:port>  # 指定恢复的主机ip和端口号,默认值localhost:27017
--port # 指定端口号 默认27017

--username <username>, -u <username> # 指定用户名
--password <password>, -p <password> # 指定密码
--authenticationDatabase <dbname> # 指定认证的数据库
--authenticationMechanism <name> # 指定认证的算法 ,默认值 SCRAM-SHA-1
--objcheck # 开启验证,验证还原操作,确保没有无效的文档插入数据库。会有较小的性能影响
--oplogReplay # 恢复备份数据并将 mongodump 执行期间的操作(记录在导出的日志)恢复。
--oplogLimit  # 指定恢复
--oplogFile # 指定 Oplog 路径
--keepIndexVersion # 阻止mongorestore在还原过程中将索引升级到最新版本。
--restoreDbUsersAndRoles # 还原指定的数据库用户和角色。
--maintainInsertionOrder # 默认值为False,如果为 True,mongorestore 将按照输入源的文档顺序插入,否则是 随机执行插入。
--numParallelCollections int, -j int # 指定并行恢复的集合数。
--numInsertionWorkersPerCollection int # 默认值为 1,指定每个集合恢复的并发数,大数据量导入增加该值可提高 恢复速度。
--gzip # 从压缩文档中 恢复。
--archive # 从归档文件中恢复。
--dir # 指定还原数据储存目录。

可以通过mongorestore –help查看options

MongoDB定时备份Shell脚本实现

可以通过Shell脚本与linux的crontab实现定时备份,目的是做到如下几点:

  • 使用dump命令备份七天内的mongoDB数据
  • 需要对备份的数据进行压缩归档处理(mongodump并不提供压缩归档功能)
  • 过期备份数据清理,只保留七天内

定时备份Shell脚本如下:

#--------------------------------------------
# mongodb定时备份脚本
#--------------------------------------------
#! /bin/bash

# 命令执行路径
MONGOD=/usr/bin/mongodump
OUT_DIR=/data/backup/mongo/mongod_bak_tmp
# 压缩后的备份存放路径
TAR_DIR=/data/backup/mongo/mongod_bak_list
# 压缩时间为当前系统时间/删除时间为七天前
TAR_DATE=$(date +%F)
DEL_DATE=$(date +%F -d "-7 day")

# 数据库配置
DB_HOST=ip:port
DB_NAME==******
DB_AUTHSOURCE=admin
DB_USERNAME=******
DB_PASSWORD=******

if [[ ! -d ${OUT_DIR} ]];then
mkdir -p ${OUT_DIR}
fi

if [[ ! -d ${TAR_DIR} ]];then
mkdir -p ${TAR_DIR}
fi

TAR_BAK="mongo_bak_${TAR_DATE}.tar.gz"
cd ${OUT_DIR}
rm -rf ${OUT_DIR}/*
${MONGOD} -h ${DB_HOST} -u ${DB_USERNAME} -p ${DB_PASSWORD} --authenticationDatabase ${DB_AUTHSOURCE} -d ${DB_NAME} -o ${OUT_DIR}
# 压缩归档
tar -zcvPf ${TAR_DIR}/${TAR_BAK} ${OUT_DIR}
# 清除历史归档(七天前)
for i in `find ${TAR_DIR} -maxdepth 1 \( -type d -o -type l \)`;
do
        find -L $i -maxdepth 1 -type f \( -name "*${DEL_DATE}*" -a -name "*.tar.gz" \) -exec rm -f {} \;
done

其他:可以将添加crontab定时任务使用Shell编写,基于Jenkins控制发布,做到自动化运维与减少误操作。一般执行crontab -e命令都是直接往/var/spool/cron下创建一个文件,这个文件的名称就是你的当前用户名,内容就是你添加的任务具体内容。依据这一点可以做到自动化的crontab发布,Shell脚本大致如下:

crontab_reload(){
    echo "30 0 * * * ${SCRIPT_DIR}/auto/crontab/mongo_back.sh" > /var/spool/cron/root
    # 重启crontab
    /sbin/service crond restart
    service crond status
    echo "get current crontab"
    crontab -l
    echo "crontab reload done"
}