Mysql之備份與恢復


Mysql備份常用方法(邏輯備份和物理備份)

邏輯備份mysqldump
  恢復時通過mysqldump命令備份的sql語句還原到mysql數據庫中
  補充,增量備份備份binlog日志文件即可,恢復增量即通過mysqlbinlog工具截取binlog日志轉換成sql語句,通過mysql或source進行語句還原
物理備份備份方法
  使用cp,rsync,tar,scp等工具,由於在備份期間數據依然在寫數據,所以直接復制會引起數據丟失,在恢復數據庫時,對新數據庫的路徑,配置也有要求,一般要和遠程保持一致。為了確保數據一致性,可以選擇人工停庫或者鎖庫后進行。但是一般生產部允許,除非可以申請停機或鎖表
      物理備份兩部:1、停庫或鎖表,打包拷貝  2、第三方xtrabackup

 

企業場景全量和增量的頻率
1、中小公司,全量一般每天一次,業務流量低谷進行,備份時鎖表
         增量:定時,例如每分鍾rsync推一次binlog
2、大公司,一般周備,節省備份時間,減小備份壓力,缺點是binlog文件副本太多,還原比較麻煩
3、一主錯從環境,主從復制本身就是實時遠程備份,可以解決物理故障
4、一主多從環境,可以采取一個從庫上專門進行備份,通過延時同步解決人為誤操作

 

mysql全量備份與增量備份

按天全備

周一0點全量備份           周二0點全量備份                                          
01.sql.gz 02.sql.gz
周一增量備份 周二增量備份
mysql-bin.00025
mysql-bin.00026
..........
mysql-bin.index
mysql-bin.00035
mysql-bin.00036
..............
 mysql-bin.index

優點:恢復時間短,維護成本低

缺點:暫用時間多,暫用系統資源多,經常鎖表影響客戶體驗

 

 

 

 

 

 

 

 

按周全備

        周六0點全量備份                 
周一增量備份 周二增量數據 周三增量數據 周四增量數據
mysql-bin.00025
mysql-bin.00026
mysql-bin.00027
...........
 mysql-bin.index
mysql-bin.00035
mysql-bin.00036
mysql-bin.00037
.............
mysql-bin.index
mysql-bin.00040
mysql-bin.00041
mysql-bin.00042
..............
mysql-bin.index
mysql-bin.00050
mysql-bin.00051
mysql-bin.00052
..............
mysql-bin.index

 優點:暫用空間小,暫用系統資源少,無需鎖表或次數少,用戶體驗好些
缺點:維護成本高,恢復麻煩,時間長

 

 

 

 

 

 

 

 

MySql的備份命令

  myisam引擎
    #mysqldump -uroot -pxxx -A -B -F --master-data=2  -x --events >/opt/name.sql.gz
   innodb引擎
    #mysqldump -uroot -pxxx  -A -B -F --master-data=2 --events --single-transaction | gzip>/opt/name.sql.gz

--master-data
  這個參數在建立slave數據庫的時候會用到,當這個參數的值為1的時候,mysqldump出來的文件就會包括CHANGE MASTER TO這個語句,CHANGE MASTER TO后面緊接着就是file和position的記錄,file和position記錄的位置就是slave從master端復制文件的起始位置。默認情況下這個值是1
  當這個值是2的時候,chang master to也是會寫到dump文件里面去的,但是不會有上面那個作用了
--master-data=1   (--master-data=2注釋)
  表示在dump過程中記錄主庫的binlog和pos點,並在dump文件中不注釋掉這一行,即恢復時會執行;
-F   切割binlog參數
-A   備份所有庫 
-B, --databases   備份數據時使用-B參數,會在備份數據中增加建庫及use庫的語句   使用-B參數,后面可以接多個庫,否則只能有一個庫,之后的都被認為是表
--single-transaction 適合innodb事務數據庫備份(可代替鎖表)   設置事務的隔離級別為可重復讀,即REPEATABLE READ,這樣能保證在一個事務中所有相同的查詢讀取到同樣的數據,也就大概保證了在dump期間,如果其他innodb引擎的線程修改了表的數據並提交,對該dump線程的數據並無影響. :InnoDB 表在備份時,通常啟用選項 --single-transaction 來保證備份的一致性,實際上它的工作原理是設定本次會話的隔離級別為:REPEATABLE READ,以確保本次會話(dump)時,不會看到其他會話已經提交了的數據。
-x,--lock-all-tables    Locks all tables across all databases. This is achieved by taking a global read lock for the duration of thewhole dump. Automatically turns --single-transaction and --lock-tables off.
-l, --lock-tables   Lock all tables for read.
mysql其他常用參數
--default-character-set=latin1 指定字符集(一般不用)
-d  只備份表結構
-t  只備份數據
-T,--tab  分離表和數據,數據是文本
-R  備份存儲過程
-q  Don't buffer query, dump directly to stdout.(Defaults to on; use --skip-quick to disable.)

鎖表備份

1、mysql> flush table with read lock;  鎖表 (窗口不能退出,不然失效)
2、新開窗口進行導出備份(如果數據量大,且允許停機,就使用停機打包,而不用dump)
  #mysqldump -uroot -pxxx --events  -A -B  --master-data=2| gzip >/opt/bak_$(date  +%F).sql.gz
3、mysql> unlock tables;  解鎖

數據庫表的備份

# mysqldump -uroot -pxxx databasename table1 table2 table3 >/opt/table.sql


案例:多個庫和多個表備份到一起了,如何恢復單個庫或表

  1、將備份導入測試庫,然后把需要的備份出來,恢復到正式庫
  2、 單表:grep tablename bak.sql> name.sql
      單庫:循環過濾庫里所有表
  3、 事先分庫分表備份 

分庫備份命令

#mysql -uroot -prootabcd -e "show databases;" | grep -Evi "Database|information_schema|performance_schema" | sed -r 's#(.*)#mysqldump -uroot -prootabcd --events -B \1 |gzip >/tmp/\1.sql.gz#g'| bash

分庫備份腳本

#!/bin/sh
MYUSER=root
MYPASS=rootabcd
[ ! -d /server/backup/ ] && mkdir -p /server/backup  -p
MYCMD="mysql -u$USER -p$MYPASS"
MYDUMP="mysqldump -u$MYUSER -p$MYPASS -B "
for database in `$MYCMD -e "show databases;" | grep -Evi "Database|information_schema|performance_schema|mysql"`
do
        $MYDUMP $database | gzip> /server/backup/${database}_$(date +%F).sql.gz
done

 

==============================================================================
數據庫優化
1、insert批量插入
2、不要用*,列出查詢列,指定范圍
select id,name from test
select id,name from test limit 2;
select id,name from test where id=1;
select id,name from test where name="oldgirl"; 字符串查詢帶引號
select id,name from test where name="oldgirl" or id=5;
select id,name from test where id>2 and id<4;
select SQL_NO_CACHE  id,name from test where id>2 and id<4; 不查緩存

排序(order by的列也可以考慮建索引)
select id,name from test order by id asc;
select id,name from test order by id desc;    逆序



刷新binlog參數(logbin文件生效參數log-bin)
binlog日志生成,每次重啟和-F參數重新生成,以及超過1.1G后重新生成

mysqldump用於對某一時刻的數據全備,例如在0點進行備份bak.sql.gz
增量備份:當有數據寫入到數據庫時,還會同時把更新的sql語句寫入到對應文件里,即binlog文件
10點丟失數據需要恢復,處理方法如下:
a、將0點時刻的備份bak.sql.gz數據還原,即數據庫數據截至時間為00點
b、0點到10點的數據,從binlog里恢復


知識技巧
binlog日志切割(即刷新binlog)確定全備和增量備份的臨界點。備份時候加-F(--flush-logs)參數,刷新binlog,生成新文件,將來增量恢復從這個文件開始
[root@test85 3306]# mysqldump -uroot -poldboy123 -S /data/3306/mysql.sock -F -d oldboy student >t2.sql
然后記錄下ls 出binlog位置(發到郵箱或寫到log),恢復時從新刷新的binlog中提取數據



利用source命令恢復數據庫(用的不多)
1、登陸數據庫
2、mysql>use oldboy
3、使用source命令,后面接腳本文件mysql>source oldboy_db.sql 給文件系統路徑,默認是登陸mysql前的文件系統路徑。(注意編碼 utf8無簽名)

利用mysql命令恢復數據庫[配置文件中有mysqldump參數模塊可以設置]
[mysqldump]
quick
max_allowed_packet = 8M

1、指定庫恢復
#mysql -uroot -poldboy123 -S /data/3306/mysql.sock  oldboy<1.sql (備份oldboy庫的時候如果加了-B,這邊都不用加庫名了)

針對壓縮的備份數據恢復
方法一(建議此種)
gzip -d /opt/mysql_bak.sql.gz
mysql -uroot -prootabcd < /opt/mysql_bak.sql
方法二
gunzip< mysql_bak.sql.gz >/opt/ mysql_bak.sql
mysql -uroot -pxxx < /opt/mysql_bak.sql
或者
gunzip <mysql_bak.sql.gz | mysql -uroot -pxxx


mysqlbinlog工具解析binlog日志實踐
1、解析指定庫的binlog日志,利用-d參數指定庫
平時插入數據記錄時,先use 庫 在insert。如果是insert into database.table values就不行
[root@test85 3306]# mysqlbinlog -d oldboy mysql-bin.000001 |egrep -v "^#|--|^$|\*"
mysqlbinlog截取位置
mysqlbinlog mysqlbin.000020 --start-position=365 --stop-position=456 -r pos.sql     -r 輸出到文件
用時間不精確
mysqlbinlog mysqlbin.000020 --start-datetime='2014-10-16 15:44' --stop-datetime=='2014-10-17 15:44' -r time.sql
(測試中發現時間及位置均不包括結束點)
mysqlbinlog命令--解析binlog日志為sql語句
    -d參數根據指定庫拆分binlog(單表根據關鍵字過濾)
    --start-datetime=name --stop-datetime=name
    --start-position=# --stop-position=#
    -r, --result-file=name  相當於重定向
    解析row語句:mysqlbinlog --base64-output=“decode-rows” --verbose mysql-bin.000001


binlog的刪除
mysql>reset master   binlog全部干掉
mysql>purge master logs to 'mysql-bin.00004'刪除之前的日志 (不包括0004)
# grep expire /data/3306/my.cnf     配置文件自動刪
expire_logs_days = 7     自動刪除7天前的備份 

以上很類似mysql innodb引擎的--single-transaction備份策略

mysql備份方案
如果是單機備份環境,如果大於1台服務器一定要做主從復制
1、主從本身就是備份,而且是實時備份。主從同步的功能本身就是解決物理故障宕機的實時備份方案。缺點:不能防止邏輯故障數據丟失

選擇從庫備份
1)選擇一個不對外提供業務的從庫做備份
2)開啟binlog
3)備份時可以鎖表也可以停止sql_thread, 不停io_thread,即暫停應用sql。備份期間,如果主庫掛了,那么,從庫備份加上備份后的binlog就是完整的主庫內容。
4)數據量小於50G,mysqldump足夠,如果數據量大於50G,xtrabackup物理工具。或者從庫停止sql_thread,cp或打包的方案(還原主庫----biglog-----停thread的那個點到打開)
5)1主5從,3從對外LVS集群提供服務,1個從定時任務,開發,后台用,最后一個啥也不干,最大限度保持和主一致(還原時,刪除中繼日志,其他change master 切換為主庫)

mysql增量恢復條件
1、開啟了log-bin日志功能(主從庫都需開啟了)(位置點)
至少存在全備加上全備之后的時刻到出問題時刻的所有增量binlog文件
2、存在mysql數據庫全備

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM