[AWS] 備份 MySQL 資料至 AWS S3 Bucket

鼠年全馬鐵人挑戰 - WEEK 20

前言

現實生活中的系統,為了避免資料遺失,系統平時都該備份資料庫的資料。當系統發生問題時,能在最快的時間點還原原始資料。本篇文章紀錄如何將既有的MySQL資料庫內資料,藉由 Crontab 指令定期備份至 AWS S3

前置作業

  • 既有的MySQL資料庫,裡面有多張資料表
  • OS: Ubuntu 18.04
  • MySQL 5.7+
  • AWS 帳號
  • 下載 AWS Cli tools

流程

本文會依照下方流程實作備份:

  • 什麼是 S3 Bucket
  • 建立S3 Bucket
  • 建立 IAM User
  • 依照政策 賦予 IAM User 權限
  • 撰寫備份用的 shell script
  • 制定 Cron job 定期任務排程

什麼是 AWS S3

S3 是 AWS 提供的儲存服務,用於存放和擷取任意數量的資料,資料會以物件的形式進行儲存,花費的成本低廉,所以備份至S3是不錯的選擇。

建立S3 Bucket

進入已經創建好的 AWS 帳號,選擇 S3 服務,點擊Create bucket,接著輸入自訂的 bucket 名稱,下方選單選擇想要存放的Region

輸入完畢後點擊Create bucket

建立 IAM User


輸入User Name 且自訂密碼

新建policy

貼上下方的JSON格式資料,並將資料內的mysqlsourcebackup替換成自己創建S3 Bucket 所取的名稱,修改完畢後點擊Review Policy

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
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListAllMyBuckets"],
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::mysqlsourcebackup"

},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::mysqlsourcebackup/*"


}
]
}


接著替自己創建的policy取名後,點擊Create Policy

回到剛剛創建User的介面,搜尋新創建的policy名稱進行勾選,就可以繼續執行一步到創建完成。

下載個人金鑰置個人電腦,金鑰為機密資訊,務必好好保管!也可以寄信至個人信箱

撰寫備份用的 shell script

建立runbackup.sh

1
sudo vim runbackup.sh

填入下方程式碼,並修改=後方的值:

  • your_access_keyyour_secret_key: 為剛才創建帳號時下載的金鑰資訊
  • s3_region: S3 bucket 所在之區域
  • S3_BUCKET: S3 bucket 名稱
  • 其餘為MySQL相關資訊: host_name(e.g. localhost)MYSQL_PORT(e.g. 3306)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
## 填入 AWS User Credential 的資訊
AWS_ACCESS_KEY_ID=your_access_key \
AWS_SECRET_ACCESS_KEY=your_secret_key \
## 填入 S3 資訊
AWS_DEFAULT_REGION=s3_region \
S3_BUCKET=your_buket_name \
## 填入MySQL資訊
MYSQL_HOST=host_name \
MYSQL_PORT=db_port \
MYSQL_USER=db_user \
MYSQL_PASS=db_password \
MYSQL_DB=db_name \
## 執行 backup.sh
bash -x backup.sh

修改完畢後按下ESC+:wq!儲存關閉。

建立backup.sh

1
sudo vim backup.sh

寫入下方程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
cd /tmp
file=$(date +%A%d%B%Y).sql
mysqldump \
--host ${MYSQL_HOST} \
--port ${MYSQL_PORT} \
-u ${MYSQL_USER} \
--password="${MYSQL_PASS}" \
${MYSQL_DB} > ${file}
if [ "${?}" -eq 0 ]; then
gzip ${file}
aws s3 cp ${file}.gz s3://${S3_BUCKET}
rm ${file}.gz
else
echo "Error backing up mysql"
exit 255
fi

修改完畢後按下ESC+:wq!儲存關閉。

測試腳本

1
bash -x runbackup.sh

執行上述指令執行runbackup.sh這支腳本,到 S3 Bucket 的管理介面查看有沒有上傳成功!

制定 Cron job 定期任務排程

下載

1
sudo apt update & sudo apt install cron 

確保有在背景執行

1
sudo systemctl enable cron

成功的話會提示跟下方相同的訊息

1
2
3
Output
Synchronizing state of cron.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable cron

編輯 crontab

1
crontab -e

執行上方指令,會跳出下方的提示資訊

1
2
3
4
5
6
7
8
9
10
Output
no crontab for sammy - using an empty one

Select an editor. To change later, run 'select-editor'.
1. /bin/nano <---- easiest
2. /usr/bin/vim.basic
3. /usr/bin/vim.tiny
4. /bin/ed

Choose 1-4 [1]:

個人習慣用Vim,故輸入2,可依個人習慣自由選擇,選擇好之後就會進入新建立的 crontab

在下方新增排程時間,以及要執行的指令,假設是 每天凌晨12:00 進行排程任務,執行runbackup.sh這支檔案,就可以寫成下方的指令:

1
0 0 * * * root bash -x /home/coupon/runbackup.sh

修改完畢後按下ESC+:wq!儲存關閉。

補充

  • bash -x /home/coupon/runbackup.sh 為要執行的檔案,要確認檔案的所在位置是正確的!
  • Crontab 時間結構
欄位 允許範圍
minute 0-59
hour 0-23
day_of_month 1-31
month 1-12 or JAN-DEC
day_of_week 0-6 or SUN-SAT
  • crontab 執行規則如下:
    1
    minute hour day_of_month month day_of_week command_to_run

更多細節參考Digital Ocean Community所撰寫的文章,還蠻清楚的!

Comments