一、备份的目的

  • 防止硬件故障引起的数据丢失
  • 防止人为错误误删数据
  • 时间回溯
  • 监管要求

二、备份机制与备份方式介绍:

MongoDB的备份机制:

  • 延迟节点备份
  • 全量备份 + oplog增量

最常见的全量备份方式包括:

  • mongodump
  • 复制数据文件
  • 文件系统快照

三、mongodump和 mongorestore

3.1 介绍

mongodump能够在 Mongodb运行时进行备份,它的工作原理是对运行的 Mongodb做查询,然后将所有查到的 文档写入磁盘。可以备份单独的数据库、集合甚至集合中的子集。

存在问题:

  • 备份恢复的速度较慢
  • 使用 mongodump产生的备份不一定是数据库的实时快照
  • 在备份时可能会对其它客户端性能产生不利的影响

3.2 下载

从 MongoDB 4.4开始, MongoDB数据库工具现在从 MongoDB服务器单独发布,使用自己的版本,初始版本为 100.0.0。以前,这些工具是与 MongoDB服务器一起发布的,并使用匹配的版本控制。 MongoDB数据库工具是一组用于 MongoDB部署的命令行实用程序。数据库工具包括以下二进制文件 :mongodump、 mongoexport、 mongoimport、 mongorestore、 mongostat、 mongotop

cd /data/download
wget https://fastdl.mongodb.org/tools/db/mongodb-database-tools-rhel70-x86_64-100.10.0.tgz
tar zxvf mongodb-database-tools-rhel70-x86_64-100.10.0.tgz
mv mongodb-database-tools-rhel70-x86_64-100.10.0 mongodb-database-tools

3.3 mongodump参数

$ mongodump help

参数说明:

  • -h:指明数据库宿主机的 IP
  • -u:指明数据库的用户名
  • -p:指明数据库的密码
  • -d:指明数据库的名字
  • -c:指明 collection的名字
  • -o:指明到要导出的文件名
  • -q:指明导出数据的过滤条件
  • -j, numParallelCollections= number of collections to dump in parallel (4 by default) #要并行转储的集合数量 (默认为 4)
  • --oplog 备份的同时备份 oplog

3.4 mongodump和 mongorestore基本使用

1、全库备份

mkdir -p /data/backup/mongodb
$ /data/download/mongodb-database-tools/bin/mongodump  -uroot -h192.168.1.153 -p000000 --port 27017 --authenticationDatabase admin -o /data/backup/mongodb

2、备份 app库

$ /data/download/mongodb-database-tools/bin/mongodump  -uroot -h192.168.1.153 -p000000 --port 27017 --authenticationDatabase admin -d app -o /data/backup/mongodb/150-app

3、备份 app库下的 log集合

$ /data/download/mongodb-database-tools/bin/mongodump  -uroot -h192.168.1.153 -p000000 --port 27017 --authenticationDatabase admin -d app -c log  -o /data/backup/mongodb/150-app-log

4、压缩备份

$ /data/download/mongodb-database-tools/bin/mongodump  -uroot -h192.168.1.153 -p000000 --port 27017 --authenticationDatabase admin -d app -o /data/backup/mongodb/gzip --gzip
[root@dev1 app]# pwd
/data/backup/mongodb/gzip/app
[root@dev1 app]# ls
a.bson.gz  a.metadata.json.gz  c.bson.gz  c.metadata.json.gz  fruit.bson.gz  fruit.metadata.json.gz  log.bson.gz  log.metadata.json.gz

5、全备中恢复单库

$ /data/download/mongodb-database-tools/bin/mongorestore -uroot -h192.168.1.153 -p000000 --port 27017 --authenticationDatabase=admin -d app1 /data/backup/mongodb/app

6、全备中恢复单表

$ /data/download/mongodb-database-tools/bin/mongorestore -uroot -h192.168.1.153 -p000000 --port 27017 --authenticationDatabase=admin -d app -c log1 /data/backup/mongodb/app/log.bson

恢复压缩的数据

$ /data/download/mongodb-database-tools/bin/mongorestore -uroot -h192.168.1.153 -p000000 --port 27017 --authenticationDatabase=admin -d app -c log2 /data/backup/mongodb/gzip/app/log.bson.gz --gzip

7、 drop表示恢复的时候把之前的集合 drop掉 (危险 )

$ /data/download/mongodb-database-tools/bin/mongorestore -uroot -h192.168.1.153 -p000000 --port 27017 --authenticationDatabase=admin -d app --drop /data/backup/mongodb/app

3.5 mongodump和 mongorestore高级企业应用( oplog)

--oplog use oplog for taking a point-in-time snapshot

注意:这是 replica set模式专用

oplog介绍

在 replica set中 oplog是一个定容集合( capped collection),它的默认大小是磁盘空间的 5%(可以 通过 oplogSizeMB参数修改 ).

  • 位于 local库的 db.oplog.rs

  • 其中记录的是整个 mongod实例一段时间内数据库的所有变更(插入 /更新 /删除)操作。

  • 当空间用完时新记录自动覆盖最老的记录。

  • 其覆盖范围被称作 oplog时间窗口。

oplog企业级应用

(1)实现热备,在备份时使用 oplog选项

注:为了演示效果我们在备份过程,模拟数据插入

(2)准备测试数据

repl:PRIMARY> use test
repl:PRIMARY> for(var i = 1 ;i < 100; i++) {db.foo.insert({a:i});}
repl:PRIMARY> use local
repl:PRIMARY> db.oplog.rs.find({"op":"i"}).pretty()
{
 "op" : "i",
 "ns" : "test.foo",
 "ui" : UUID("5c0217c6-1f82-4a19-be40-1bd65b1fd4e3"),
 "o" : {
 "_id" : ObjectId("634d3d284e2addec5fcad718"),
 "a" : 3
 },
 "ts" : Timestamp(1666006312, 4),
 "t" : NumberLong(1),
 "v" : NumberLong(2),
 "wall" : ISODate("2022-10-17T11:31:52.906Z")
}

oplog 配合 mongodump实现热备

#备份
/data/download/mongodb-database-tools/bin/mongodump  -uroot -h192.168.1.153 -proot123456 --port 27018 --authenticationDatabase admin --oplog -o /data/backup/mongodb/repl

作用介绍:--oplog 会记录备份过程中的数据变化。会以oplog.bson保存下来

#恢复
/data/download/mongodb-database-tools/bin/mongorestore -uroot -h192.168.1.153 -proot123456 --port 27018 --oplogReplay /data/backup/mongodb/repl

!!!!!!!!!!oplog高级应用 ==========binlog应用

背景:每天 0点全备, oplog恢复窗口为 48小时

某天,上午 10点 world.city 业务表被误删除。

恢复思路:

0、停应用

2、找测试库

3、恢复昨天晚上全备

4、截取全备之后到 world.city误删除时间点的 oplog,并恢复到测试库

5、将误删除表导出,恢复到生产库

恢复步骤:

模拟故障环境:

1、全备数据库

模拟原始数据

/data/download/mongosh/bin/mongosh mongodb://192.168.1.153:27018/admin
/data/download/mongosh/bin/mongosh "mongodb://root:root123456@192.168.1.153:27018/admin"
> use wo
> for(var i = 1 ;i < 20; i++) {
     db.ci.insert({a: i});
 }

全备:

/data/download/mongodb-database-tools/bin/mongodump  -uroot -h192.168.1.153 -proot123456 --port 27018 --authenticationDatabase admin --oplog -o /data/backup/mongodb/repl_20240801

oplog功能:在备份同时,将备份过程中产生的日志进行备份

文件必须存放在 /data/backup/mongodb/repl_20240801下,自动命令为oplog.bson

再次模拟数据

db.ci1.insert({id:1})
db.ci2.insert({id:2})

2、晚上17:55点:删除wo库下的ci表 //19:55时刻,误删除

db.ci.drop()
show tables;

3、备份现有的oplog.rs表

/data/download/mongodb-database-tools/bin/mongodump  -uroot -h192.168.1.153 -proot123456 --port 27018 --authenticationDatabase admin -d local -c oplog.rs  -o /data/backup/mongodb/repl_20240801

4、截取oplog并恢复到drop之前的位置

更合理的方法:登陆到原数据库

mongo 192.168.1.153:27018/admin -uroot -proot123456
my_repl:PRIMARY> use local
repl:PRIMARY> db.oplog.rs.find({ op:"c","o.drop":"ci","ts" : { "$gte" : Timestamp(1722678900, 1) } }).pretty()
{
 "op" : "c",
 "ns" : "wo.$cmd",
 "ui" : UUID("1059940d-5d32-42f7-b1ce-ce0cc19d1921"),
 "o" : {
 "drop" : "ci"
 },
 "o2" : {
 "numRecords" : 19
 },
 "ts" : Timestamp(1722678913, 1),
 "t" : NumberLong(1),
 "v" : NumberLong(2),
 "wall" : ISODate("2024-08-03T09:55:13.492Z")
}

或者 repl:PRIMARY> db.oplog.rs.find({op:"c"}).sort({ts:-1}).limit(1)获取到oplog误删除时间点位置:

1722678913, 1

5、恢复备份 +应用oplog

[mongod@db03 backup]$ cd /data/backup/mongodb/repl_20240803/local
[mongod@db03 local]$ ls
oplog.rs.bson  oplog.rs.metadata.json
[mongod@db03 local]$ cp oplog.rs.bson ../oplog.bson    #覆盖原来的 oplog.bson
rm -rf /data/backup/mongodb/repl_20240803/local/
/data/download/mongodb-database-tools/bin/mongorestore  -uroot -h192.168.1.153 -proot123456 --port 27018 --oplogReplay --oplogLimit "1722678913:1"  --drop /data/backup/mongodb/repl_20240803/

6、查看恢复的数据

/data/mongodb/mongodb_repl/bin/mongo 192.168.1.153:27018/admin -uroot -proot123456
repl:PRIMARY> use wo
repl:PRIMARY> show tables
ci
ci1
ci2
repl:PRIMARY> db.ci.count()
19

7、分片集群的备份思路

Sharding备份形式基本上可以分为两种,分别是异构备份恢复和同构备份恢复。

(1)异构备份恢复

恢复出来的形态和原来不同

方案:

  • 使用 mongodump工具链接 mongos进行备份

问题:

  • 逻辑备份效率低,只适用于数据量小的场景
  • 恢复出来后需要重新分片

(2)同构备份恢复

恢复出来的形态与原来的架构完全一致

方案:

  • 分别备份 shard、configserver

问题:

  • 很难取得一个一致的 sharding备份
  • 备份出来的数据时间不一致
  • 影响因素:
  • 备份过程中外部的修改
  • 备份过程中内部的修改:内部迁移(chunk迁移)/

(3)其他方案

a.使用 Ops Manager

b.

balancer 关闭--->

同一时刻config、shard其中一个节点脱离集群--->

开始备份节点数据 --->

把节点恢复到集群

四、表导入导出常用工具

mongoexport/mongoimport

针对库中的表,导入/导出的是JSON格式或者CSV格式,而mongodump/mongorestore针对库,导入/导出的是BSON格式。

应用场景:

mongoexport/mongoimport: json csv

1、异构平台迁移 mysql <---> mongodb

2、同平台,跨大版本: mongodb 5 ----> mongodb 6

mongodump/mongorestore

1、日常备份恢复时使用

4.1 导出工具 mongoexport

1、定义

Mongodb中的 mongoexport工具可以把一个 collection导出成 JSON格式或 CSV格式的文件。可以通过参数指定导出的数据项,也可以根据指定的条件导出数据。

(1)版本差异较大

(2)异构平台数据迁移

2、用法

mongoexport具体用法如下所示:

$ mongoexport --help

参数说明:

  • -h: 指明数据库宿主机的 IP
  • -u: 指明数据库的用户名
  • -p: 指明数据库的密码
  • -d: 指明数据库的名字
  • -c: 指明 collection的名字
  • -f: 指明要导出那些列
  • -o: 指明到要导出的文件名
  • -q: 指明导出数据的过滤条件
  • --authenticationDatabase admin

3、示例

(1)单表备份至 json格式

> use test
> for(i=0;i<100;i++){ db.log.insert({"uid":i,"name":"mongodb","age":6,"date":new Date()}); }
$ /data/download/mongodb-database-tools/bin/mongoexport -uroot -h192.168.1.153 -p000000 --port 27017 --authenticationDatabase admin -d test -c log -o /data/backup/mongodb/mongoexport/log.json

注:备份文件的名字可以自定义,默认导出了JSON格式的数据。

(2)单表备份至 csv格式

如果我们需要导出CSV格式的数据,则需要使用--type=csv参数:

$ /data/download/mongodb-database-tools/bin/mongoexport -uroot -h192.168.1.153 -p000000 --port 27017 --authenticationDatabase admin -d test -c log --type=csv -f uid,name,age,date -o /data/backup/mongodb/mongoexport/log.csv

4.2 导入工具 mongoimport

1、定义

Mongodb中的 mongoimport工具可以把一个特定格式文件中的内容导入到指定的 collection中。该工具可以导入 JSON格式数据,也可以导入 CSV格式数据。具体使用如下所示:

2、用法

$ mongoimport --help

参数说明:

  • -h: 指明数据库宿主机的 IP
  • -u: 指明数据库的用户名
  • -p: 指明数据库的密码
  • -d: 指明数据库的名字
  • -c: 指明 collection的名字
  • -f: 指明要导入那些列
  • -j, --numInsertionWorkers=<number> number of insert operations to run concurrently (defaults to 1)

并行

3、示例

数据恢复:

(1)恢复json格式表数据到log1

$ /data/download/mongodb-database-tools/bin/mongoimport -uroot -h192.168.1.153 -p000000 --port 27017 --authenticationDatabase admin -d test -c log1 /data/backup/mongodb/mongoexport/log.json

(2)恢复csv格式的文件到log2

上面演示的是导入 JSON格式的文件中的内容,如果要导入 CSV格式文件中的内容,则需要通过 type参数指 定导入格式,具体如下所示:

1、csv格式的文件头行,有列名字

--headerline:指明第一行是列名,不需要导入

$ /data/download/mongodb-database-tools/bin/mongoimport -uroot -h192.168.1.153 -p000000 --port 27017 --authenticationDatabase admin -d test -c log2 --type=csv --headerline --file  /data/backup/mongodb/mongoexport/log.csv

2、csv格式的文件头行,没有列名字

$ /data/download/mongodb-database-tools/bin/mongoimport -uroot -h192.168.1.153 -p000000 --port 27017 --authenticationDatabase admin -d test -c log3 -j 4 --type=csv -f id,name,age,date --file /data/backup/mongodb/mongoexport/log.csv

4、异构平台迁移案例

mysql -----> mongodb

oldboy_test数据库下info_area表进行导出,导入到mongodb

(1)mysql开启安全路径

vim /etc/my.cnf   --->添加以下配置
secure-file-priv=/data/backup/

--重启数据库生效

/etc/init.d/mysqld restart

(2)导出mysql的city表数据

mysql -uroot -h 192.168.1.150 -p000000 -P3307
mysql> use oldboy_test
mysql> select * from info_area into outfile '/tmp/info_area.csv' fields terminated by ',';
Query OK, 20104 rows affected (0.03 sec)

(3)获取列信息

mysql> select table_name,group_concat(column_name)  from information_schema.columns where table_schema='oldboy_test' and table_name='info_area' group by table_name order by null ;
+------------+---------------------------+
| table_name | group_concat(column_name) |
+------------+---------------------------+
| info_area  | id,name,rel_id,pid,level  |
+------------+---------------------------+
1 row in set (0.00 sec)
mysql> select * from oldboy_test.info_area limit 1;
+-------+--------+--------+-----+-------+
| id    | name   | rel_id | pid | level |
+-------+--------+--------+-----+-------+
| 10000 | 北京   | 10000  |   0 |     1 |
+-------+--------+--------+-----+-------+
1 row in set (0.00 sec)

(4)在mongodb中导入备份

$ /data/download/mongodb-database-tools/bin/mongoimport -uroot -h192.168.1.150 -p000000 --port 27017 --authenticationDatabase admin -d test -c info_area --type=csv -f id,name,rel_id,pid,level --file  /tmp/info_area.csv
> use test
> db.info_area.find()
{ "_id" : ObjectId("634be046c0612fd495ae2c8a"), "id" : 10000, "name" : "北京", "rel_id" : 10000, "pid" : 0, "level" : 1 }

5、如何将MySQL大量表迁移到MongoDB

(1)批量从MySQL导出某个库下的多张表

# mysqldump -h192.168.1.150 -P3307 -uroot -p000000 --single-transaction oldboy_test --fields-terminated-by=',' --fields-enclosed-by '"' -T /tmp/backup/
# cd /tmp/backup
# rm -rf /tmp/backup/*.sql
# find ./  -name "*.txt" | awk -F "." '{print $2}' | xargs -i -t mv ./{}.txt  ./{}.csv

(2)拼接语句

mysql> select concat("/data/download/mongodb-database-tools/bin/mongoimport -uroot -h192.168.1.150 -p000000 --port 27017 --authenticationDatabase admin -d ",table_schema, " -c  ",table_name ," --type=csv "," -f ", group_concat(column_name) ," --file  /tmp/backup/",table_name ,".csv") from information_schema.columns where table_schema="oldboy_test" group by table_name;

(3)将语句写入文件 import.sh

[root@dev0 backup]# mysql -h192.168.1.150 -P3307 -uroot -p000000 -D oldboy_test -Ne 'select concat("/data/download/mongodb-database-tools/bin/mongoimport -uroot -h192.168.1.150 -p000000 --port 27017 --authenticationDatabase admin -d ",table_schema, " -c  ",table_name ," --type=csv "," -f ", group_concat(column_name) ," --file  /tmp/backup/",table_name ,".csv") from information_schema.columns where table_schema="oldboy_test" group by table_name;' > /tmp/backup/import.sh
[root@dev0 backup]# ll -h
总用量 1.1M
-rw-r--r--. 1 root  root  1.2K 10月 16 19:05 import.sh
-rw-rw-rw-. 1 mysql mysql  515 10月 16 18:53 info_area_20240801.csv
-rw-rw-rw-. 1 mysql mysql 1.9K 10月 16 18:53 info_area_bak.csv
-rw-rw-rw-. 1 mysql mysql 1.1M 10月 16 18:53 info_area.csv
-rw-rw-rw-. 1 mysql mysql   19 10月 16 18:53 repl_ignore_test.csv

(4)导入数据

[mongod@db01 backup]$ sh import.sh
#登录mongo查看库表信息
> show dbs
admin        0.000GB
app          0.001GB
config       0.000GB
local        0.000GB
oldboy_test  0.001GB
test         0.002GB
> use oldboy_test
switched to db oldboy_test
> show tables;
info_area
info_area_20240801
info_area_bak
repl_ignore_test