MySQL xtrabackup 物理備份原理解析
一、簡介
xtrabackup 是percona公司開源的MySQL innodb物理備份工具,支持在線熱備(備份時不影響數(shù)據(jù)讀寫),在工具在業(yè)內(nèi)生產(chǎn)上被大量使用,本次使用xtrabackup 備份的日志和數(shù)據(jù)庫general 日志來對備份的流程和原理進行解讀。
二、xtrabackup備份原理:
1、xtrabackup 之所以可以通過復(fù)制 InnoDB 表的 ibd 文件工作,是由于 InnoDB 內(nèi)部維護了一個重做日志(redo log)。redo log包含了每次 InnoDB 會更改數(shù)據(jù)的記錄。當(dāng) Innodb 啟動時,它會檢查數(shù)據(jù)文件并重做日志,并執(zhí)行以下兩步操作:應(yīng)用已經(jīng)提交的事務(wù)(前滾),回滾那些未提交的事務(wù)(回滾)
2、Xtrabackup在啟動時會記住log sequence number(LSN),并且復(fù)制所有的數(shù)據(jù)文件。同時xtrabackup會運行一個后臺進程,用于監(jiān)視事務(wù)日志,并從事務(wù)日志復(fù)制最新的修改。所以xtrabackup自啟動開始,就不停的將事務(wù)日志中每個數(shù)據(jù)文件的修改都記錄下來。
3、innobackupex不支持在線備份MyISAM表,當(dāng)xtrabackup復(fù)制完innodb數(shù)據(jù)文件后,會執(zhí)行FLUSH TABLES WITH READ LOCK來阻止新的寫入進來并把MyISAM表數(shù)據(jù)刷到硬盤上,之后復(fù)制MyISAM數(shù)據(jù)文件,最后釋放鎖。
4、準(zhǔn)備(prepare)過程,xtrabackup使用之前復(fù)制的事務(wù)日志,對各個數(shù)據(jù)文件執(zhí)行災(zāi)難恢復(fù)(就像mysql剛啟動時要做的一樣),將表數(shù)據(jù)前滾到FLUSH TABLES WITH READ LOCK的時間點;所以myisam表數(shù)據(jù)與InnoDB表數(shù)據(jù)是同步的。類似oracle的,InnoDB的prepare過程可以稱為recover(恢復(fù)),myisam的數(shù)據(jù)復(fù)制過程可以稱為restore(還原)。
注:InnoDB 和非 InnoDB 文件的備份都是通過拷貝文件來做的,但是實現(xiàn)的方式不同,前者是以page為粒度做的(xtrabackup),后者是 cp 或者 tar 命令(innobackupex),xtrabackup 在讀取每個page時會校驗 checksum 值,保證數(shù)據(jù)塊是一致的,而 innobackupex 在 cp MyISAM 文件時已經(jīng)做了flush(FTWRL),磁盤上的文件也是完整的,所以最終備份集里的數(shù)據(jù)文件都是寫入完整的。
三、xtrabackup備份流程
1、innobackupex 在啟動后,會先 fork 一個進程,啟動 xtrabackup進程,記錄當(dāng)前的LSN號,然后就等待 xtrabackup 備份完 ibd 數(shù)據(jù)文件;
2、xtrabackup 在備份 InnoDB 相關(guān)數(shù)據(jù)時,是有2種線程的,1種是 redo 拷貝線程,負責(zé)拷貝 redo 文件,1種是 ibd 拷貝線程,負責(zé)拷貝 ibd 文件;redo 拷貝線程只有一個,在 ibd 拷貝線程之前啟動,在 ibd 線程結(jié)束后結(jié)束。xtrabackup 進程開始執(zhí)行后,先啟動 redo 拷貝線程,從最新的 checkpoint 點開始順序拷貝 redo 日志;然后再啟動 ibd 數(shù)據(jù)拷貝線程,在 xtrabackup 拷貝 ibd 過程中,innobackupex 進程一直處于等待狀態(tài)(等待文件被創(chuàng)建)。
3、xtrabackup 拷貝完成idb后,通知 innobackupex(通過創(chuàng)建文件),同時自己進入等待(redo 線程仍然繼續(xù)拷貝);
4、innobackupex 收到 xtrabackup 通知后,執(zhí)行FLUSH TABLES WITH READ LOCK (FTWRL),取得一致性位點,然后開始備份非 InnoDB 文件(包括 frm、MYD、MYI、CSV、opt、par等)??截惙?InnoDB 文件過程中,因為數(shù)據(jù)庫處于全局只讀狀態(tài),如果在業(yè)務(wù)的主庫備份的話,要特別小心,非 InnoDB 表(主要是MyISAM)比較多的話整庫只讀時間就會比較長,這個影響一定要評估到。
5、當(dāng) innobackupex 拷貝完所有非 InnoDB 表文件后,通知 xtrabackup(通過刪文件) ,同時自己進入等待(等待另一個文件被創(chuàng)建);
6、xtrabackup 收到 innobackupex 備份完非 InnoDB 通知后,就停止 redo 拷貝線程,然后通知 innobackupexredo log 拷貝完成(通過創(chuàng)建文件);
7、innobackupex 收到 redo 備份完成通知后,就開始解鎖,執(zhí)行 UNLOCK TABLES;
8、最后 innobackupex 和 xtrabackup 進程各自完成收尾工作,如資源的釋放、寫備份元數(shù)據(jù)信息等,innobackupex 等待 xtrabackup 子進程結(jié)束后退出。
四、xtrabackup常用命令選項:
完整的選項使用請執(zhí)行innobackupex –help,這里只介紹使用常用的選項進行完整備份及增量備份和還原,這里只對常用參數(shù)進行描述
-u, --user=name:備份時連接數(shù)據(jù)的用戶名稱。
-H, --host=name:指定數(shù)據(jù)庫的 IP 地址或者主機名(如果主機名可以解析的話)
-P, --port=#:連接數(shù)據(jù)庫的端口號。
-p, --password=name:連接數(shù)據(jù)庫用戶的密碼。
-S, --socket=name:該選項接受一個字符串參數(shù),可以指定使用 UNIX 套接字的方式連接到本地數(shù)據(jù)庫。
–defaults-file 數(shù)據(jù)庫的配置文件路徑,感覺本地備份不寫也可以,遠程沒測試過。
–no-timestamp 創(chuàng)建備份時不自動生成時間目錄,可以自定義備份目錄名例如: /backups/mysql/base
–databases 用于指定要備份的數(shù)據(jù)庫, 多個庫文件使用方法: “database1 database2″,對innodb表無用
–incremental 在全備份的基礎(chǔ)上進行增量備份,后跟增量備份存貯目錄路徑
–incremental-basedir=DIRECTORY 增量備份所需要的全備份路徑目錄或上次做增量備份的目錄路徑
–incremental-dir=DIRECTORY 增量備份存貯的目錄路徑
–redo-only 用于準(zhǔn)備增量備份內(nèi)容把數(shù)據(jù)合并到全備份目錄,配合–incremental-dir 增量備份目錄使用。
–force-non-empty-directories 如果是特定庫備份還原,不需要刪掉整個mysql目錄,只是特定庫的及相關(guān)文件就可以,還原時加上此參數(shù)就不會報錯。
--apply-log:通過應(yīng)用 BACKUP_DIR 目錄中的 xtrabackup_logfile 的事務(wù)日志,在 BACKUP_DIR 目錄中準(zhǔn)備備份,并且創(chuàng)建新的事務(wù)日志。innobackupex --apply-log 默認使用 BACKUP_DIR 目錄 backup-my.cnf 中的 InnoDB 配置,如果指定了--defaults-file 選項,那么就使用它指定的配置文件。
--copy-back:將準(zhǔn)備好的備份文件從備份目錄復(fù)制到原始位置,其原始位置目錄必須為空,否則報錯(除非指定--force-non-empty-directories 選項)。
--move-back:將之前備份的所有文件從備份目錄移動到原始目錄。此選項恢復(fù)后將刪除備份文件,請大家慎重使用。
--stream=name:該選項接受指定流備份執(zhí)行格式的字符串參數(shù),備份將以指定的格式完成 STDOUT。對備份文件進行打包。支持格式有 tar 和 xbstream。如果在該選項后指定路徑,則該路徑被解釋為 tmpdir 的值。
--tables-file=name:
-t, --tmpdir=name:該選項接受一個指定臨時文件位置的字符串參數(shù)。它可以與--stream 選項一起使用。使用該選項,事務(wù)日志首先會存儲到臨時文件中,然后流式傳輸或者復(fù)制到遠程主機。如果未指定該選項,則默認值為使用 my.cnf 配置讀取的 tmpdir 值。
--use-memory=#:該選項指定 xtrabackup 在 prepare 階段進行崩潰恢復(fù)的內(nèi)存使用量,以字節(jié)為單位,支持的單位如 1MB、1M、1GB、1G。
--slave-info:該選項用于在從庫上的備份。它會打印二進制日志的位置和主庫的名稱,還會將此信息以“CHANGE MASTER”命令的形式寫入到 xtrabackup_slave_info 文件中,可以通過此備份啟動從實例。
--safe-slave-backup:這個選項是要和--slave-info 結(jié)合使用的。發(fā)起備份時,會暫停 SLAVE 的 SQL Thread,確保備份時沒有臨時表打開,保證數(shù)據(jù)的一致性。備份結(jié)束后,SQL 線程會自動啟動。如果 Slave_open_temp_tables 在--safe-slave-backup-timeout 秒后未變成零,則備份失敗。
--safe-slave-backup-timeout=seconds:該選項指定--safe-slave-backup 應(yīng)等待多長時間,以使 Slave_open_temp_tables 變?yōu)榱?。默認時間為 300 秒
--lock-ddl
備份開始時候阻塞所有DDL操作
--lock-ddl-per-table
在xtrabackup開始復(fù)制每個表之前和備份完成之前,都要阻塞對該表的DDL操作。
--lock-ddl-timeout
在指定的時間內(nèi)沒有返回,就終止備份
--parallel
整數(shù)參數(shù),指定xtrabackup子進程用于同時備份文件的線程數(shù)。 請注意,此選項適用于文件級別,即,如果您有多個.ibd文件,則它們將并行復(fù)制。 如果表一起存儲在單個表空間文件中,則它將無效。此選項將允許同時解密和/或解壓縮多個文件
--no-version-check
不檢查版本
五、xtrabackup備份實踐
備份:
普通全備:
innobackupex --defaults-file=/dbdata/3306/3306.cfg --user=root --password=xxxx --socket=/dbdata/3306/mysql.sock --no-timestamp --lock-ddl-per-table --no-version-check --parallel=4 --slave-info /dbdata/testbak2 >/dbdata/backup.log 2>&1
使用tar壓縮全備:
innobackupex --defaults-file=/dbdata/3306/3306.cfg --user=root --password=xxxx --socket=/dbdata/3306/mysql.sock --no-timestamp --lock-ddl-per-table --no-version-check --parallel=4 --slave-info --stream=tar
tmpdir=/dbdata |gzip >/dbdata/backup.tar.gz
增量備份:
innobackupex --defaults-file=${mycnf} --user=${user} --password=${password} --use-memory=1G --no-timestamp --incremental ${backuppath}/${incrbakdir} --incremental-basedir ${backuppath}/${backupdir}
全備恢復(fù):
全備恢復(fù):
innobackupex --defaults-file=/dbdata/mysql5718/mysql3306/my.cnf --use-memory=8G --apply-log
/dbdata/2017-05-11_21-53-56
innobackupex --defaults-file=/dbdata/mysql5718/mysql3306/my.cnf --use-memory=8G --copy-back /dbdata/2017-05-11_21-53-56
增量備份恢復(fù):
1)先應(yīng)用完整備份
innobackupex --defaults-file=/dbdata/mysql5718/mysql3306/my.cnf --use-memory=8G --apply-log --redo-only /dbdata/2017-05-11_21-53-56
2)應(yīng)用增量備份
innobackupex --defaults-file=/dbdata/mysql5718/mysql3306/my.cnf --use-memory=8G --apply-log --redo-only --incremental-dir=/xxx/inr_xx /dbdata/2017-05-11_21-53-56
(如果有多個增備,僅僅最后一個增備無需指定--redo-only )
遠程備份:
非壓縮方式
innobackupex --stream=tar /tmp | ssh root@192.168.1.7 / "cat - > /backup/bak.tar"
壓縮方式
innobackupex --stream=tar /tmp | ssh root@192.168.1.7 / "gzip >/backup/bak.tar.gz"
六、xtrabackup備份日志分析
180802 15:10:15 Connecting to MySQL server host: localhost, user: root, password: set, port: 3306, socket: /dbdata/3306/mysql.sock
Using server version 5.7.21-log
./innobackupex version 2.4.7 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 05f1fcf)
xtrabackup: uses posix_fadvise().
xtrabackup: cd to /dbdata/3306/data
xtrabackup: open files limit requested 65535, set to 65535
xtrabackup: using the following InnoDB configuration:
xtrabackup: innodb_data_home_dir = .
xtrabackup: innodb_data_file_path = ibdata1:512M:autoextend
xtrabackup: innodb_log_group_home_dir = ./
xtrabackup: innodb_log_files_in_group = 3
xtrabackup: innodb_log_file_size = 268435456
2018-08-02 15:10:15 0x7f78c6d8c740 InnoDB: Using Linux native AIO
xtrabackup: using O_DIRECT
InnoDB: Number of pools: 1
180802 15:10:15 >> log scanned up to (1873374524) redo拷貝線程開始拷貝redo中新增的
xtrabackup: Generating a list of tablespaces
InnoDB: Allocated tablespace ID 2 for mysql/plugin, old maximum was 0
xtrabackup: Starting 4 threads for parallel data files transfer
180802 15:10:15 [01] Copying ./ibdata1 to /dbdata/testbak2/ibdata1 拷貝innodb引擎的數(shù)據(jù)文件
180802 15:10:15 [02] Copying ./mysql/plugin.ibd to /dbdata/testbak2/mysql/plugin.ibd
.....................................
180802 15:10:16 [02] Copying ./test01/qrtz_job_details.ibd to /dbdata/testbak2/test01/qrtz_job_details.ibd
180802 15:10:16 [03] Copying ./sys/sys_config.ibd to /dbdata/testbak2/sys/sys_config.ibd
180802 15:10:16 [04] Copying ./test01/qrtz_triggers.ibd to /dbdata/testbak2/test01/qrtz_triggers.ibd
......................................
180802 15:10:18 >> log scanned up to (1873374524)
180802 15:10:18 Executing FLUSH NO_WRITE_TO_BINLOG TABLES... 關(guān)閉所有表(操作不發(fā)送到slave)
180802 15:10:18 Executing FLUSH TABLES WITH READ LOCK... 全局讀鎖
180802 15:10:18 Starting to backup non-InnoDB tables and files 開始拷貝非innodb表和文件
180802 15:10:18 [01] Copying ./mysql/db.opt to /dbdata/testbak2/mysql/db.opt
180802 15:10:18 [01] ...done
.................................................
180802 15:10:19 [01] Copying ./test01/qrtz_job_details.frm to /dbdata/testbak2/test01/qrtz_job_details.frm
180802 15:10:19 [01] ...done
.................................................
180802 15:10:19 Finished backing up non-InnoDB tables and files
180802 15:10:19 [00] Writing xtrabackup_slave_info 寫入show slave status信息
180802 15:10:19 [00] ...done
180802 15:10:19 [00] Writing xtrabackup_binlog_info 寫入show master status信息
180802 15:10:19 [00] ...done
180802 15:10:19 Executing FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS... 刷新 redo log buffer 中的日志到磁盤中
xtrabackup: The latest check point (for incremental): '1873374515'
xtrabackup: Stopping log copying thread.
180802 15:10:19 >> log scanned up to (1873374524) 最后一次拷貝redo
180802 15:10:19 Executing UNLOCK TABLES 解鎖表
180802 15:10:19 All tables unlocked
180802 15:10:19 [00] Copying ib_buffer_pool to /dbdata/testbak2/ib_buffer_pool
180802 15:10:19 [00] ...done
180802 15:10:19 Backup created in directory '/dbdata/testbak2/'
MySQL binlog position: filename 'bin-log.000018', position '96573286', GTID of the last change '237931e4-52a1-11e8-9d07-000c293ddb5b:5-9,
ab805be6-52a0-11e8-9e8c-000c2925c742:1-1544667'
MySQL slave binlog position: master host '192.168.73.102', purge list '237931e4-52a1-11e8-9d07-000c293ddb5b:5-9, ab805be6-52a0-11e8-9e8c-000c2925c742:1-1544667'
180802 15:10:19 [00] Writing backup-my.cnf
180802 15:10:19 [00] ...done
180802 15:10:19 [00] Writing xtrabackup_info
180802 15:10:19 [00] ...done
xtrabackup: Transaction log of lsn (1873374515) to (1873374524) was copied.
180802 15:10:19 completed OK! 備份完成
七、xtrabackup備份的general_log分析
Id Command Argument
11998 Connect root@localhost on using Socket
11998 Query SET SESSION wait_timeout=2147483 調(diào)整session級別wait_timeout值
11998 Query SHOW VARIABLES
11998 Query SHOW ENGINE I NNODB STATUS
11998 Query SET SESSION lock_wait_timeout=31536000 調(diào)整session級別lock_wait_timeout值
11998 Query FLUSH NO_WRITE_TO_BINLOG TABLES 關(guān)閉打開的表
11998 Query FLUSH TABLES WITH READ LOCK FTWRL全局讀鎖
11998 Query SHOW SLAVE STATUS 獲取復(fù)制信息
11998 Query SHOW VARIABLES
11998 Query SHOW MASTER STATUS 獲取本機的binlog信息
11998 Query SHOW VARIABLES
11998 Query FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS 刷新buffer中的redo到redo log file中
11998 Query UNLOCK TABLES 解鎖
11998 Query SELECT UUID()
11998 Query SELECT VERSION()
11998 Quit 退出
與mysqldump的general_log相比,最主要是多了 FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS這一步驟,因為5.6后group commit中的innodb commit不需要在做sync操作,如果不執(zhí)行flush engine logs ,因為xtrabackup不備份Binlog,恢復(fù)時則可能會丟失部分?jǐn)?shù)據(jù)。
引用:
https://www.percona.com/doc/percona-xtrabackup/2.4/index.html
http://mysql.taobao.org/monthly/2016/03/07/
http://www.unixfbi.com/349.html
到此這篇關(guān)于MySQL xtrabackup 物理備份原理的文章就介紹到這了,更多相關(guān)MySQL xtrabackup 物理備份原理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用python連接mysql數(shù)據(jù)庫之pymysql模塊的使用
這篇文章主要介紹了使用python連接mysql數(shù)據(jù)庫之pymysql模塊的使用,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-09-09