---
# System prepended metadata

title: backup(備份)
tags: [server, linux]

---

---
tags: linux,server
---
# backup(備份)
一般會需要備份的東西:資料庫、更動過的設定檔、會時常更動的檔案。

先詢問有哪些主機

## SSH 公開金鑰認證
以下的方式用於下載完ssh之後，client指的是伺服器，server是本機。

SSH公開金鑰認證，可以讓server可以不需要密碼就可以進入client。

### 實作
如果要在 Linux 上產生 SSH 登入用的金鑰，可以使用 ssh-keygen 這個指令。在建立金鑰之前，要先建立 ~/.ssh 這個目錄，並設定正確的權限：
```shell
$ mkdir -p ~/.ssh     #建立.sh資料夾
$ chmod 700 ~/.ssh    #改變.sh的權限設定
$ cd .ssh
$ ssh-keygen          #建立金鑰的指令
```
在產生金鑰的過程中，會詢問一些問題，對於一般的使用者而言，全部都使用預設值（直接按下 Enter 鍵）即可。

==詢問金鑰建立位置==
```
Generating public/private rsa key pair.    
Enter file in which to save the key (/home/seal/.ssh/id_rsa):
```
==詢問密碼==
指定金鑰保護密碼，如果有設定密碼的話，以後每次使用都要輸入密碼，除你需要非常高的安全性，否則就不用設定了，直接按下 Enter 鍵即可。
```
Enter passphrase (empty for no passphrase):
```
==再次輸入密碼==
直接按下 Enter 鍵，接著就會產生金鑰了。
```
Enter same passphrase again:
```
==產生的金鑰指紋==
```
Your identification has been saved in /home/seal/.ssh/id_rsa.
Your public key has been saved in /home/seal/.ssh/id_rsa.pub.
The key fingerprint is:
c7:61:98:72:02:91:94:db:12:96:05:9d:59:91:aa:25 seal@seal-desktop
The key's randomart image is:
+--[ RSA 2048]----+
|   .=O.+oo       |
|    *.+ .o       |
|   . +o.+ o      |
|    E ++ o .     |
|     =  S o      |
|    .    .       |
|                 |
|                 |
|                 |
+-----------------+
```
==建立的位置中會產生兩種金鑰==
id_rsa.pub：公開金鑰（public key），這是可以對外公開的金鑰，之後要將它放在要遠端的 Linux 伺服器上作認證使用。
id_rsa：私密金鑰（private key），這是要保護好的金鑰，它等同於你的 Linux 密碼，放在自己的電腦中。

將產生的 id_rsa.pub 這個公開金鑰複製到client上的 ~/.ssh/authorized_keys 檔案中
```shell
$ scp ~/.ssh/id_rsa.pub user@host:~/.ssh     #user是client的名字 host是client的IP
```
然後切換到client的.ssh資料夾
```
$ cp id_rsa.pub authorized_keys            #id_rsa.pub 寫進 authorized_keys
```
之後server就可以不用密碼就登入client了

==改用金鑰登入而不用密碼登入==
修改client的/etc/ssh/sshd_config
```s
PasswordAuthentication no
PubkeyAuthentication yes
```
接著重啟ssh服務
```shell
$ sudo service ssh restart
```
之後client就只接受金鑰登入了
如果還有問題，可能是因為金鑰判斷權限過大不安全所以暫停金鑰驗證。

## 備份
備份跟copy是一樣的概念，完整備份有兩種，一種是累積備份、一種是差異備份。
以下做的是差異備份，差異備份的第一次是把檔案全部備份，之後備份同樣的資料會和第一次做比較，然後存取，所以和copy比速度會比較快，和累積備份比，速度會比較慢，不過還原速度比較快。
### rsync
大部分的 Linux 發行版都會內建 rsync 工具，如果您的系統沒有安裝，通常也都可以透過系統的套件來安裝。
```shell
$ sudo apt-get install rsync
```
==rsync一般用法==
```shell
rsync 參數 來源檔案 目的檔案
```
==參數==
rsync 預設只會將來源端現存的檔案同步更新至目的端（同步所有新增或修改的檔案），但是如果在來源端有檔案被刪除的話，rsync 並不會主動刪除目的端的檔案，這樣可以確保資料被勿刪時，備份檔不會也跟著被刪除。
```shell
-v：verbose 模式，輸出比較詳細的訊息。
-r：遞迴（recursive）備份所有子目錄下的目錄與檔案。
-a：封裝備份模式，遞迴備份所有子目錄下的目錄與檔案，保留連結檔、檔案的擁有者、群組、權限以及時間戳記。
-z：啟用壓縮。
-h：將數字以比較容易閱讀的格式輸出。
-e "ssh -p 指定port":轉port。
--progress：傳輸檔案時可以即時顯示進度。
--delete：同步刪除。
--exclude　'指定名稱'：排除指定名稱檔案。
--include '指定名稱'：備份指定名稱檔案。
```


### mysqldump
適用於資料庫的備份(匯出)、還原(匯入)。
大部分下載完資料庫後都會有，如果您的系統沒有安裝，通常也都可以透過系統的套件來安裝。
```shell
sudo apt-get install mysql-client
```
==mysqldump備份(匯出)一般用法==

```shell
mysqldump -u 資料庫帳號 -p database名稱 > 匯出的名稱.sql
```

==參數==
```shell
-h 目標ip位置
如果想備份本機資料庫，此參數可省略，上述用法已省略。

備份資料庫中單一資料表
mysqldump -u 資料庫帳號 -p database名稱 table名稱 > 匯出的名稱.sql

備份資料庫中多張資料表
mysqldump -u 資料庫帳號 -p database名稱 table1 table2 > 匯出的名稱.sql

備份多個資料庫
mysqldump -u 資料庫帳號 -p --databases db1 db2 > 匯出的名稱.sql

備份所有資料庫
mysqldump -u 資料庫帳號 -p --all-databases > 匯出的名稱.sql
```
==mysqldump還原(匯入)一般用法==
匯入的話建議資料庫帳號用root
```shell
復原單一資料庫 #要先有database才能匯入
mysql -u 資料庫帳號 -p database名稱 < 匯入的檔案.sql

復原多個資料庫
mysql -u 資料庫帳號 -p < 匯入的檔案.sql
```
## 撰寫bash檔
因為會需要用到sudo權限，所以以下都是用root狀態下執行。
```
su root
```
因為根目錄沒有backup資料夾，所以創建一個。
```
mkdir -p /backup
cd /backup
```
以下使用blog當範例

==mysqldump備份(資料庫的備份)==
取名時附檔名一定要是 "xx.sh"
```shell
vi backupblogsql.sh
```
```bash=
#!/bin/bash
#myhost指的是備份的目標ip，如果在本機備份就可省略
myHost="120.110.114.xx"
#目標資料庫帳號
myUser="root"
#目標資料庫密碼
myPass="*******"
#目標資料庫名稱
myDB="blogallsql"
#日期
date=$(date +"%Y%m%d")
#要匯出的檔案名稱
sql_file=/backup/sql/$myDB"_"$date".sql"

echo "mysqldump..."

#mysqldump -h $myHost -u $myUser -p$myPass $myDB > $sql_file
#如果是在本機備份，-h可省略
mysqldump  -u $myUser -p$myPass --all-databases > $sql_file

echo $sql_file" OK"
```
因為備份檔案在/backup/sql，但沒有這個檔案，所以創建一個。
```shell
mkdir -p /backup/sql
```
寫好執行檔後須把權限都調成可執行，否則可能會跳出錯誤。
```shell
chmod 755 檔案名稱.sh
```
嘗試執行檔案，查看是否有寫錯。
```
sh backupblogsql.sh
```
==rsync備份(一般檔案的備份)==
```shell
vi backupblogwww.sh
```
```bash=
#!/bin/bash
export timestamp=$(date +"%Y%m%d")
rsync -avh --delete /var/www/html /backup/www/

tar -cvpzf /backup/www/bloghtmlbackup_$timestamp.tar.gz /backup/www/html
```
因為備份檔案在/backup/www，但沒有這個檔案，所以創建一個。
```shell
mkdir -p /backup/www
```
寫好執行檔後須把權限都調成可執行
```shell
chmod 755 檔案名稱.sh
```
嘗試執行，查看是否有寫錯。
```
sh backupblogwww.sh
```
如果確定可以執行成功且確定能正確還原資料庫，就可以寫一個bash合併執行
```shell
vi backupblog.sh
```
```bash=
#備份資料位置(本機)
backup_path="/backup/"
#日期
date=$(date +"%Y%m%d")
sql_file=$backup_path"sql/blogallsql_"$date".sql"
www_file=$backup_path"www/bloghtmlbackup_"$date."tar.gz"
sh backupblogwww.sh
sh backupblogsql.sh
#10.10.10.12是備份機內網
rsync -avh $sql_file 帳號@10.10.10.12:~/sql
rsync -avh $www_file 帳號@10.10.10.12:~/www
```
設定自動刪除30天以前的檔案(不含30)
```shell=
vi rmbk30_blog.sh
```
```bash=
find /backup/sql/ -type f -name "*.sql" -mtime +30 -exec rm -f {} \;
find /backup/www/ -type f -name "*.tar.gz" -mtime +30 -exec rm -f {} \;
```

設定排程(鬧鐘)
到/etc/crontab修改 設定為每個星期六早上2點自動執行一次
```shell
0 2 * * 6 root cd /backup && sh backupblog.sh
```








下圖在介紹為什麼要從伺服器備份到備份機，而不是備份機主動到伺服器備份。
![](https://scontent.ftpe11-2.fna.fbcdn.net/v/t1.15752-9/50510676_1867672530021671_2336613469182230528_n.jpg?_nc_cat=108&_nc_ht=scontent.ftpe11-2.fna&oh=34361c5def4d08a04c59bef0d44f6cf8&oe=5D233376)
每台機器的用途都不一樣，所以要備份的東西都不太相同，備份的用意在於就算資料丟失或損毀都有補救的方法，所以只要確保能夠還原到最佳狀態就可以了。
