Posts 低成本备份数据库数据到云端
Post
Cancel

低成本备份数据库数据到云端

  万万没想到,刚买没多久的野机场的服务器老板跑路了.服务器直接没了,数据都没来得及备份.现在换了新服务器第一件事情就是想办法备份数据库数据.一开始看了下各大云厂商的云存储,价格虽然不贵但是我这数据也不多.买了的话感觉有点杀鸡用牛刀的感觉.于是我突然看到我的oneDrive,所以我就想到可以备份到oneDrive里面去.免费的容量就5G,可以去淘宝扩容到永久15G.我只用了5块钱. 用来备份我这些玩具项目产生的数据绰绰有余,实在不行还可以再花点钱买个1年1T的套餐还附带一年的office365高级版.

1.自动备份 MongoDB 数据的脚本

  这次我是备份mongodb数据,我的mongodb是跑在容器里面的,启动容器的时候(docker run -p 27017:27017 -v /mongodb:/data/db --name mongodb --restart=always -d mongo --auth)数据是被我挂载在了宿主机 /mongodb 目录下所以我们只需要备份这个目录就可以了.到时候换一个地方跑容器再把备份的这个目录重新挂载就可以了.下面是我用来备份使用到一个powershell脚本(备份一周的数据).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
$today = Get-Date
$folder = "mongodb"
$needDeleteTempFolders = $false
$Logfile = "C:\Users\Mr.Li\OneDrive\backMongoDB.log"

Function LogWrite
{
   Param ([string]$logstring)
   Add-content $Logfile -value $logstring
}

try {
  LogWrite "today: $today" 

  LogWrite "Task Begin at $(Get-Date -Format "MM/dd/yyyy HH:mm:ss")" 

  if (!(Test-Path -Path "C:\Users\Mr.Li\OneDrive\MongoDB")) {
    LogWrite "MongoDB folder donesn't exist, create it" 

    New-Item -Path "C:\Users\Mr.Li\OneDrive" -Name "MongoDB" -ItemType "directory"

    LogWrite "Create MongoDB folder successfully" 
  } else {
    LogWrite "MongoDB folder already exist" 
  }

  if (Test-Path -Path "C:\Users\Mr.Li\OneDrive\MongoDB\$($today.Dayofweek).zip")  {
    LogWrite "C:\Users\Mr.Li\OneDrive\MongoDB\$($today.Dayofweek).zip already exist" 

    Rename-Item "C:\Users\Mr.Li\OneDrive\MongoDB\$($today.Dayofweek).zip" "C:\Users\Mr.Li\OneDrive\MongoDB\$($today.Dayofweek)_temp.zip"

    LogWrite "Rename $($today.Dayofweek).zip to $($today.Dayofweek)_temp.zip successfully" 
  }

  LogWrite "Begin copy files from Server" 

  # 在这里需要设置自己的服务器信息
  scp -r {username}@{host}:/$folder "C:\Users\Mr.Li\OneDrive\MongoDB\$($today.Dayofweek)"

  LogWrite "Complete Copy files at $(Get-Date -Format "MM/dd/yyyy HH:mm:ss")" 

  LogWrite "Begin comperess file"

  # 压缩下 节省空间 成本降到最低
  Compress-Archive -Path "C:\Users\Mr.Li\OneDrive\MongoDB\$($today.Dayofweek)" -DestinationPath "C:\Users\Mr.Li\OneDrive\MongoDB\$($today.Dayofweek).zip"

  LogWrite "Compelte comperess file at $(Get-Date -Format "MM/dd/yyyy HH:mm:ss")"

  LogWrite "Begin remove download files"

  Remove-Item "C:\Users\Mr.Li\OneDrive\MongoDB\$($today.Dayofweek)" -Recurse -Force

  $needDeleteTempFolders = $true

  LogWrite "Compelte remove download files successfully at $(Get-Date -Format "MM/dd/yyyy HH:mm:ss")" 
} catch {
  $needDeleteTempFolders = $false

  LogWrite $_.Exception.Message

  throw $_.Exception
}

try {
  if ($needDeleteTempFolders) {
    LogWrite "Begin remove temp file" 

    # Error "Access to the cloud file is denied" backing up OneDrive
    # Resolve above error: OneDrive setting disable the "Save space and download files as you use them" option (根据需要下载文件以节约空间)
    Remove-Item "C:\Users\Mr.Li\OneDrive\MongoDB\$($today.Dayofweek)_temp.zip" -Recurse -Force

    LogWrite "Compelte remove temp file successfully at $(Get-Date -Format "MM/dd/yyyy HH:mm:ss")" 
  }
} catch {
  LogWrite $_.Exception.Message
  throw $_.Exception
}

LogWrite "-------------------- Task End at $(Get-Date -Format "MM/dd/yyyy HH:mm:ss") --------------------" 

2.设置定期备份

  接下来我们还需要自动运行这个 powershell ,首先需要自动开机.我这个电脑因为配置了别的东西的时候已经设置了自动开机,设置自动开机可以参考使用frp实现windows远程桌面连接这个文章.接下来就是执行我们的powershell脚本了,定期执行 powershell 的方法很多,我这次采用的方法是写一个bat脚本来调用我们的 powershell 脚本,而bat脚本放到 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp 这个目录下,这样就能在每次开机的时候自动运行bat脚本来执行我们的 powershell 脚本了.bat脚本内容如下, 唯一需要改变的就是你的powershell脚本的路径

1
Powershell.exe -executionpolicy remotesigned -File C:\Users\Mr.Li\OneDrive\backUpMongoDB.ps1

3.Issues

  在经过一段时间后,发现备份下来的数据越来越大.而我数据的增长并没有这么大,对比了下前几天备份的数据,发现是 diagnostic.data 这个文件夹一直在增大.查找资料发现对于备份数据来说,这个文件夹并不需要做备份.所以可以有两种选择: 1.在备份的脚本上添加删除这个文件夹的代码 2.在服务器上就删掉这个文件夹.我选择了后者因为如果这个数据越来越大,会加长下载文件的时间.所以我就在服务器上删除了这个文件夹并禁止了 mongodb 继续生成这个文件夹. 因为每此到容器中改配置文件太没法了,所以我就把配置文件写在本地在挂载到容器里面.注意: 在执行下面的命令的时候需要先在本地写好配置文件. docker run -p 27017:27017 -v /mongodb:/data/db -v /mongodb/mongod.conf.orig:/etc/mongod.conf.orig --name mongodb --net userDefined --ip 172.20.0.2 --restart=always -d mongo --auth

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# mongod.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# Where and how to store data.
storage:
  dbPath: /var/lib/mongodb
  journal:
    enabled: true
#  engine:
#  wiredTiger:

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

# network interfaces
net:
  port: 27017
  bindIp: 127.0.0.1


# how the process runs
processManagement:
  timeZoneInfo: /usr/share/zoneinfo

security:
    authorization: enabled

setParameter:
  diagnosticDataCollectionEnabled: false
#operationProfiling:

#replication:

#sharding:

## Enterprise-Only Options:

#auditLog:

#snmp:

  又过了一段时间,我发现 diagnostic.data 这个文件夹还是会生成. 不过 MongoDB 官方文档有写这个文件夹在默认没修过的情况下最大只有200M (200MB maximum diagnostic.data folder size) 所以不删也没啥太大的问题, 一开始我还以为会无限增大呢. 当然了, 强迫症的我还是觉得把这个文件夹给解决掉. 我每天是 9.10 电脑自动启动开始备份,所以我使用 crontab 设置了一个定时任务,每天早上 9 点清空文件里面的内容. crontab -e 添加下面内容设置定时任务

1
0 21 * * * /bin/sh /mongodb/delete_diagnostic_data.sh

delete_diagnostic_data.sh 脚本的内容也很简单

1
rm -f /mongodb/diagnostic.data/metrics.*

0 21 * * * 的意思是在服务器的每天 21 点运行. 因为我的服务器是纽约时间.换算成北京时间就是 9 点. cat /etc/timezone 查看服务器的时区, date 命令查看服务器当前时间.

4.Ref

  1. What-is-diagnostic-data-file-in-mongodb-data-folder
  2. MongoDB Doc
  3. How to schedule a Cron Job to run a script on Ubuntu 16.04
This post is licensed under CC BY 4.0 by the author.

从0到1构建自己具有https协议的服务器

Docker 踩坑合集