嘮嘮mydumper

Ⅰ、背景

  • mysqldump單線程備份,很慢
  • 恢復慢,一張表一張表恢復,
  • 若是備份了100G的數據,想恢復其中一個表,很難作(全部的表都在一個文件裏)

因此推薦使用mydumper備份mysql

  • 支持並行備份,基於行,即便一張表也能並行,好強吶
  • 恢復也支持並行
  • 恢復的時候能夠只恢復指定表

完美(^__^)c++

Ⅱ、安裝mydumper

yum install -y  glib2-devel mysql-devel zlib-devel pcre-devel openssl-devel cmake gcc gcc-c++ git
cd /usr/local/src && git clone https://github.com/maxbube/mydumper
cd mydumper
cmake .
make -j 4
make install
export LD_LIBRARY_PATH="/usr/local/mysql/lib:$LD_LIBRARY_PATH"

Ⅲ、參數介紹

參數和mysqldump不少同樣git

-G --triggers
-E --events
-R --routines
--trx-consistency-only    等於--single-transaction
-t 開幾個線程,默認4個
-o 備份到指定目錄
-x 正則匹配
-c 壓縮
-B 指定數據庫
-T 指定表
-F --chunk-filesize 指定文件大小
--rows 100000   每10w行導出到一個文件

Ⅳ、初體驗

4.1 備份

[root@VM_0_5_centos backup]# mydumper -G -E -R --trx-consistency-only -t 4 -c -B dbt3 -o /mdata/backup
另開一個會話看下show processlist;能夠看到四個線程
(root@172.16.0.10) [(none)]> show processlist;
+--------+------+------------------+------+---------+------+-------------------+----------------------------------------------------------+
| Id     | User | Host             | db   | Command | Time | State             | Info                                                     |
+--------+------+------------------+------+---------+------+-------------------+----------------------------------------------------------+
| 137488 | root | 172.16.0.5:53046 | NULL | Query   |    0 | starting          | show processlist                                         |
| 137523 | root | 172.16.0.5:53546 | NULL | Query   |    3 | Sending to client | SELECT /*!40001 SQL_NO_CACHE */ * FROM `dbt3`.`customer` |
| 137524 | root | 172.16.0.5:53548 | NULL | Query   |    3 | Sending to client | SELECT /*!40001 SQL_NO_CACHE */ * FROM `dbt3`.`lineitem` |
| 137525 | root | 172.16.0.5:53550 | NULL | Query   |    1 | Sending to client | SELECT /*!40001 SQL_NO_CACHE */ * FROM `dbt3`.`partsupp` |
| 137526 | root | 172.16.0.5:53552 | NULL | Query   |    3 | Sending to client | SELECT /*!40001 SQL_NO_CACHE */ * FROM `dbt3`.`orders`   |
+--------+------+------------------+------+---------+------+-------------------+----------------------------------------------------------+
5 rows in set (0.00 sec)

tips:
mydumper參數和其所跟的值不能連在一塊兒,否則會輸出以下報錯:github

option parsing failed: Error parsing option -r, try --help

4.2 分析備分內容

進入備份目錄sql

[root@VM_0_5_centos backup]# ll
total 1200340
ll
total 305044
-rw-r--r-- 1 root root       281 Jan 24 10:41 dbt3.customer-schema.sql.gz
-rw-r--r-- 1 root root   9173713 Jan 24 10:41 dbt3.customer.sql.gz
-rw-r--r-- 1 root root       401 Jan 24 10:41 dbt3.lineitem-schema.sql.gz
-rw-r--r-- 1 root root 221097124 Jan 24 10:42 dbt3.lineitem.sql.gz
-rw-r--r-- 1 root root       228 Jan 24 10:41 dbt3.nation-schema.sql.gz
-rw-r--r-- 1 root root      1055 Jan 24 10:41 dbt3.nation.sql.gz
-rw-r--r-- 1 root root       294 Jan 24 10:41 dbt3.orders-schema.sql.gz
-rw-r--r-- 1 root root  47020810 Jan 24 10:41 dbt3.orders.sql.gz
-rw-r--r-- 1 root root       264 Jan 24 10:41 metadata
...
篇幅有限未將全部表列出來

發現基於每張表備份併產生壓縮文件,因此恢復的時候能夠指定某張表恢復數據庫

摟一眼
metadata文件記錄二進制日誌位置(master-data=1)centos

[root@VM_0_5_centos backup]# cat metadata
Started dump at: 2018-01-24 10:35:50
SHOW MASTER STATUS:
    Log: bin.000001
    Pos: 154
    GTID:

Finished dump at: 2018-01-24 10:35:50

解開壓縮文件session

[root@VM_0_5_centos backup]# gunzip dbt3.customer-schema.sql.gz dbt3.customer.sql.gz dbt3-schema-create.sql.gz

[root@VM_0_5_centos backup]# cat dbt3-schema-create.sql
CREATE DATABASE `dbt3` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;

[root@VM_0_5_centos backup]# cat dbt3-schema-create.sql
CREATE DATABASE `dbt3` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
[root@VM_0_5_centos backup]# cat dbt3.customer-schema.sql
/*!40101 SET NAMES binary*/;
/*!40014 SET FOREIGN_KEY_CHECKS=0*/;

CREATE TABLE `customer` (
  `c_custkey` int(11) NOT NULL,
  `c_name` varchar(25) DEFAULT NULL,
  `c_address` varchar(40) DEFAULT NULL,
  `c_nationkey` int(11) DEFAULT NULL,
  `c_phone` char(15) DEFAULT NULL,
  `c_acctbal` double DEFAULT NULL,
  `c_mktsegment` char(10) DEFAULT NULL,
  `c_comment` varchar(117) DEFAULT NULL,
  PRIMARY KEY (`c_custkey`),
  KEY `i_c_nationkey` (`c_nationkey`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

[root@VM_0_5_centos backup]# head -5 dbt3.customer.sql
/*!40101 SET NAMES binary*/;
/*!40014 SET FOREIGN_KEY_CHECKS=0*/;
/*!40103 SET TIME_ZONE='+00:00' */;
INSERT INTO `customer` VALUES
(1,"Customer#000000001","j5JsirBM9PsCy0O1m",15,"25-989-741-2988",711.56,"BUILDING","regular, regular platelets are fluffily according to the even attainments. blithely iron"),

綜上:mvc

文件 做用
-schema.sql 每張表的表結構
.sql 數據文件
-schema-create.sql.gz 建立庫

4.3 恢復

恢復使用myloader命令性能

-d 恢復文件目錄
-t 指定線程數
-B 指定庫
-e 記錄binlog
[root@VM_0_5_centos mdata]# myloader -d /mdata/backup -t 4 -B test

tips:
SSD上開4線程比source單線程快將近兩倍(hdd盤可能性能提高會受必定影響)

Ⅴ、mydumper原理:

這裏有了mysqldump的基礎就不開glog詳細分析了

核心問題:並行怎麼作到的?一張表都能並行導出,還要保持一致性

step1:
session1(主線程):

flush tables with read lock; 整個數據庫鎖成只讀,其餘線程只能讀,不能寫,針對myisam作的

start transaction with consistent snapshot 開啓一致性快照事務,針對innodb作的

show master status 獲取二進制文件位置點

step2:
主線程建立執行備份任務的子線程並切換到事務隔離級別爲rr

session2:start transaction with consistent snapshot;

session3:start transaction with consistent snapshot;

session4:start transaction with consistent snapshot;

這樣多個線程讀到的內容是一致的

step3:
備份no-innodb

step4:
session1:unlock tables;

備份innodb至備份結束

小結:
從整個流程來看,多個線程看到的數據是一致的,因此select各個表,搞出來的數據是一致的,其實就是利用了mvcc的特性(不談非innodb的話)

問題:
一張表怎麼並行?

  • 先看主鍵,根據主鍵的第一個字段分區,對錶進行分片再進行備份,提早切好,區間先算好(不是每一個區間相等),show processlist;中能夠看出來
  • 無主鍵則看惟一索引,根據惟一索引第一個字段分區
  • 最差的狀況無主鍵無惟一索引,則找一個區分度高的索引來切片
  • 可是須要注意,目前這個切分的字段僅支持int型,其餘類型切不了
相關文章
相關標籤/搜索