1.全量備份
全量備份就是把數據庫中所有的數據進行備份。
備份所有庫:
mysqldump -uroot -p456 -S /data/3306/mysql.sock -F -A -B |gzip >/server/backup/mysqlbak_$(date+%F).sql.gz

備份一個庫:
mysqldump -uroot -p456 -S /data/3306/mysql.sock -F -B oldboy|gzip >/server/backup/mysqlbak_$(date+%F).sql.gz

2.增量備份
從上次全備之后,到下次全備之前更新的新數據。對於mysql來說,binlog日志就是mysql的增量數據。
1)按天備份
| 周一00點全量備份 | 周二00點全量備份 |
| 01.sql.gz | 02.sql.gz |
| 周一增量備份 | 周二增量備份 |
| mysql-bin.000021 mysql-bin.000022 mysql-bin.000023 ... |
mysql-bin.000035 mysql-bin.000036 mysql-bin.000037 ... |
優點:
恢復時間:短,維護成本:低
缺點:
占用空間:多,占用資源:多,經常鎖表影響用戶體驗
2)按周備份
| 周六00點全量備份 | ||
| 01.sql.gz | ||
| 周一增量備份 | 周二增量備份 | 周三增量備份 |
| mysql-bin.000021 mysql-bin.000022 mysql-bin.000023 ... |
mysql-bin.000035 mysql-bin.000036 mysql-bin.000037 ... |
mysql-bin.000043 mysql-bin.000044 mysql-bin.000045 ... |
優點:
占用空間:小,占用資源:少,無需鎖表用戶體驗相對好
缺點:
恢復時間:長、復雜,維護成本:高
3.從企業的角度看全量和增量
1)對於中小公司,全量一般每天一次,在業務量低估時執行全備並鎖表;
2)對於單台數據庫如何實現增量。利用rsync(配合定時任務頻率高點,或者inotify主從復制)把所有binlog備份到遠程服務器。但是盡量還是要做主從復制!
3)對於大公司,有可能會做周備,其他時間都是增量;
4)一主多從,會有一個從庫做備份,延遲同步;
>>>需要mysql的mysqldump全量備份場合:
遷移或升級數據庫;
增加從庫的時候;
由於硬件或異常情況導致的主庫或從庫宕機,主從可互相切換,無需備份;但是由於人為操作導致主庫誤刪,主從都會執行,此時需要備份;
做跨機房災備,需要全量備份到異地。
>>>需要mysql的增量恢復場合:
人為操作導致主庫誤刪(如drop),主從都會執行,此時需要增量備份;
只有一個主庫的情況下需要增量恢復。
4.實戰----模擬操作失誤導致數據丟失進行恢復的過程
>>>思路一:
mysql -uroot -p456 -S /data/3306/mysql.sock
mysql> use oldboy
mysql> show tables;
mysql> select * from student;
mysql> quit
date -s '2018/10/05'
history |grep mysqld
mysqldump -uroot -p456 -S /data/3306/mysql.sock -F -B --master-data=2 oldboy|gzip >/server/backup/bak_$(date+%F).sql.gz #假設現在是00點,一般全量備份只要指定為master-data=2,master-data的作用就是為拿到開始恢復的位置點,以便后面的增量備份有所依據,其他全備已存在不用更新;建立從庫才需要指定master-data=1告訴從庫從主庫的哪個位置進行更新,只需做全備無需增量備份。最好記錄切割前的mysql-bin位置點(可以通過鎖表看下master.info中記錄的信息)
mysql -uroot -p456 -S /data/3306/mysql.sock
mysql> use oldboy
mysql> desc student;
mysql> insert into student(name) values('oldboy101');
mysql> insert into student(name) values('oldboy102'); #模擬00點到早上10點的增量
mysql> select * from student;
mysql> drop database oldboy; #模擬早上10點做的誤操作,應用開始出現故障
mysql> quit
通過防火牆禁止web等應用向主庫寫數據或者主庫鎖表,讓主庫暫時停止更新,進行數據恢復
ll /server/backup
gzip -d bak_2018-10-05.sql.gz
grep -i "change" bak_2018-10-05.sql #如果先前忘記查看位置點,可以嘗試在此找到,假設為000014
mysqladmin -uroot -p456 -S /data/3306/mysql.sock flush-logs #刷新binlog,將恢復的目標定到上步找到的位置,下面一個binlog則是新產生的了
cd /data/3306/
cp mysql-bin.000014 /server/backup/
cd /server/backup/
mysqlbinlog -d oldboy mysql-bin.000014 >bin.sql
vi bin.sql 將drop database oldboy這句刪掉,並保存文件
mysql -uroot -p456 -S /data/3306/mysql.sock
mysql -uroot -p456 -S /data/3306/mysql.sock <bak_2018-10-05.sql
mysql -uroot -p456 -S /data/3306/mysql.sock oldboy <bin.sql
mysql -uroot -p456 -S /data/3306/mysql.sock
mysql> use oldboy
mysql> select * from student; #發現恢復成功
{補充:
mysql> show variables like '%log_bin%'; #有個參數sql_log_bin,如果關掉此參數,則利用mysqldump進行恢復的時候,就不會記錄新的binlog日志mysql-bin.000015中}
>>>思路二:
1)停止一個從庫,然后在主庫刷新binlog,把mysql-bin.000014恢復成bin.sql(去掉drop語句的)
2)把全備bak_2018-10-05.sql及10點前的增量bin.sql恢復到從庫
3)此時數據丟失多少?10點刷新binlog以后的數據,即mysql-bin.000015
4)停止主庫,快速把mysql-bin.000015解析為SQL,恢復到從庫 #避免主鍵沖突問題,盡量使停庫時間縮到最短,盡量減少應用停止的時間
5)切換到從庫提供服務
>>>增量恢復小結:
人為SQL造成的誤操作;
需准備全備和增量;
恢復時建議對外停止更新;
恢復全量,然后把增量日志中有問題的SQL語句刪除,恢復數據庫
>>>增量恢復的核心思想:
流程制度控制,否則將面臨服務和數據故障的風險;
可以通過延遲備份來解決,或者通過監控,或者通過制定黑、白名單(where子句)機制來控制;
選擇停庫修復,定義可量化的目標,滿足業務需求的最低限制
5.mysqlbinlog增量備份
作用:解析mysql的binlog日志 #mysql-bin.0000XX,mysql-bin.index記錄了所有mysql-bin文件
mysql內部增刪改查等對mysql數據庫有更新記錄的文件,即mysql-bin文件
-d 指定單獨的數據庫恢復 #適用於對單個庫做了誤操作,只需恢復此庫的備份恢復操作
--start-position --stop-position 指定位置恢復 mysqlbinlog mysql-bin.000020 --start-position=365 --stop-position=456 -r pos.sql
--start-datetime --stip-datetime 指定時間點恢復 mysqlbinlog mysql-bin.000020 --start-datetime='2018-10-06 15:00:00' --stop-datetime='2018-10-06 15:09:00' -r time.sql
【思考】
>>mysql出現同步延遲原因是什么?如何解決?
當主庫的TPS並發較高時,產生的DDL(修改類的sql語句)數量,超過了slave機器sql線程所能承受的能力,那么延時就會產生了。
>>解決方式
數據庫的讀寫分離軟件,mysql-proxy和amoeba;
了解mysql高可用MMM技術;
mysql半同步應用,xtrabackup物理備份;
mysql+heartbeat+drbd高可用;
2018年11月2日
祝好!
