MySQL增量備份與恢復mysql
1、MySQL增量備份概念
使用mysqldump進行徹底備份,備份的數據中有重複數據,備份時間與恢復時間過長。而增量備份就是備份自上一次備份以後增長或改變的文件或內容。linux
增量備份的特色:
沒有重複數據,備分量不大,時間短。
恢復麻煩:須要上次徹底備份及徹底備份以後全部的增量備份才能恢復,並且要對全部增量備份進行逐個反推恢復。
MySQL 沒有提供直接的增量備份辦法,能夠經過 MySQL提供的二進制日誌(binarylogs(binlog))間接實現增量備份。sql
MySQL 二進制日誌對備份的意義:
二進制日誌保存了全部更新或者可能更新數據庫的操做。
二進制日誌在啓動 MySQL 服務器後開始記錄,並在文件達到max binlogIsize所設置的大小或者接收到 flush logs命令後從新建立新的日誌文件。.
[root@localhost~]# vim/etc/my.cnf數據庫
52 max_binlog_size=1024000 //二進制日誌最大 1Mvim
只需定時執行flush logs方法從新建立新的日誌,生成二進制文件序列,並及時把這些日誌保存到安全的地方就完成了一個時間段的增量備份。安全
要進行MySQL 的增量備份,首先要開啓二進制日誌功能,開啓 MySQL的二進制日誌功能。bash
方法一:MySQL的配置文件的[mysqld]項中加入log-bin=文件存放路徑/文件前綴,如log-bin=mysql-bin,而後重啓mysqld服務。默認此配置存在。服務器
[root@localhost ~]# awk /log-bin/"(print NR,$OY /etc/my.cnfsession
server-id=1
log-bin=mysql-bin架構
方法二:使用 mysqld-log-bin=文件存放路徑/文件前綴 從新啓動 mysqld 服務,每週選擇服務器負載較輕的時間段,或者用戶訪問較少的時間段進行備份。
2、MySQL增量恢復
應用場景:
一、人爲的SQL 語句破壞了數據庫
二、在進行下一次全備以前發生系統故障致使數據庫數據丟失
三、在主從架構中,主庫數據發生了故障
增量恢復的方法:
一、通常的恢復:備份的二進制日誌內容所有恢復.
格式:mysqlbinlog[--no-defaults]增量備份文件|mysql-u用戶名p密碼。
二、基於時間點的恢復:便於跳過某個發生錯誤的時間點實現數據恢復。
格式:從日誌開頭截止到某個時間點的恢復:
mysqlbinlog [--no-defaults] --stop-datetime=’年-月-日 小時:分鐘:秒 二進制日誌 |mysql-u用戶名-p密碼
從某個時間點到日誌結尾的恢復:
mysqlbinlog [--no-defaults] --start-datetime=’年-月-日 小時:分鐘:秒二進制日誌 |mysql-u用戶名 -p密碼
從某個時間點到某個時間點的恢復:
mysqlbinlog[--no-defaults] --start-datetime=’年-月-日 小時:分鐘:秒--stop-datetime='年-月-日-小時:分鐘:秒二進制日誌|mysql-u用戶名 -p密碼
3、制定企業備份策略的思路
一、肯定當前 mysql是處於哪一種表類型下工做的,它們支持事物處理仍是非事物的,由於咱們須要根據不一樣的特色來作一些設置。
二、要選擇備份的形式是徹底備份仍是增量備份,它們各有優缺點。
三、爲了保證恢復的完整性,咱們得開啓 binarylog功能,同時binlog給恢復工做也帶來了很大的靈活性,能夠基於時間點或是位置進行恢復。考慮到數據庫性能,咱們能夠將binlog_文件保存到其餘安全的硬盤中。
四、正如最初所提到的,備份操做和應用服務同時運行,這樣就十分消耗系統資源了,會致使數據庫服務性能降低,這就要求咱們選擇一個合適的時間(好比在應用負擔很小的時候)再來進行備份操做。
五、不是備份完就萬事大吉,咱們還得確認備份是否可用,因此以後的恢復測試是徹底有必要的。
根據數據更新頻繁,則應該較爲頻繁的備份
數據重要,則在有適當更新時進行備份
在數據庫壓力小的時段進行備份,如一週一次徹底備份,而後天天進行增量備份
中小公司,全備通常可一天一次
大公司可每週進行一次全備,天天進行一次增量備份
儘可能爲企業實現主從複製架構
4、案例演示
要進行MySQL的增量備份,首先要開啓MySQL二進制日誌功能
[root@localhost ~]# vim /etc/my.cnf
[mysqld]
server-id=1
log-bin=mysql-bin
[root@localhost ~]# systemctl restart mariadb
[root@localhost ~]# ls /var/lib/mysql/ //查看一下
[root@localhost ~]# mysqladmin -uroot -p123 flush-logs // 切一下日誌,開始使用第二個日誌
一、建立數據庫、表、錄入數據
MariaDB [(none)]> create database lty;
Query OK, 1 row affected (0.01 sec)
MariaDB [(none)]> use lty
Database changed
MariaDB [lty]> create table user_info(身份證 char(20) not null,姓名 char(20) not null,D號 char(10) not null,資費 int(10));
Query OK, 0 rows affected (0.01 sec)
MariaDB [lty]> desc user_info;
+-------------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+----------+------+-----+---------+-------+
| 身份證 | char(20) | NO | | NULL | |
| 姓名 | char(20) | NO | | NULL | |
| 性別 | char(4) | YES | | NULL | |
| 用戶ID號 | char(10) | NO | | NULL | |
| 資費 | int(10) | YES | | NULL | |
+-------------+----------+------+-----+---------+-------+
5 rows in set (0.00 sec)
MariaDB [lty]> insert into user_info values('000000006','張三','男','016','10');
Query OK, 1 row affected (0.01 sec)
MariaDB [lty]> insert into user_info values('000000006','李四','女','017','91');
Query OK, 1 row affected (0.01 sec)
MariaDB [lty]> insert into user_info values('000000006','王五','女','018','23');
Query OK, 1 row affected (0.01 sec)
MariaDB [lty]> select * from user_info;
+-----------+--------+--------+-------------+--------+
| 身份證 | 姓名 | 性別 | 用戶ID號 | 資費 |
+-----------+--------+--------+-------------+--------+
| 000000006 | 張三 | 男 | 016 | 10 |
| 000000006 | 李四 | 女 | 017 | 91 |
| 000000006 | 王五 | 女 | 018 | 23 |
+-----------+--------+--------+-------------+--------+
3 rows in set (0.00 sec)
二、建立一個文件夾用來作備份
[root@localhost ~]# mkdir /mysql_bak
三、對現有的三我的作一個完整備份
[root@localhost ~]# mysqldump -uroot -p123 lty user_info >/mysql_bak/lty_user_info-$(date +%F).sql // 對錶進行完整備份
[root@localhost ~]# mysqldump -uroot -p123 --databases lty > /mysql_bak/lty-$(date +%F).sql //對庫進行完整備份
[root@localhost ~]# ls /mysql_bak/ //查看
lty-2019-10-14.sql lty_user_info-2019-10-14.sql
四、切一個日誌
[root@localhost ~]# mysqladmin -uroot -p123 flush-logs
五、再插入兩條記錄
MariaDB [lty]> insert into user_info values('000000009','趙六','男','019','37');
Query OK, 1 row affected (0.01 sec)
MariaDB [lty]> insert into user_info values('000000010','孫七','男','020','36');
Query OK, 1 row affected (0.00 sec)
六、再切一個日誌,生成了4號日誌,可是我要用的日誌是3號日誌
[root@localhost ~]# mysqladmin -uroot -p123 flush-logs
[root@localhost ~]# ls /var/lib/mysql/
aria_log.00000001 client ib_logfile0 mysql mysql-bin.000003 mysql.sock
aria_log_control crushlinux ib_logfile1 mysql-bin.000001 mysql-bin.000004 performance_schema
auth ibdata1 lty mysql-bin.000002 mysql-bin.index test
七、實驗文檔裏用的是2好日誌,拿走3號更名03
[root@localhost ~]# cp /var/lib/mysql/mysql-bin.000003 /mysql_bak/mysql-bin.000002
八、做分析:
[root@localhost ~]# mysqlbinlog --no-defaults /mysql_bak/mysql-bin.000002
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#191014 15:02:53 server id 1 end_log_pos 245 Start: binlog v 4, server v 5.5.41-Mari91014 15:02:53
BINLOG '
nR2kXQ8BAAAA8QAAAPUAAAAAAAQANS41LjQxLU1hcmlhREItbG9nAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAA2QAEGggAAAAICAgCAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAx8QIRg==
'/*!*/;
# at 245
#191014 15:04:21 server id 1 end_log_pos 312 Query thread_id=4 exec_time=0
SET TIMESTAMP=1571036661/*!*/;
SET @@session.pseudo_thread_id=4/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checutocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.colla*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
# at 312
#191014 15:04:21 server id 1 end_log_pos 441 Query thread_id=4 exec_time=0
use `lty`/*!*/;
SET TIMESTAMP=1571036661/*!*/;
insert into user_info values('000000009','趙六','男','019','37')
/*!*/;
# at 441
#191014 15:04:21 server id 1 end_log_pos 468 Xid = 80
COMMIT/*!*/;
# at 468
#191014 15:04:52 server id 1 end_log_pos 535 Query thread_id=4 exec_time=0
SET TIMESTAMP=1571036692/*!*/;
BEGIN
/*!*/;
# at 535
#191014 15:04:52 server id 1 end_log_pos 664 Query thread_id=4 exec_time=0
SET TIMESTAMP=1571036692/*!*/;
insert into user_info values('000000010','孫七','男','020','36')
/*!*/;
# at 664
#191014 15:04:52 server id 1 end_log_pos 691 Xid = 81
COMMIT/*!*/;
# at 691
#191014 15:06:56 server id 1 end_log_pos 734 Rotate to mysql-bin.000004 pos: 4
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
其中有後來插入的兩條信息記錄
九、模擬誤操做刪除user_info表,並查看
[root@localhost ~]# mysql -uroot -p123 -e 'drop table lty.user_info;'
[root@localhost ~]# mysql -uroot -p123 -e 'select * from lty.user_info;'
ERROR 1146 (42S02) at line 1: Table 'lty.user_info' doesn't exist
十、先恢復完整備份
[root@localhost ~]# mysql -uroot -p123 lty < /mysql_bak/lty_user_info-2019-10-14.sql
[root@localhost ~]# mysql -uroot -p123 -e 'select * from lty.user_info;'
+-----------+--------+--------+-------------+--------+
| 身份證 | 姓名 | 性別 | 用戶ID號 | 資費 |
+-----------+--------+--------+-------------+--------+
| 000000006 | 張三 | 男 | 016 | 10 |
| 000000006 | 李四 | 女 | 017 | 91 |
| 000000006 | 王五 | 女 | 018 | 23 |
+-----------+--------+--------+-------------+--------+
完整備份裏只有三我的的信息,剩下兩我的的信息要靠增量的二進制日誌來進行恢復
十一、恢復增量備份:
[root@localhost ~]# mysqlbinlog --no-defaults /mysql_bak/mysql-bin.000002 | mysql -u root -p123 //將日誌中的全部的語句都執行了一遍
[root@localhost ~]# mysql -uroot -p123 -e 'select * from lty.user_info;'
+-----------+--------+--------+-------------+--------+
| 身份證 | 姓名 | 性別 | 用戶ID號 | 資費 |
+-----------+--------+--------+-------------+--------+
| 000000006 | 張三 | 男 | 016 | 10 |
| 000000006 | 李四 | 女 | 017 | 91 |
| 000000006 | 王五 | 女 | 018 | 23 |
| 000000009 | 趙六 | 男 | 019 | 37 |
| 000000010 | 孫七 | 男 | 020 | 36 |
+-----------+--------+--------+-------------+--------+
數據信息徹底恢復了。
試一下有條件的增量恢復二進制日誌:
只恢復到有趙六的數據:
[root@localhost ~]# mysql -uroot -p123 -e 'drop table lty.user_info;'
[root@localhost ~]# mysql -uroot -p123 -e 'select * from lty.user_info;'
ERROR 1146 (42S02) at line 1: Table 'lty.user_info' doesn't exist
[root@localhost ~]# mysql -uroot -p123 lty < /mysql_bak/lty_user_info-2019-10-14.sql //先恢復完整備份
[root@localhost ~]# mysqlbinlog --no-defaults --stop-datetime='2019-10-14 15:04:35' /my.000002 | mysql -u root -p123
[root@localhost ~]# mysql -uroot -p123 -e 'select * from lty.user_info;'
+-----------+--------+--------+-------------+--------+
| 身份證 | 姓名 | 性別 | 用戶ID號 | 資費 |
+-----------+--------+--------+-------------+--------+
| 000000006 | 張三 | 男 | 016 | 10 |
| 000000006 | 李四 | 女 | 017 | 91 |
| 000000006 | 王五 | 女 | 018 | 23 |
| 000000009 | 趙六 | 男 | 019 | 37 |
+-----------+--------+--------+-------------+--------+
只恢復到有孫七的數據:
[root@localhost ~]# mysql -uroot -p123 -e 'drop table lty.user_info;'
[root@localhost ~]# mysql -uroot -p123 -e 'select * from lty.user_info;'
ERROR 1146 (42S02) at line 1: Table 'lty.user_info' doesn't exist
[root@localhost ~]# mysql -uroot -p123 lty < /mysql_bak/lty_user_info-2019-10-14.sql
[root@localhost ~]# mysqlbinlog --no-defaults --start-datetime='2019-10-14 15:04:35' /mysql_bak/mysql-bin.000002 | mysql -u root -p123
[root@localhost ~]# mysql -uroot -p123 -e 'select * from lty.user_info;'
+-----------+--------+--------+-------------+--------+
| 身份證 | 姓名 | 性別 | 用戶ID號 | 資費 |
+-----------+--------+--------+-------------+--------+
| 000000006 | 張三 | 男 | 016 | 10 |
| 000000006 | 李四 | 女 | 017 | 91 |
| 000000006 | 王五 | 女 | 018 | 23 |
| 000000010 | 孫七 | 男 | 020 | 36 |
+-----------+--------+--------+-------------+--------+
基於位置控制恢復:
[root@localhost ~]# mysql -uroot -p123 -e 'drop table lty.user_info;'
[root@localhost ~]# mysql -uroot -p123 -e 'select * from lty.user_info;'
ERROR 1146 (42S02) at line 1: Table 'lty.user_info' doesn't exist
[root@localhost ~]# mysql -uroot -p123 lty < /mysql_bak/lty_user_info-2019-10-14.sql
[root@localhost ~]# mysqlbinlog --no-defaults --stop-position='468' /mysql_bak/mysql-bi-u root -p123
[root@localhost ~]# mysql -uroot -p123 -e 'select * from lty.user_info;'
+-----------+--------+--------+-------------+--------+
| 身份證 | 姓名 | 性別 | 用戶ID號 | 資費 |
+-----------+--------+--------+-------------+--------+
| 000000006 | 張三 | 男 | 016 | 10 |
| 000000006 | 李四 | 女 | 017 | 91 |
| 000000006 | 王五 | 女 | 018 | 23 |
| 000000009 | 趙六 | 男 | 019 | 37 |
+-----------+--------+--------+-------------+--------+
5、企業數據庫備份腳本
一、完整備份腳本
[root@localhost ~]# vim /opt/mysql_bak_wanbei.sh
#!/bin/bash
# MySQL數據庫備份腳本
# 設置登陸變量
MY_USER="root"
MY_PASS="123"
MY_HOST="192.168.200.111"
MY_CONN="-u$MY_USER -p$MY_PASS -h$MY_HOST"
# 設置備份的數據庫(或表)
MY_DB="lty"
# 定義備份路徑、工具、時間、文件名
BF_DIR="/mysql_bak/wanbei"
BF_CMD="/usr/bin/mysqldump"
BF_TIME=$(date +%Y%m%d-%H%M)
NAME="$MY_DB1-$BF_TIME"
# 備份爲.sql腳本,而後打包壓縮(打包後刪除原文件)
[ -d $BF_DIR ] || mkdir -p $BF_DIR
cd $BF_DIR
$BF_CMD $MY_CONN --databases $MY_DB > $NAME.sql
/bin/tar zcf $NAME.tar.gz $NAME.sql --remove &>/dev/null
二、增量備份
[root@localhost ~]# vim /opt/mysql_bak_zengbei.sh
#!/bin/bash
# MySQL數據庫備份腳本
# 設置登陸變量
MY_USER="root"
MY_PASS="123"
MY_HOST="192.168.200.111"
MY_CONN="-u$MY_USER -p$MY_PASS -h$MY_HOST"
#定義備份路徑、工具、二進制日誌前綴、二進制日誌存放路徑
BF_TIME="$(date +%Y%m%d)"
BF_DIR="/mysql_bak/zengbei/$BF_TIME"
CMD="/usr/bin/mysqladmin"
QZ="mysql-bin"
LOG_DIR="/var/lib/mysql"
#拷貝二進制日誌
[ -d $BF_DIR ] || mkdir -p $BF_DIR
$CMD $MY_CONN flush-logs
/bin/cp -p$(ls $LOG_DIR/$QZ.* | awk -v RS="" '{print $(NF-2)}') $BF_DIR
[root@localhost ~]# chmod +x /opt/mysql_bak_*
[root@localhost ~]# crontab -e
0 0 * * 1 /opt/mysql_bak_wanbei.sh //每週一零點進行完備
0 0 * * 2-7 /opt/mysql_bak_zengbei.sh //每週二至周天零點進行增量備份