1. 程式人生 > >安全的web服務器——使用mysqldump和mysqlbinlog實現MySQL全量與增量備份

安全的web服務器——使用mysqldump和mysqlbinlog實現MySQL全量與增量備份

ted l數據庫 pos web服務 max 教程 sudo osi 所有

1.環境

系統是Deepin15.6,數據庫的版本號是:

Server version: 5.7.18-1 (Debian)

數據庫引擎是:InnoDB。如何查看數據庫版本和數據庫引擎呢?

終端登錄MySQL數據庫命令行的時候,就可以看見數據庫版本。

登錄數據庫後,使用如下命令:

show engines;

它會顯示很多數據庫引擎,其中,顯示YES的指本數據庫支持的引擎,顯示default的是本數據庫默認的引擎。

也可以用如下命令:

show variables like %storage_engine%;

來顯示數據庫引擎。

2.全量備份

全量備份很簡單,備份的命令是:

#--databases,指定數據庫 #--flush-logs,產生新的日誌文件,binlog文件,這個在後面的增量備份有講到過 #--delete-master-logs,刪掉原來的日誌文件,binlog文件 #DumpFile是要備份的目標文件 mysqldump -uroot -p123456 --databases wordpressdb --flush-logs --delete-master-logs --single-transaction > $DumpFile

恢復的命令是在MySQL命令行中執行的,要先手動創建一個數據庫,然後再use這個數據庫:

mysql> source $DumpFile

3.增量備份

這個操作需要MySQL本身的日誌文件支持,登陸mysql,檢查log-bin是否開啟:

show variables like ‘log_bin‘;

如果如下所示:

mysql> show variables like log_bin;
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | OFF   |
+---------------+-------+
1 row in
set (0.00 sec)

顯示OFF的話,那就是沒有開始日誌服務。那麽找到MySQL的配置文件,更改配置,這個地方看了網上的很多教程,但是都沒有用。大概他們講的都是centos上的配置步驟吧,而我用的是基於debian的deepin15.6(Ubuntu應該也是適用的)。配置文件的目錄是

/etc/mysql/mysql.conf.d/mysqld.cnf

在其中加入這麽幾項:

技術分享圖片

然後,在終端中輸入:sudo service mysql restart 重啟MySQL服務,再登陸上MySQL,執行命令

show variables like ‘log_bin‘;看到如下結果,證明binlog配置成功。
+---------------------------------+--------------------------------+
| Variable_name                   | Value                          |
+---------------------------------+--------------------------------+
| log_bin                         | ON                             |
| log_bin_basename                | /var/log/mysql/mysql-bin       |
| log_bin_index                   | /var/log/mysql/mysql-bin.index |
| log_bin_trust_function_creators | OFF                            |
| log_bin_use_v1_row_events       | OFF                            |
+---------------------------------+--------------------------------+
5 rows in set (0.00 sec)

關於binlog日誌的詳細配置用法:

binlog_format 此參數配置binlog的日誌格式,默認為mixed。

max_binlog_size此參數配置binlog的日誌最大值,最大和默認值是1GB。

max_binlog_cache_size此參數表示binlog使用最大內存的數。

binlog-do-db=db_name 此參數表示只記錄指定數據庫的二進制日誌。

binlog-ignore-db=db_name此參數表示不記錄指定的數據庫的二進制日誌。

expire_logs_days 此參數表示binlog日誌保留的時間,默認單位是天。

關於binlog日誌的操作命令:

1.查看所有binlog日誌列表
  mysql> show master logs;

2.查看master狀態,即最後(最新)一個binlog日誌的編號名稱,及其最後一個操作事件pos結束點(Position)值,這個文件就是當前MySQL在使用的binlog文件。
  mysql> show master status;

3.刷新log日誌,自此刻開始產生一個新編號的binlog日誌文件
  mysql> flush logs;
  註:每當mysqld服務重啟時,會自動執行此命令,刷新binlog日誌;在mysqldump備份數據時加 -F 選項也會刷新binlog日誌;

4.重置(清空)所有binlog日誌
  mysql> reset master;

如果想查看binlog日誌的具體內容,登錄MySQL命令行:

mysql> show binlog events [IN log_name] [FROM pos] [LIMIT [offset,] row_count];
選項解析:
IN log_name   指定要查詢的binlog文件名(不指定就是第一個binlog文件)
FROM pos        指定從哪個pos起始點開始查起(不指定就是從整個文件首個pos點開始算)
LIMIT [offset,] 偏移量(不指定就是0)
row_count       查詢總條數(不指定就是所有行)

比如做一下查詢,在mysql-bin.000002文件中查詢pos在219之後的內容:

mysql> show binlog events in mysql-bin.000002 from 219;
+------------------+-----+------------+-----------+-------------+----------------------------------------+
| Log_name         | Pos | Event_type | Server_id | End_log_pos | Info                                   |
+------------------+-----+------------+-----------+-------------+----------------------------------------+
| mysql-bin.000002 | 219 | Query      |         1 |         298 | BEGIN                                  |
| mysql-bin.000002 | 298 | Table_map  |         1 |         366 | table_id: 241 (wordpressdb.wp_options) |
| mysql-bin.000002 | 366 | Write_rows |         1 |         447 | table_id: 241 flags: STMT_END_F        |
| mysql-bin.000002 | 447 | Xid        |         1 |         478 | COMMIT /* xid=53 */                    |
+------------------+-----+------------+-----------+-------------+----------------------------------------+
4 rows in set (0.00 sec)

這樣,我們的binlog日誌功能算是做好了。

4.恢復數據實戰

首先,建立一個數據庫,並且插入一些數據:在MySQL程序中輸入以下命令:

mysql> create database AAA;
Query OK, 1 row affected (0.00 sec)

mysql> use AAA;
Database changed
mysql> create table BBB(id int);
Query OK, 0 rows affected (0.04 sec)

mysql> insert into BBB (id) values (1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into BBB (id) values (2);
Query OK, 1 row affected (0.01 sec)

mysql> insert into BBB (id) values (3);
Query OK, 1 row affected (0.01 sec)

此時,數據庫AAA中的數據庫表BBB中的內容如下所示:

mysql> select * from BBB;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.00 sec)

然後,使用MySQL的全量備份,備份整個AAA數據庫:

mysqldump -uroot -p123456 --databases AAA --flush-logs --single-transaction > /home/xu/AAA.sql

然後,我們再對數據庫AAA中的數據庫表BBB做一些操作:

mysql> insert into BBB (id) values (4);
Query OK, 1 row affected (0.01 sec)

mysql> update BBB set id=5 where id=3;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

此時,數據庫AAA中的數據庫表BBB的內容如下所示:

mysql> select * from BBB;
+------+
| id   |
+------+
|    1 |
|    2 |
|    5 |
|    4 |
+------+
4 rows in set (0.00 sec)

接著,不小心刪掉了數據庫AAA:

mysql> drop database AAA;
Query OK, 1 row affected (0.03 sec)

此時,迅速的查看當前使用的binlog文件:

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      818 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

這裏,查看這個binlog文件的內容:

mysql> show binlog events in mysql-bin.000003;
+------------------+-----+----------------+-----------+-------------+-----------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                    |
+------------------+-----+----------------+-----------+-------------+-----------------------------------------+
| mysql-bin.000003 |   4 | Format_desc    |         1 |         123 | Server ver: 5.7.18-1-log, Binlog ver: 4 |
| mysql-bin.000003 | 123 | Previous_gtids |         1 |         154 |                                         |
| mysql-bin.000003 | 154 | Anonymous_Gtid |         1 |         219 | SET @@SESSION.GTID_NEXT= ANONYMOUS    |
| mysql-bin.000003 | 219 | Query          |         1 |         290 | BEGIN                                   |
| mysql-bin.000003 | 290 | Table_map      |         1 |         335 | table_id: 254 (AAA.BBB)                 |
| mysql-bin.000003 | 335 | Write_rows     |         1 |         375 | table_id: 254 flags: STMT_END_F         |
| mysql-bin.000003 | 375 | Xid            |         1 |         406 | COMMIT /* xid=1777 */                   |
| mysql-bin.000003 | 406 | Anonymous_Gtid |         1 |         471 | SET @@SESSION.GTID_NEXT= ANONYMOUS    |
| mysql-bin.000003 | 471 | Query          |         1 |         542 | BEGIN                                   |
| mysql-bin.000003 | 542 | Table_map      |         1 |         587 | table_id: 254 (AAA.BBB)                 |
| mysql-bin.000003 | 587 | Update_rows    |         1 |         633 | table_id: 254 flags: STMT_END_F         |
| mysql-bin.000003 | 633 | Xid            |         1 |         664 | COMMIT /* xid=1778 */                   |
| mysql-bin.000003 | 664 | Anonymous_Gtid |         1 |         729 | SET @@SESSION.GTID_NEXT= ANONYMOUS    |
| mysql-bin.000003 | 729 | Query          |         1 |         818 | drop database AAA                       |
+------------------+-----+----------------+-----------+-------------+-----------------------------------------+
14 rows in set (0.00 sec)

從中,我們可以看見,最後一個命令正式刪除數據的操作。

所以,先恢復全量備份的數據庫文件AAA.sql, 在從增量備份文件mysql-bin.000003,恢復文件。因為恢復文件過程中,依然要在binlog中記錄,所以首先要刷新binlog文件:

mysql> flush logs;
Query OK, 0 rows affected (0.02 sec)

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000004 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

這樣,恢復過程中的記錄就不會再記錄到mysql-bin.000003中,造成死循環了。並且,在恢復過程中,一定要關閉對數據庫AAA的操作。

首先,手動創建數據庫AAA,然後使用恢復全量文件AAA.sql:

mysql> create database AAA;
Query OK, 1 row affected (0.00 sec)

mysql> use AAA;
Database changed
mysql> source /home/xu/AAA.sql
Query OK, 0 rows affected (0.00 sec)
(…………………………………………………………………………………………)
Query OK, 0 rows affected (0.00 sec)

此時,查詢數據庫,有如下結果:

mysql> select * from BBB;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.00 sec)

接著,從增量文件mysql-bin.000003中恢復BBB數據庫中的其他數據:

      恢復語法格式:
      # mysqlbinlog mysql-bin.0000xx | mysql -u用戶名 -p密碼 數據庫名

        常用選項:
          --start-position=953                   起始pos點
          --stop-position=1437                   結束pos點
          --start-datetime="2013-11-29 13:18:54" 起始時間點
          --stop-datetime="2013-11-29 13:21:53"  結束時間點
          --database=zyyshop                     指定只恢復zyyshop數據庫(一臺主機上往往有多個數據庫,只限本地log日誌)
            
        不常用選項:    
          -u --user=name              Connect to the remote server as username.連接到遠程主機的用戶名
          -p --password[=name]        Password to connect to remote server.連接到遠程主機的密碼
          -h --host=name              Get the binlog from server.從遠程主機上獲取binlog日誌
          --read-from-remote-server   Read binary logs from a MySQL server.從某個MySQL服務器上讀取binlog日誌

所以,這裏恢復命令是:

root@DESKTOP-M1SSCB1:/var/log/mysql# mysqlbinlog --stop-position=729 --database=AAA /var/log/mysql/mysql-bin.000003 | mysql -uroot -p123456 -v AAA

註意,在恢復的時候,一定要註意--stop-position這個命令,不然,很可能會使得drop命令還被執行。

再觀察數據庫,可以看到數據庫恢復成功:

mysql> select * from BBB;
+------+
| id   |
+------+
|    1 |
|    2 |
|    5 |
|    4 |
+------+
4 rows in set (0.00 sec)

5.通過腳本實現定時的備份

全量備份的腳本如下:

#!/bin/bash
export LANG=en_US.UTF-8
BakDir=/home/xu/mysql/backup
LogFile=/home/xu/mysql/backup/bak.log
Date=`date +%Y%m%d%H%M%S`
Begin=`date +"%Y年%m月%d日 %H:%M:%S"`
cd $BakDir
DumpFile=$Date.sql
GZDumpFile=$Date.sql.tgz
#--databases,指定數據庫,所有表格的表結構及其數據
#--flush-logs,產生新的日誌文件,binlog文件,這個在後面的增量備份有講到過
#--delete-master-logs,刪掉原來的日誌文件,binlog文件
#DumpFile是要備份的目標文件
mysqldump -uroot -p123456 --databases wordpressdb --flush-logs --single-transaction > $DumpFile
#tar -czvf $GZDumpFile $DumpFile
#rm $DumpFile

#只保留過去四周的數據庫內容
count=$(ls -l *.sql |wc -l)
if [ $count -ge 5 ]
then
file=$(ls -l *.sql |awk {print $9}|awk NR==1)
rm -f $file
fi

 
Last=`date +"%Y年%m月%d日 %H:%M:%S"`
echo 開始:$Begin 結束:$Last $GZDumpFile succ >> $LogFile

#恢復命令:在MySQL命令行裏面使用source命令  mysql> source /home/xu/mysql/backup/20180804104810.sql

然後,通過crontab來設置定時運行:

vi /etc/crontab

#每個星期日淩晨3:00執行完全備份腳本
0 3 * * 0 /......../databak.sh >/dev/null 2>&1

使上述定時任務生效:

crontab /etc/crontab

安全的web服務器——使用mysqldump和mysqlbinlog實現MySQL全量與增量備份