1. 程式人生 > 資料庫 >淺談MySQL8.0 非同步複製的三種方式

淺談MySQL8.0 非同步複製的三種方式

本實驗中分別針對空庫、離線、聯機三種方式,配置一主兩從的mysql標準非同步複製。只做整伺服器級別的複製,不考慮對個別庫表或使用過濾複製的情況。

實驗環境

[root@slave2 ~]# cat /etc/hosts
192.168.2.138 master
192.168.2.192 slave1
192.168.2.130 slave2
mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.16  |
+-----------+
1 row in set (0.00 sec)

一、空庫

1.檢視主庫二進位制資訊

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File       | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000004 |   155 |       |         |          |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

2.在主庫上建立複製使用者

mysql> create user 'repl'@'%' identified with mysql_native_password by 'wwwwww';
Query OK,0 rows affected (0.03 sec)
mysql> grant replication client,replication slave on *.* to 'repl'@'%';
Query OK,0 rows affected (0.04 sec)
mysql> flush privileges;
Query OK,0 rows affected (0.00 sec)

3.在從庫建立主庫資訊

mysql> stop slave;
mysql> change master to master_host='192.168.2.138',master_port=3306,master_user='repl',master_password='wwwwww',master_log_file='mysql-bin.000004',master_log_pos=155;
Query OK,0 rows affected,2 warnings (0.00 sec)
mysql> start slave;
Query OK,0 rows affected (0.00 sec)
mysql> show slave status\G

剛才我們並沒有在從庫上建立repl使用者,但由於create user語句是在起始位置點後執行的,因此可以正常複製到從庫,查詢mysql.user表即可確認。

sql> select * from mysql.user where user='repl'\G

二、離線

如果資料庫已經存在應用資料,但允許一個可接受的離線時間視窗做複製,這種場景下常用的做法是先直接將主庫的資料目錄整體拷貝到從庫,再啟動複製。具體步驟如下。

1.在master節點建立測試庫和測試表

CREATE DATABASE test;
Query OK,1 row affected (0.04 sec)
mysql> USE test;
Database changed
mysql> CREATE TABLE t(id int(10));
Query OK,0 rows affected (0.09 sec)
mysql> INSERT INTO t VALUES (111);
Query OK,1 row affected (0.05 sec)
mysql> INSERT INTO t VALUES (222);
Query OK,1 row affected (0.00 sec)
mysql> INSERT INTO t VALUES (333);
Query OK,1 row affected (0.00 sec)

2.在主庫建立複製使用者

mysql> create user 'repl'@'%' identified with mysql_native_password by 'wwwwww';
Query OK,0 rows affected (0.00 sec)

3.停止複製的所有例項,在master、slave1、slave2分別執行

[root@master ~]# ln -s /usr/local/mysql/bin/mysqladmin /usr/bin/mysqladmin
[root@master ~]# mysqladmin -hlocalhost -uroot -pwwwwww shutdown

4.複製資料至slave1、slave2

[root@master data]# cd /data
[root@master data]# scp -r mysql/ slave1:/data/
[root@master data]# scp -r mysql/ slave2:/data/

5.在slave1、slave2從庫執行命令,刪除auto.cnf檔案

[root@slave1 mysql]# cd /data/mysql
[root@slave1 mysql]# rm -rf auto.cnf
[root@slave2 mysql]# cd /data/mysql
[root@slave2 mysql]# rm -rf auto.cnf
 

6.重啟例項,在三個節點都需要執行

[root@master data]# service mysqld start
Starting MySQL.. SUCCESS!

7.在主庫檢視二進位制日誌

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File       | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000005 |   155 |       |         |          |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

8.在slave1、slave2從庫執行命令

mysql> stop slave;
Query OK,0 rows affected (0.01 sec)
mysql> change master to master_host='192.168.2.138',master_log_file='mysql-bin.000005',2 warnings (0.02 sec)
mysql> start slave;
Query OK,0 rows affected (0.03 sec)
mysql> show slave status\G

9.在slave1、slave2從庫執行命令檢視庫和表是否同步過來

mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t       |
+----------------+
1 row in set (0.00 sec)
mysql> select * from t;
+------+
| id  |
+------+
| 111 |
| 222 |
| 333 |
+------+
3 rows in set (0.00 sec)

三、mysqldump聯機

離線建立複製的需求太過理想化,大多數情況下,複製是被要求在不影響線上業務的情況下,聯機建立的,而且還要求對線上庫的影響越小越好。例如,複製過程化中對主庫加鎖會影響對主庫的訪問,因此通常是不被允許的。這種場景下有兩種備選的複製方案:使用mysqldump程式或使用如XtraBackup的第三方工具。這兩種方案有各自的適用場合。使用mysqldump聯機建立複製的過程如下。

1.在主庫建立測試的資料庫和表

mysql> CREATE DATABASE test;
Query OK,1 row affected (0.04 sec)
mysql> use test;
Database changed
mysql> CREATE TABLE t(id int(10));
Query OK,0 rows affected (0.10 sec)
mysql> INSERT INTO t VALUES(111);
Query OK,1 row affected (0.09 sec)
mysql> INSERT INTO t VALUES(222);
Query OK,1 row affected (0.00 sec)
mysql> INSERT INTO t VALUES(333);
Query OK,1 row affected (0.05 sec)
mysql> INSERT INTO t VALUES(444);
Query OK,1 row affected (0.00 sec)

2.在主庫建立複製使用者

mysql> create user 'repl'@'%' identified with mysql_native_password by 'wwwwww';
Query OK,0 rows affected (0.01 sec)
mysql> grant replication client,0 rows affected (0.01 sec)
mysql> flush privileges;
Query OK,0 rows affected (0.01 sec)
 

3.在slave1、slave2從庫建立主庫資訊

mysql> change master to master_host='192.168.2.138',master_password='wwwwww';
Query OK,2 warnings (0.04 sec)

4.在slave1、slave2從庫使用mysqldump命令複製資料

[root@slave2 ~]# mysqldump --single-transaction --all-databases --master-data=1 --host=192.168.2.138 --user=root --password=wwwwww --apply-slave-statements | mysql -uroot -pwwwwww -hlocalhost
mysql: [Warning] Using a password on the command line interface can be insecure.
mysqldump: [Warning] Using a password on the command line interface can be insecure.

引數說明

–single-transaction引數可以對Innodb表執行非鎖定匯出。此選項將事務隔離模式設定為REPEATABLE READ,並在轉儲資料之前向伺服器傳送START TRANSACTION SQL語句。它僅適用於Innodb等事務表,因為它會在發出START TRANSACTION時轉儲資料庫的一致狀態,而不會阻塞任何應用程式。因此這裡假定:1. 所有的應用資料表都使用Innodb引擎。2. 所有系統表資料在備份過程中不會發生變化。

–master-data引數會導致轉儲輸出包含類似 CHANGE MASTER TO MASTER_LOG_FILE=‘binlog.000004',MASTER_LOG_POS=1480; 的SQL語句,該語句指示主庫的二進位制日誌座標(檔名和位置)。如果選項值為2,則CHANGE MASTER TO語句將寫為SQL註釋,因此僅提供資訊,不會執行。如果引數值為1,則該語句不會寫為註釋,並在重新載入轉儲檔案時執行。如果未指定選項值,則預設值為1。

–apply-slave-statements引數會在CHANGE MASTER TO語句之前新增STOP SLAVE語句,並在輸出結尾處新增START SLAVE語句,用來自動開啟複製。

通過管道操作符,匯出匯入一步進行,不需要中間落盤生成檔案。

5.在從庫確認複製狀態

mysql> show slave status\G

6.在從庫檢視庫和表是否複製成功

use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select * from t;
+------+
| id  |
+------+
| 111 |
| 222 |
| 333 |
| 444 |
| 555 |
+------+
5 rows in set (0.00 sec)

mysqldump方式的優點是可以進行部分複製,如在配置檔案中定義replicate-do-table=db1.*,則用這種方法可以只複製db1庫而忽略其它複製事件。缺點是由於mysqldump會生成主庫轉儲資料的SQL語句,實際是一種邏輯備份方式所以速度較慢,不適用於大庫。

四、XtraBackup聯機複製

聯機建立複製的另一種可選方案是使用XtraBackup。XtraBackup是Percona公司的開源專案,用以實現類似Innodb官方的熱備份工具InnoDB Hot Backup的功能,它支援線上熱備份,備份時不影響資料讀寫。到目前為止,最新的版本為Percona XtraBackup 8.0.6,可以從https://www.percona.com/downloads/下載安裝包。XtraBackup有很多功能和優點,例如支援全備、增量備份、部分備份;支援壓縮備份;備份不影響資料讀寫、事務等,但是也有缺陷不足:例如不支援離線備份、不支援直接備份到磁帶裝置、不支援Cloud Back,MyISAM的備份也會阻塞。不過這些小瑕疵不影響XtraBackup成為一款流行的MySQL備份工具。另外,注意XtraBackup只支援Linux平臺,不支援Windows平臺。下面演示用XtraBackup聯機搭建主從複製的過程,主庫已經建立了用於執行復制的使用者repl。

在主庫建立複製使用者

mysql> create user 'repl'@'%' identified with mysql_native_password by 'wwwwww';
Query OK,0 rows affected (0.01 sec)

1.在主庫和從庫都安裝XtraBackupv

[root@master ~]# yum -y install libev
[root@master home]# yum localinstall percona-xtrabackup-80-8.0.6-1.el7.x86_64.rpm -y

2.配置主庫到從庫的SSH免密碼連線

[root@master home]# ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:GBLbrw17UVck8RyCa/fbYyLkSNZIRc5p+jPQmpkD+bI root@master
The key's randomart image is:
+---[RSA 2048]----+
|  .   .o+o+ |
|   +  +..* . |
|  o o  o*. o |
|   . +.o*..  |
|   ooS+oo .  |
|    =o=Bo . |
|   o.=B++  o |
|    .o..oo..o.|
|    E  . o .|
+----[SHA256]-----+
[root@master home]# ssh-copy-id 192.168.2.138
[root@master home]# ssh-copy-id 192.168.2.192
[root@master home]# ssh-copy-id 192.168.2.130

3.停止從庫,並刪除從庫裡面的資料

[root@slave1 home]# service mysql stop
[root@slave2 home]# service mysql stop
[root@slave1 home]# rm -rf /data/mysql/*
[root@slave2 home]# rm -rf /data/mysql/*

4.備份資料並傳輸

[root@master tmp]# xtrabackup -uroot -pwwwwww --socket=/data/mysql/mysql.sock --no-lock --backup --compress --stream=xbstream --parallel=4 --target-dir=./ | ssh [email protected] "xbstream -x -C /data/mysql/ --decompress"

執行過程中報錯,

190606 01:21:47 >> log scanned up to (19597291)

190606 01:21:47 Selecting LSN and binary log position from p_s.log_status

Error: failed to fetch query result SELECT server_uuid,local,replication,storage_engines FROM performance_schema.log_status: Access denied; you need (at least one of) the BACKUP_ADMIN privilege(s) for this operation

mysql> grant BACKUP_ADMIN on *.* to 'root'@'%';
Query OK,0 rows affected (0.01 sec)

行如下命令,刪除192.168.2.192:/data/mysql/*的內容,再次執行命令,發現已經正確了。成功執行如下所示:

淺談MySQL8.0 非同步複製的三種方式

這條命令連線主庫,進行並行壓縮流式備份,同時將備份通過管道操作符傳輸到從庫,並直接解壓縮到從庫的資料目錄。所有操作一條命令完成,不需要中間落盤生成檔案。

5.在從庫恢復備份

[root@slave1 /]# xtrabackup --prepare --target-dir=/data/mysql
[root@slave2 /]# xtrabackup --prepare --target-dir=/data/mysql

6.在從庫檢視二進位制bin-log日誌

[root@slave1 mysql]# cat xtrabackup_binlog_info 
mysql-bin.000008    155
[root@slave2 mysql]# cat xtrabackup_binlog_info 
mysql-bin.000009    155

7.啟動從庫

[root@slave1 data]# service mysqld start
Starting MySQL... SUCCESS! 
[root@slave2 data]# service mysqld start
Starting MySQL... SUCCESS!

8.建立主庫資訊,其中的master_log_file和master_log_pos值來自第6步

mysql> change master to master_host='192.168.2.138',master_log_file='mysql-bin.000008',2 warnings (0.04 sec)
mysql> start slave;
Query OK,0 rows affected (0.00 sec)
mysql> show slave status\G

9.在從庫測試資料

mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select * from t;
+------+
| id  |
+------+
| 111 |
| 222 |
| 333 |
| 444 |
| 555 |
+------+
5 rows in set (0.00 sec)

XtraBackup是物理複製,效能比mysqldump高的多,而且對主庫的影響極小,非常適用於從頭聯機建立高負載、大資料量、全例項從庫的場景。

到此這篇關於淺談MySQL8.0 非同步複製的三種方式的文章就介紹到這了,更多相關MySQL8.0 非同步複製內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!