天天看點

MySQL分布式邏輯備份

摘要

定期備份的重要性在資料庫生命周期中已得到展現。有不同的風格:二進制的(Percona XtraBackup),二進制日志備份,磁盤快照(lvm,ebs等)和經典的:邏輯備份,可以使用mysqldump,mydumper或mysqlpump等工具進行的備份。它們每個都有特定的用途,MTTR,保留政策等。

另一個事實是,一旦datadir增長,進行備份可能是一項非常緩慢的任務:存儲更多資料,讀取和備份更多資料。而且,另一個事實是,不僅資料會增長,而且環境中可用的MySQL執行個體的數量也會增加(通常)。那麼,為什麼不利用更多的MySQL執行個體來進行邏輯備份以使此操作更快呢?

分布式備份(或使用所有可用的從站)

這個想法很簡單:不要從單個伺服器上擷取整個備份,而要使用所有可用的伺服器。本概念證明僅專注于在主/從拓撲上使用副本。也可以使用Master,但是在這種情況下,我決定不使用它,以免增加備份開銷。

測試

在主/從屬拓撲中:

MySQL分布式邏輯備份

來自Orchestrator GUI的圖形

使用約64GB資料(不包括索引大小)和300個表(模式“ sb”)的小datadir:

+--------------+--------+--------+-----------+----------+-----------+----------+
| TABLE_SCHEMA | ENGINE | TABLES | ROWS      | DATA (M) | INDEX (M) | TOTAL(M) |
+--------------+--------+--------+-----------+----------+-----------+----------+
| meta         | InnoDB | 1      |         0 | 0.01     | 0.00      |   0.01   |
| percona      | InnoDB | 1      |         2 | 0.01     | 0.01      |   0.03   |
| sb           | InnoDB | 300    | 295924962 | 63906.82 |   4654.68 | 68561.51 |
| sys          | InnoDB | 1      |         6 | 0.01     | 0.00      |   0.01   |
+--------------+--------+--------+-----------+----------+-----------+----------+           

複制

使用3個副本,使用mysqldump進行的分布式邏輯備份花費了6分13秒:

[root@mysql1 ~]# ls -lh /data/backups/20200101/
total 56G
-rw-r--r--. 1 root root 19G Jan  1 14:37 mysql2.sql
-rw-r--r--. 1 root root 19G Jan  1 14:37 mysql3.sql
-rw-r--r--. 1 root root 19G Jan  1 14:37 mysql4.sql
[root@mysql1 ~]# stat /data/backups/20200101/mysql2.sql
  File: '/data/backups/20200101/mysql2.sql'
  Size: 19989576285     Blocks: 39042144 IO Block: 4096   regular file
Device: 10300h/66304d   Inode: 54096034 Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 0/ root) Gid: (    0/ root)
Context: unconfined_u:object_r:unlabeled_t:s0
Access: 2020-01-01 14:31:34.948124516 +0000
Modify: 2020-01-01 14:37:41.297640837 +0000
Change: 2020-01-01 14:37:41.297640837 +0000
 Birth: -           

複制

單個副本上的相同備份類型花費了11分59秒:

[root@mysql1 ~]# time mysqldump -hmysql2 --single-transaction --lock-for-backup sb > /data/backup.sql

real    11m58.816s
user    9m48.871s
sys     2m6.492s
[root@mysql1 ~]# ls -lh /data/backup.sql
-rw-r--r--. 1 root root 56G Jan  1 14:52 /data/backup.sql           

複制

換一種說法:

分布式伺服器快48%!

這是一個相當小的資料集。值得一試。那麼它是怎樣工作的?

概念

邏輯很簡單,可以分為多個階段。

階段1:準備

  • 找出可用的副本數
  • 找出要備份的架構中的表數
  • 在所有可用副本之間劃分表的數量。結果塊将是每個副本将備份的表。

階段2:保證一緻性

  • 阻止主伺服器執行更改二進制日志位置的操作。通常,這是通過帶有讀取鎖的FLUSH TABLES完成的,但是此PoC使用的是Percona Server for MySQL上的LOCK BINLOG FOR BACKUP的很酷的功能, 并且破壞性較小。
  • 查找最新副本
  • 使用START SLAVE UNTIL使所有其他副本與最新副本比對
  • 使用相應的表塊為每個副本啟動一個mysqldump,并使用–lock-for-backup(Percona Server的另一個功能)

完整的腳本可以在這裡找到:

https://github.com/nethalo/parallel-mysql-backup/blob/master/dist_backup.sh

值得一提的是,腳本具有自己的日志,該日志将描述每個步驟,它看起來像這樣:

[200101-16:01:19] [OK] Found 'mysql' bin
[200101-16:01:19] [Info] SHOW SLAVE HOSTS executed
[200101-16:01:19] [Info] Count tables OK
[200101-16:01:19] [Info] table list gathered
[200101-16:01:19] [Info] CREATE DATABASE IF NOT EXISTS percona
[200101-16:01:19] [Info] CREATE TABLE IF NOT EXISTS percona.metabackups
[200101-16:01:19] [Info] TRUNCATE TABLE percona.metabackups
[200101-16:01:19] [Info] Executed INSERT INTO percona.metabackups (host,chunkstart) VALUES('mysql3',0)
[200101-16:01:19] [Info] Executed INSERT INTO percona.metabackups (host,chunkstart) VALUES('mysql4',100)
[200101-16:01:19] [Info] Executed INSERT INTO percona.metabackups (host,chunkstart) VALUES('mysql2',200)
[200101-16:01:19] [Info] lock binlog for backup set
[200101-16:01:19] [Info] slave status position on mysql3
[200101-16:01:19] [Info] slave status file on mysql3
[200101-16:01:19] [Info] slave status position on mysql4
[200101-16:01:19] [Info] slave status file on mysql4
[200101-16:01:19] [Info] slave status position on mysql2
[200101-16:01:19] [Info] slave status file on mysql2
[200101-16:01:19] [Info] set STOP SLAVE; START SLAVE UNTIL MASTER_LOG_FILE = 'mysql-bin.000358', MASTER_LOG_POS = 895419795 on mysql3
[200101-16:01:20] [Info] set STOP SLAVE; START SLAVE UNTIL MASTER_LOG_FILE = 'mysql-bin.000358', MASTER_LOG_POS = 895419795 on mysql4
[200101-16:01:20] [Info] set STOP SLAVE; START SLAVE UNTIL MASTER_LOG_FILE = 'mysql-bin.000358', MASTER_LOG_POS = 895419795 on mysql2
[200101-16:01:20] [Info] Created /data/backups/20200101/ directory
[200101-16:01:20] [Info] Limit chunk OK
[200101-16:01:20] [Info] Tables list for mysql3 OK
[200101-16:01:20] [OK] Dumping mysql3
[200101-16:01:20] [Info] Limit chunk OK
[200101-16:01:20] [Info] Tables list for mysql4 OK
[200101-16:01:20] [OK] Dumping mysql4
[200101-16:01:20] [Info] Limit chunk OK
[200101-16:01:20] [Info] Tables list for mysql2 OK
[200101-16:01:20] [OK] Dumping mysql2
[200101-16:01:20] [Info] UNLOCK BINLOG executed
[200101-16:01:20] [Info] set start slave on mysql3
[200101-16:01:20] [Info] set start slave on mysql4
[200101-16:01:20] [Info] set start slave on mysql2           

複制

一些基本要求

由于該工具使用指令SHOW SLAVE HOSTS ,是以必須設定變量report_host,如果使用的是Orchestrator,則很可能已經設定了該變量。

在“ report_host”變量中設定的主機應該是可通路的主機。例如,可以實際解析的IP或主機(DNS,編輯/ etc / hosts檔案)。

任何涉及的副本上都沒有複制過濾器。這樣可以保證資料的一緻性。

該腳本目前應在主伺服器中本地運作。

由于使用了備份鎖,是以隻能在Percona Server上使用。

預計MySQL使用者憑據将在.my.cnf檔案内的主目錄中可用

MySQL分布式邏輯備份