MySQL在備份方面包含了自身的mysqldump工具,但其只支持單線程工做,這就使得它沒法迅速的備份數據。而mydumper做爲一個實用工具,可以良好支持多線程工做,這使得它在處理速度方面十倍於傳統的mysqldump。其特徵之一是在處理過程當中須要對列表加以鎖定,所以若是咱們須要在工做時段執行備份工做,那麼會引發DML阻塞。但通常如今的MySQL都有主從,備份也大部分在從上進行,因此鎖的問題能夠不用考慮。這樣,mydumper能更好的完成備份任務。html
###更新(2016-04-01)###python
注意:mydumper的多線程備份是基於表的,因此當只有一張表或99張是小表,1張是超級大表,mydumper不如mysqldump,甚至更慢。其實mydumper是支持對一張表多個線程備份的,參數-r。mysql
Mydumper主要特性:是一個針對MySQL和Drizzle的高性能多線程備份和恢復工具,開發人員主要來自MySQL,Facebook,SkySQL公司。linux
1:輕量級C語言寫的
2:執行速度比mysqldump快10倍
3:事務性和非事務性表一致的快照(適用於0.2.2以上版本)
4:快速的文件壓縮
5:支持導出binlog
6:多線程恢復(適用於0.2.1以上版本)
7:以守護進程的工做方式,定時快照和連續二進制日誌(適用於0.5.0以上版本)
8:開源 (GNU GPLv3)
下載安裝:c++
環境:Ubuntu 12.04正則表達式
下載:sql
wget https://launchpad.net/mydumper/0.5/0.5.2/+download/mydumper-0.5.2.tar.gz
安裝:解壓後,在README中安裝說明數據庫
apt-get install cmake make libglib2.0-dev libmysqlclient15-dev zlib1g-dev libpcre3-dev g++
cmake .
make
root@dd:~/mydumper-0.5.2# cmake . -- The CXX compiler identification is GNU -- Check for working CXX compiler: /usr/bin/c++ -- Check for working CXX compiler: /usr/bin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Using mysql-config: /usr/bin/mysql_config -- Found MySQL: /usr/include/mysql, /usr/lib/x86_64-linux-gnu/libmysqlclient_r.so;/usr/lib/x86_64-linux-gnu/libpthread.so;/usr/lib/x86_64-linux-gnu/libz.so;/usr/lib/x86_64-linux-gnu/libm.so;/usr/lib/x86_64-linux-gnu/librt.so;/usr/lib/x86_64-linux-gnu/libdl.so CMake Warning at docs/CMakeLists.txt:9 (message): Unable to find Sphinx documentation generator -- ------------------------------------------------ -- MYSQL_CONFIG = /usr/bin/mysql_config -- CMAKE_INSTALL_PREFIX = /usr/local -- BUILD_DOCS = ON -- RUN_CPPCHECK = OFF -- Change a values with: cmake -D<Variable>=<Value> -- ------------------------------------------------ -- -- Configuring done -- Generating done -- Build files have been written to: /root/mydumper-0.5.2 root@dd:~/mydumper-0.5.2# make Scanning dependencies of target mydumper [ 20%] Building C object CMakeFiles/mydumper.dir/mydumper.c.o [ 40%] Building C object CMakeFiles/mydumper.dir/binlog.c.o [ 60%] Building C object CMakeFiles/mydumper.dir/server_detect.c.o [ 80%] Building C object CMakeFiles/mydumper.dir/g_unix_signal.c.o Linking C executable mydumper [ 80%] Built target mydumper Scanning dependencies of target myloader [100%] Building C object CMakeFiles/myloader.dir/myloader.c.o Linking C executable myloader [100%] Built target myloader
生成2個工具:mydumper(備份),myloader(導入),放入到bin目錄下。服務器
參數:多線程
mydumper(0.5.2):
root@dd:~/mydumper-0.5.2# ./mydumper --help Usage: mydumper [OPTION...] multi-threaded MySQL dumping Help Options: -?, --help Show help options Application Options: -B, --database 須要備份的庫 -T, --tables-list 須要備份的表,用逗號分隔 -o, --outputdir 輸出文件的目錄 -s, --statement-size 生成插入語句的字節數, 默認 1000000,這個參數不能過小,否則會報 Row bigger than statement_size for tools.t_serverinfo -r, --rows 分裂成不少行塊表 -c, --compress 壓縮輸出文件 -e, --build-empty-files 即便表沒有數據,仍是產生一個空文件 -x, --regex 正則表達式: 'db.table' -i, --ignore-engines 忽略的存儲引擎,用逗號分隔 -m, --no-schemas 不導出表結構 -k, --no-locks 不執行共享讀鎖 警告:這將致使不一致的備份 -l, --long-query-guard 設置長查詢時間,默認60秒,超過該時間則會報錯:There are queries in PROCESSLIST running longer than 60s, aborting dump
--kill-long-queries kill掉長時間執行的查詢 -b, --binlogs 導出binlog -D, --daemon 啓用守護進程模式 -I, --snapshot-interval dump快照間隔時間,默認60s,須要在daemon模式下 -L, --logfile 日誌文件 -h, --host The host to connect to -u, --user Username with privileges to run the dump -p, --password User password -P, --port TCP/IP port to connect to -S, --socket UNIX domain socket file to use for connection -t, --threads 使用的線程數,默認4 -C, --compress-protocol 在mysql鏈接上使用壓縮協議 -V, --version Show the program version and exit -v, --verbose 更多輸出, 0 = silent, 1 = errors, 2 = warnings, 3 = info, default 2
myloader(0.5.2):
root@dd:~/mydumper-0.5.2# ./myloader --help
Usage:
myloader [OPTION...] multi-threaded MySQL loader
Help Options:
-?, --help Show help options
Application Options: -d, --directory 備份文件所在的目錄 -q, --queries-per-transaction 每次執行查詢數量, 默認1000 -o, --overwrite-tables 若是表存在則先刪除。這裏注意下,使用該參數,須要備份時候要備份表結構,否則會出問題 -B, --database 指定須要還原的數據庫 -e, --enable-binlog 啓用二進制恢復數據 -h, --host The host to connect to -u, --user Username with privileges to run the dump -p, --password User password -P, --port TCP/IP port to connect to -S, --socket UNIX domain socket file to use for connection -t, --threads 使用的線程數量,默認4 -C, --compress-protocol 鏈接上使用壓縮協議 -V, --version Show the program version and exit -v, --verbose 更多輸出, 0 = silent, 1 = errors, 2 = warnings, 3 = info, default 2
###更新(2016-04-01)###
上面介紹的是0.5.2版本,目前版本已經更新到了0.9.1,新增了一些參數,如今對新參數瞭解一下:
mydumper(0.9.1):
root@op3:/home/zhoujy# mydumper --help Usage: mydumper [OPTION...] multi-threaded MySQL dumping Help Options: -?, --help Show help options Application Options: -B, --database 須要備份的數據庫,一個數據庫一條命令備份,要不就是備份全部數據庫,包括mysql。 -T, --tables-list 須要備份的表,用逗號分隔。 -o, --outputdir 備份文件目錄 -s, --statement-size 生成插入語句的字節數,默認1000000,這個參數不能過小,否則會報 Row bigger than statement_size for tools.t_serverinfo -r, --rows 試圖用行塊來分割表,該參數關閉--chunk-filesize -F, --chunk-filesize 行塊分割表的文件大小,單位是MB -c, --compress 壓縮輸出文件 -e, --build-empty-files 即便表沒有數據,也產生一個空文件 -x, --regex 正則表達式匹配,如'db.table' -i, --ignore-engines 忽略的存儲引擎,用逗號分隔 -m, --no-schemas 不導出表結構 -d, --no-data 不導出表數據 -G, --triggers 導出觸發器 -E, --events 導出事件 -R, --routines 導出存儲過程 -k, --no-locks 不執行共享讀鎖 警告:這將致使不一致的備份 --less-locking 減到最小的鎖在innodb表上. -l, --long-query-guard 設置長查詢時間,默認60秒,超過該時間則會報錯:There are queries in PROCESSLIST running longer than 60s, aborting dump
-K, --kill-long-queries kill掉長時間執行的查詢,備份報錯:Lock wait timeout exceeded; try restarting transaction
-D, --daemon 啓用守護進程模式 -I, --snapshot-interval dump快照間隔時間,默認60s,須要在daemon模式下 -L, --logfile 使用日誌文件,默認標準輸出到終端 --tz-utc 備份的時候容許備份Timestamp,這樣會致使不一樣時區的備份還原會出問題,默認關閉,參數:--skip-tz-utc to disable. --skip-tz-utc --use-savepoints 使用savepoints來減小採集metadata所形成的鎖時間,須要SUPER權限 --success-on-1146 Not increment error count and Warning instead of Critical in case of table doesn't exist
--lock-all-tables 鎖全表,代替FLUSH TABLE WITH READ LOCK -U, --updated-since Use Update_time to dump only tables updated in the last U days --trx-consistency-only Transactional consistency only -h, --host The host to connect to -u, --user Username with privileges to run the dump -p, --password User password -P, --port TCP/IP port to connect to -S, --socket UNIX domain socket file to use for connection -t, --threads 備份執行的線程數,默認4個線程 -C, --compress-protocol 在mysql鏈接上使用壓縮協議 -V, --version Show the program version and exit -v, --verbose 更多輸出, 0 = silent, 1 = errors, 2 = warnings, 3 = info, default 2
加粗部分是新增長的參數。
myloader(0.9.1):
root@op:~# myloader --help Usage: myloader [OPTION...] multi-threaded MySQL loader Help Options: -?, --help Show help options Application Options: -d, --directory 備份文件所在的目錄 -q, --queries-per-transaction 每一個事務的query數量, 默認1000 -o, --overwrite-tables 若是表存在則先刪除,使用該參數,須要備份時候要備份表結構,否則還原會找不到表 -B, --database 指定須要還原的數據庫 -s, --source-db 還原的數據庫 -e, --enable-binlog 啓用二進制日誌恢復數據 -h, --host The host to connect to -u, --user Username with privileges to run the dump -p, --password User password -P, --port TCP/IP port to connect to -S, --socket UNIX domain socket file to use for connection -t, --threads 使用的線程數量,默認4 -C, --compress-protocol 鏈接上使用壓縮協議 -V, --version Show the program version and exit -v, --verbose 更多輸出, 0 = silent, 1 = errors, 2 = warnings, 3 = info, default 2
加粗部分是新增長的參數。
測試:測試基本用法
1:備份
./mydumper -u zjy -p ##### -h 192.168.220.245 -P 3306 -B chushihua -o /home/zhoujy/bak/
備份analyzedxy數據庫到/home/zhoujy/bak/ 目錄中,查看是否多線程:
| 4937639 | zjy | 192.168.200.25:34781 | NULL| Query | 0 | NULL | show processlist | | 4937677 | zjy | 192.168.200.25:34791 | NULL| Query | 10 | Writing to net | SELECT /*!40001 SQL_NO_CACHE */| | 4937678 | zjy | 192.168.200.25:34792 | NULL| Query | 5 | Writing to net | SELECT /*!40001 SQL_NO_CACHE */ | | 4937679 | zjy | 192.168.200.25:34793 | NULL| Query | 10 | Writing to net | SELECT /*!40001 SQL_NO_CACHE */ | | 4937680 | zjy | 192.168.200.25:34794 | NULL| Query | 10 | Writing to net | SELECT /*!40001 SQL_NO_CACHE */ |
上面顯示確實是4個線程(默認)在備份,查看備份文件:
root@zhoujy:/home/zhoujy/bak# ls -lh -rw-r--r-- 1 root root 322 2013-11-14 17:59 chushihua.dba_hospital_all_name-schema.sql
-rw-r--r-- 1 root root 16M 2013-11-14 17:59 chushihua.dba_hospital_all_name.sql
-rw-r--r-- 1 root root 221 2013-11-14 17:59 chushihua.dba_hospital-schema.sql
-rw-r--r-- 1 root root 658 2013-11-14 17:59 chushihua.dba_hospital.sql
-rw-r--r-- 1 root root 198 2013-11-14 17:59 chushihua.dba_jobTitle-schema.sql
-rw-r--r-- 1 root root 300 2013-11-14 17:59 chushihua.dba_jobTitle.sql
-rw-r--r-- 1 root root 261 2013-11-14 17:59 chushihua.dba_locatedCity-schema.sql
-rw-r--r-- 1 root root 202K 2013-11-14 17:59 chushihua.dba_locatedCity.sql
分析:mydumper把數據和表結構分開備份,而且把二進制日誌備份出來單獨放到一個文件中。
metadata:元數據 記錄備份開始和結束時間,以及binlog日誌文件位置。
table data:每一個表一個文件
table schemas:表結構文件
binary logs: 啓用--binlogs選項後,二進制文件存放在binlog_snapshot目錄下
daemon mode:在這個模式下,有五個目錄0,1,binlogs,binlog_snapshot,last_dump。
備份目錄是0和1,間隔備份,若是mydumper因某種緣由失敗而仍然有一個好的快照,當快照完成後,last_dump指向該備份。
2:還原:還原到另外一臺服務器,先創建要還原的數據庫(chushihua)
./myloader -u root -p 123456 -h 192.168.200.25 -P 3307 -B chushihua -d /home/zhoujy/bak/
和備份同樣查看是否多線程:
| 19 | root | | NULL | Query | 0 | init | show processlist| | 30 | root | | chushihua | Query | 5 | update| INSERT INTO | | 31 | root | | chushihua | Query | 5 | update| INSERT INTO | | 32 | root | | chushihua | Query | 5 | update| INSERT INTO | | 33 | root | | chushihua | Query | 5 | update| INSERT INTO |
上面顯示確實是4個線程(默認)在還原。
進一步測試:測試一些經常使用的參數
1):備份指定表(-T),而且不要導出表結構(-m)
./mydumper -u root-p 123456 -h 192.168.220.252 -P 3306 -m -B test -T b,a,c,d,e,g,f,h,i -o /home/zhoujy/bak/ zhoujy@zhoujy:~/bak$ ls -lh -rw-rw-r-- 1 zhoujy zhoujy 3.4K 2013-11-14 20:57 test.a.sql -rw-rw-r-- 1 zhoujy zhoujy 1.6M 2013-11-14 20:57 test.b.sql -rw-rw-r-- 1 zhoujy zhoujy 7.8M 2013-11-14 20:57 test.c.sql -rw-rw-r-- 1 zhoujy zhoujy 1.7M 2013-11-14 20:57 test.d.sql -rw-rw-r-- 1 zhoujy zhoujy 303K 2013-11-14 20:57 test.e.sql -rw-rw-r-- 1 zhoujy zhoujy 517K 2013-11-14 20:57 test.f.sql -rw-rw-r-- 1 zhoujy zhoujy 646K 2013-11-14 20:57 test.g.sql -rw-rw-r-- 1 zhoujy zhoujy 394K 2013-11-14 20:57 test.h.sql -rw-rw-r-- 1 zhoujy zhoujy 34K 2013-11-14 20:57 test.i.sql -rw-rw-r-- 1 zhoujy zhoujy 75 2013-11-14 20:57 metadata
2)壓縮備份文件(-c),備份binlog(-b),正則表達式備份表(-x)
./mydumper -u root -p 123456 -h 192.168.200.25 -P 3306 -m -c -b --regex=tmp.* -B test -o /home/zhoujy/bak/ drwx------ 2 zhoujy zhoujy 4.0K 2013-11-14 21:16 binlog_snapshot -rw-rw-r-- 1 zhoujy zhoujy 133 2013-11-14 21:16 metadata -rw-rw-r-- 1 zhoujy zhoujy 94K 2013-11-14 21:16 test.tmp_0808.sql.gz -rw-rw-r-- 1 zhoujy zhoujy 75K 2013-11-14 21:16 test.tmp_0809.sql.gz -rw-rw-r-- 1 zhoujy zhoujy 25K 2013-11-14 21:16 test.tmp_0813.sql.gz -rw-rw-r-- 1 zhoujy zhoujy 208K 2013-11-14 21:16 test.tmp_0826.sql.gz -rw-rw-r-- 1 zhoujy zhoujy 915 2013-11-14 21:16 test.tmp_0827.sql.gz -rw-rw-r-- 1 zhoujy zhoujy 901 2013-11-14 21:16 test.tmp_0912.sql.gz -rw-rw-r-- 1 zhoujy zhoujy 2.1K 2013-11-14 21:16 test.tmp_0916.sql.gz -rw-rw-r-- 1 zhoujy zhoujy 622K 2013-11-14 21:16 test.tmp_0918_a.sql.gz -rw-rw-r-- 1 zhoujy zhoujy 28M 2013-11-14 21:16 test.tmp_0918_ff.sql.gz
如上所示,備份文件已是壓縮的了(用gzip -d 解壓),而且備份出了tmp.*匹配出來的全部表,二進制日誌也被備份到了binlog_snapshot文件中,而且也是被壓縮的。
###更新(2016-04-01)###
新版本里已經不能備份binlog了,沒有-b參數。這裏說明下備份指定數據庫的方法:--regex 正則匹配
#指定備份數據庫:備份abc、bcd、cde mydumper -u backup -p 123456 -h 192.168.180.13 -P 3306 -t 3 -c -l 3600 -s 10000000 -e --regex 'abc|bcd|cde' -o bbb/ #指定不備份的數據庫:不備份abc、mysql、test,備份其餘數據庫 mydumper -u backup -p 123456 -h 192.168.180.13 -P 3306 -t 3 -c -l 3600 -s 10000000 -e --regex '^(?!(abc|mysql|test))' -o bbb/
3)還原,表存在先刪除(-o):這裏須要注意,使用該參數,備份目錄裏面須要有表結構的備份文件。
./myloader -u root -p 123456 -h 192.168.200.25 -P 3306 -o -B test -d /home/zhoujy/bak/
更多的參數效果,請本身測試。
最後測試:用mysqldump和mydumper進行對比測試。
#!/usr/bin/env python #coding=utf-8 import MySQLdb import os import sys import time backup = os.system('') def mysqldump_data(): t1 = time.time() backup = os.system('mysqldump --no-defaults -uroot -p123456 -h192.168.200.25 --default-character-set=utf8 test > /home/zhoujy/test.bak') t2 = time.time() t = round(t2-t1) print "mysqldump Cost Time %s" %t def mydumper_data(): t1 = time.time() backup = os.system('mydumper -u root -p 123456 -h 192.168.200.25 -P 3306 -B test -o /home/zhoujy/bak/') t2 = time.time() t = round(t2-t1) print "mydumper Cost Time %s" %t if __name__ =='__main__': mysqldump_data() mydumper_data()
測試了2個數據庫:
1:
mysqldump Cost Time :162s
mydumper Cost Time :61s
2:
mysqldump Cost Time :483s
mydumper Cost Time :337s
從上面的時間來看,mydumper 確實提高了備份數據,還原也同理。
###### 2016-07-20 更新 #######
mydumper支持一張表多個線程以chunk的方式批量導出,參數-r:試圖用行塊來分割表,該參數關閉--chunk-filesize參數。如:
mydumper -u zjy -p xxx -h 192.168.123.70 -P 3306 -t 5 -c -r 300000 -l 3600 -s 10000000 -B vs -o /home/zhoujy/vs/
表示每一個線程用300000行塊來分割表,經過show processlist 看到:5個線程備份
| Sending data |
SELECT /*!40001 SQL_NO_CACHE */ * FROM `virtual_station`.`core_event` WHERE `id` IS NULL OR (`id` >= 1 AND `id` < 446597) | | Sending to client |
SELECT /*!40001 SQL_NO_CACHE */ * FROM `virtual_station`.`core_error_log` WHERE `id` IS NULL OR (`id` >= 1 AND `id` < 351238) | | Sending to client |
SELECT /*!40001 SQL_NO_CACHE */ * FROM `virtual_station`.`core_event` WHERE (`id` >= 893193 AND `id` < 1339789) | | Sending to client |
SELECT /*!40001 SQL_NO_CACHE */ * FROM `virtual_station`.`core_event` WHERE (`id` >= 1339789 AND `id` < 1786385) | | Sending data |
SELECT /*!40001 SQL_NO_CACHE */ * FROM `virtual_station`.`core_error_log` WHERE (`id` >= 702475 AND `id` < 1053712) |
這個能夠更好的備份數據庫,無論數據庫裏是否有大表。
總結:
從上面的測試分析中看出mydumper能夠提高備份還原的效率,雖然是多線程操做,可是提高多少受限於磁盤的IO能力,在使用前作好磁盤IO的評估,你們能夠嘗試使用該工具。
更多信息見:
http://blog.csdn.net/leshami/article/details/46815553
http://www.hoterran.info/mydumper_usage