Mycat高可用解決方案二(主從復制)


Mycat高可用解決方案二(主從復制)

系統部署規划

名稱

IP

主機名稱

用戶名/密碼

配置

mysql主節點

192.168.199.110

mysql-01

root/hadoop

2/2G

mysql從節點

192.168.199.111

mysql-02

root/hadoop

2/2G

 

主機角色

Hosts文件配置

/etc/hosts

hostname配置

/etc/sysconfig/network

防火牆

Master主

192.168.199.110

127.0.0.1 localhost

127.0.0.1 mysql-01

192.168.199.110 mysql-01

192.168.199.111 mysql-02

NETWORKING=yes

HOSTNAME=mysql-01

service iptables stop

chkconfig iptables off

 

Slave從

192.168.199.111

127.0.0.1 localhost

127.0.0.1 mysql-02

192.168.199.110 mysql-01

192.168.199.111 mysql-02

NETWORKING=yes

HOSTNAME=mysql-02

service iptables stop

chkconfig iptables off

 

主從復制有兩種方式:基於日志(binlog)、基於 GTID(全局事務標示符)。本次采用基於日志(binlog)的方式。

MySQL 主從復制(也稱 A/B 復制)的原理

(1) Master將數據改變記錄到二進制日志(binary log)中,也就是配置文件log-bin指定的文件,這些記錄叫做二進制日志事件(binary log events);
(2) Slave 通過 I/O 線程讀取 Master 中的 binary log events 並寫入到它的中繼日志(relay log);
(3) Slave 重做中繼日志中的事件,把中繼日志中的事件信息一條一條的在本地執行一次,完成數據在本地的存儲,從而實現將改變反映到它自己的數據(數據重放)。

主從配置需要注意的點

(1)主從服務器操作系統版本和位數一致。

(2) Master 和 Slave 數據庫的版本要一致。

(3) Master 和 Slave 數據庫中的數據要一致。

(4) Master 開啟二進制日志,Master 和 Slave 的 server-id 在局域網內必須唯一(如果是復制的虛擬機,請把生成uuid的auto.cnf文件刪除掉,重啟mysql讓其自動生成uuid,uuid也必須是唯一的)。

主從配置的簡要步驟

1、Master 上的配置
(1) 安裝數據庫;
(2) 修改數據庫配置文件,指明 server_id,開啟二進制日志(log-bin);
(3) 啟動數據庫,查看當前是哪個日志,position 號是多少;
(4) 登錄數據庫,授權數據復制用戶(IP 地址為從機 IP 地址,如果是雙向主從,這里的還需要授權本機的 IP 地址,此時自己的 IP 地址就是從 IP 地址);
(5) 備份數據庫(記得加鎖和解鎖);
(6) 傳送備份數據到 Slave 上(scp命令);
(7) 啟動數據庫;


以上步驟,為單向主從搭建成功。

想搭建雙向主從需要的步驟:
(1) 登錄數據庫,指定 Master 的地址、用戶、密碼等信息(此步僅雙向主從時需要);
(2) 開啟同步,查看狀態
2、Slave 上的配置
(1) 安裝數據庫;
(2) 修改數據庫配置文件,指明 server_id,relay-log(如果是搭建雙向主從的話,也要開啟二進制日志 log-bin);
(3) 啟動數據庫,還原備份;
(4) 查看當前是哪個日志,position 號是多少(單向主從此步不需要,雙向主從需要);
(5) 指定 Master 的地址、用戶、密碼等信息;
(6) 開啟同步,查看狀態。

單向主從環境(也稱 MySQL A/B 復制)的搭建

1、Master(192.168.199.110)和 Slave(192.168.199.111)上都安裝了相同版本的數據庫(mysql-5.7.9)。
注意:兩台數據庫服務器的的 selinux 都要 disable(永久關閉 selinux,請修改/etc/selinux/config,將 SELINUX 改為 disabled)

2、修改 Master 的配置文件/etc/my.cnf

[root@mysql-01 ~]# vi /etc/my.cnf ## 在 [mysqld] 中增加以下配置項 ## 設置 server_id,一般設置為 IP的后一段或后兩段 server_id=110 ## 復制過濾:需要備份的數據庫,輸出 binlog #binlog-do-db=test01 ## 復制過濾:不需要備份的數據庫,不輸出(mysql 庫一般不同步) binlog-ignore-db=mysql ## 開啟二進制日志功能,可以隨便取,最好有含義 log-bin=mysql-bin ## 為每個 session 分配的內存,在事務過程中用來存儲二進制日志的緩存 binlog_cache_size=1M ## 主從復制的格式(mixed,statement,row,默認格式是 statement)
binlog_format=mixed
## 二進制日志自動刪除/過期的天數。默認值為 0,表示不自動刪除。
expire_logs_days=7
## 跳過主從復制中遇到的所有錯誤或指定類型的錯誤,避免 slave 端復制中斷。
## 如:1062 錯誤是指一些主鍵重復,1032 錯誤是因為主從數據庫數據不一致
slave_skip_errors=1062

(如想了解以上參數的更多詳細解析,大家可以直接百度參數)

 2.1 復制過濾可以讓你只復制服務器中的一部分數據,有兩種復制過濾:
(1) 在 Master 上過濾二進制日志中的事件;
(2) 在 Slave 上過濾中繼日志中的事件。如下:

2.2 MySQL 對於二進制日志 (binlog)的復制類型
(1) 基於語句的復制:在 Master 上執行的 SQL 語句,在 Slave 上執行同樣的語句。

MySQL 默認采用基於語句的復制,效率比較高。一旦發現沒法精確復制時,會自動選着基於行的復制。

(2) 基於行的復制:把改變的內容復制到 Slave,而不是把命令在 Slave 上執行一遍。從MySQL5.0 開始支持。

(3) 混合類型的復制:默認采用基於語句的復制,一旦發現基於語句的無法精確的復制時,就會采用基於行的復制。

3、啟動/重啟 Master 數據庫服務,登錄數據庫,創建數據同步用戶,並授予相應的權限

[root@mysql-01 ~]# service mysql restart Shutting down MySQL..[ OK ] Starting MySQL..[ OK ] [root@mysql-01 ~]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.9-log MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. ##創建數據同步用戶(生產環境建議密碼復雜些),並授予相應的權限 'repl'@'192.168.199.%' 或 'repl'@'192.168.%.%' mysql
> grant replication slave, replication client on *.* to 'repl'@'192.168.199.111' identified by '123456'; Query OK, 0 rows affected (0.00 sec) ## 刷新授權表信息 mysql> flush privileges; Query OK, 0 rows affected (0.00 sec) ## 查看 position 號,記下 position 號(從機上需要用到這個 position 號和現在的日志文件) mysql> show master status;

4、創建 test01 庫、表,並寫入一定量的數據,用於模擬現有的業務系統數據庫

create database if not exists test01 default charset utf8 collate utf8_general_ci; 
use test01;
DROP TABLE IF EXISTS `login_user`;
CREATE TABLE `login_user` (
`Id`
int(11) NOT NULL AUTO_INCREMENT,
`userName` varchar(
255) NOT NULL DEFAULT '' COMMENT '用戶名',
`pwd` varchar(
255) NOT NULL DEFAULT '' COMMENT '密碼',
PRIMARY KEY (`Id`)
) ENGINE
=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='用戶信息表';

INSERT INTO `login_user` VALUES (
1,'劉備','123456'),(2,'關羽','123456'),(3,'張飛','123456'),(4,'趙雲','123456');

5、為保證 Master 和 Slave 的數據一致,我們采用 主節點備份,從節點還原 來實現初始數據一致。

## 1、先臨時鎖表
mysql
> flush tables with read lock; Query OK, 0 rows affected (0.00 sec) ## 這里我們實行全庫備份,在實際中,我們可能只同步某一個庫,那也可以只備份一個庫(mysqldump在shell命令行執行 root@mysql-01 tmp]# mysqldump -p3306 -uroot -p --add-drop-table test01 > /tmp/test01.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
Enter password:
[root@mysql-01 ~]# cd /tmp
[root@mysql-01 tmp]# ll

total 8
-rw-r--r--  1 root root 2123 Jan  8 20:48 test01.sql
[root@mysql-01 tmp]#
## 注意:實際生產環境中大數據量(超 2G 數據)的備份,建議不要使用 mysqldump 進行比分,因為會非常慢。此時推薦使用 XtraBackup 進行備份。
## 2、解鎖表
mysql
> unlock tables; Query OK, 0 rows affected (0.00 sec) 將 Master 上備份的數據遠程傳送到 Slave 上,以用於 Slave 配置時恢復數據
[root@mysql-01 tmp]# scp /tmp/test01.sql root@192.168.199.111:/tmp/
root@192.168.199.111's password:
test01.sql                         100% 2123     2.1KB/s   00:00    
[root@mysql-01 tmp]#

6、接下來處理 Slave(192.168.199.111),配置文件只需修改一項,其余配置用命令來操作

[root@mysql-02 ~]# vi /etc/my.cnf ## 在 [mysqld] 中增加以下配置項 ## 設置 server_id,一般設置為 IP server_id=111 ## 復制過濾:需要備份的數據庫,輸出 binlog #binlog-do-db=test01 ##復制過濾:不需要備份的數據庫,不輸出(mysql 庫一般不同步) binlog-ignore-db=mysql ## 開啟二進制日志,以備 Slave 作為其它 Slave 的 Master 時使用 log-bin=mysql-slave-bin ## 為每個 session 分配的內存,在事務過程中用來存儲二進制日志的緩存 binlog_cache_size = 1M ## 主從復制的格式(mixed,statement,row,默認格式是 statement) binlog_format=mixed ## 二進制日志自動刪除/過期的天數。默認值為 0,表示不自動刪除。 expire_logs_days=7 ## 跳過主從復制中遇到的所有錯誤或指定類型的錯誤,避免 slave 端復制中斷。 ## 如:1062 錯誤是指一些主鍵重復,1032 錯誤是因為主從數據庫數據不一致 slave_skip_errors=1062 ## relay_log 配置中繼日志 relay_log=mysql-relay-bin ## log_slave_updates 表示 slave 將復制事件寫進自己的二進制日志 log_slave_updates=1 ## 防止改變數據(除了特殊的線程) read_only=1 如果 Slave 為其它 Slave 的 Master 時,必須設置 bin_log。
在這里,我們開啟了二進制日志,而且顯式的命名(默認名稱為 hostname,但是,如果 hostname 改變則會出現問題)。 relay_log 配置中繼日志,log_slave_updates 表示 slave 將復制事件寫進自己的二進制日志。 當設置 log_slave_updates 時,你可以讓 slave 扮演其它 slave 的 master。
此時,slave 把 SQL線程執行的事件寫進行自己的二進制日志(binary log),然后,它的 slave 可以獲取這些事件並執行它。
如下圖所示(發送復制事件到其它 Slave)

7、保存后重啟 MySQL 服務,還原備份數據

[root@mysql-02 ~]# service mysql restart Shutting down MySQL..[ OK ] Starting MySQL..[ OK ] Slave 上創建相同庫:mysql -uroot -p123456  -e create database test
或者進入mysql命令行創建數據庫
create database if not exists test01 default charset utf8 collate utf8_general_ci; use test01; 導入數據 [root@mysql-02 ~]# mysql -uroot -p test01 < /tmp/test01.sql Enter password: [root@mysql-02 ~]#

8、登錄 Slave 數據庫,添加相關參數
(Master 的 IP、端口、同步用戶、密碼、position 號、讀取哪個日志文件)

[root@mysql-02 data]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 17
Server version: 5.7.9-log MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
change master to master_host='192.168.199.110',
master_user='repl',
master_password='123456',
master_port=3306,
master_log_file='mysql-bin.000002',
master_log_pos=2555,
master_connect_retry=30
; Query OK, 0 rows affected, 2 warnings (0.01 sec) 上面執行的命令的解釋: master_host='192.168.199.110' ## Master 的 IP 地址 master_user='repl' ## 用於同步數據的用戶(在 Master 中授權的用戶) master_password='123456' ## 同步數據用戶的密碼 master_port=3306 ## Master 數據庫服務的端口 master_log_file='mysql-bin.000002' ##指定 Slave 從哪個日志文件開始讀復制數據(可 在 Master 上使用 show master status 查看到日志文件名) master_log_pos=2555 ## 從哪個 POSITION 號開始讀 master_connect_retry=30 ##當重新建立主從連接時,如果連接建立失敗,間隔多久后重試。單位為秒,默認設置為 60 秒,同步延遲調優參數。
## 查看主從同步狀態 mysql
> show slave status\G; 可看到 Slave_IO_State 為空, Slave_IO_Running 和 Slave_SQL_Running 是 No,表明 Slave 還沒有開始復制過程。
## 開啟主從同步 mysql
> start slave; Query OK, 0 rows affected (0.00 sec) ## 再查看主從同步狀態 mysql> show slave status\G;
可看到 Slave_IO_Running 和 Slave_SQL_Running 是 Yes,表明 Slave 已經開始復制過程

主要看以下兩個參數,這兩個參數如果是 Yes 就表示主從同步正常
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
由截圖中的主從同步狀態信息可以看出,我們配置的主從同步是正常的。

異常情況:
-- Last_IO_Errno: 2003 可能是主庫防火牆沒有關導致的 設置SELINUX=disabled [root@mysql-01 ~]# vi /etc/selinux/config SELINUX=disabled [root@mysql-01 ~]# service iptables status; [root@mysql-01 ~]# service iptables stop
[root@mysql-01 ~]# chkconfig iptables off 然后在從庫stop slave; start slave; 就搞定了!
即時生效,重啟后復原:service iptables stop
永久性生效,重啟后不會復原:chkconfig iptables off

可查看 master 和 slave 上線程的狀態。在 master 上,可以看到 slave 的 I/O 線程創建的連接:
Master : mysql> show processlist\G;

1.row 為處理 slave 的 I/O 線程的連接。
2.row 為處理本地命令行的線程。

Slave : mysql> show processlist\G;

1.row 為處理本地命令行的線程。

2.row 為 I/O 線程狀態。

3.row 為 SQL 線程狀態。


9、主從數據復制同步測試

(1) 在 Master 中的 test01 庫上變更數據的同步測試; mysql> INSERT INTO `login_user` VALUES (5,'同步測試 1','123456'),(6,'同步測試 2','123456'); Master 中添加完之后,登錄 Slave 中查看數據是否已同步。 (2) 在 Master 上新建一個 test02 庫 mysql> create database if not exists test02 default charset utf8 collate utf8_general_ci; 在 Slave 中查看數據庫 mysql> show databases; 最終的測試結果是,在 Master 中的操作,都成功同步到了 Slave。 10、測試過程中,如果遇到同步出錯,可在 Slave 上重置主從復制設置(選操作): (1) mysql> reset slave; (2) mysql> change master to master_host='192.168.199.110', master_user='repl', master_password='123456', master_port=3306, master_log_file='mysql-bin.00000x', master_log_pos=xx, master_connect_retry=30; (此時,master_log_file 和 master_log_pos 要在 Master 中用 show master status 命令查看) 注意:如果在 Slave 沒做只讀控制的情況下,千萬不要在 Slave 中手動插入數據,那樣數據就會不一致,主從就會斷開,就需要重新配置了。


11、上面所搭建的是單向復制的主從,也是用的比較多的,而雙向主從其實就是 Master 和Slave 都開啟日志功能,

然后在 Master 執行授權用戶(這里授權的是自己作為從服務器,也就是這里的 IP 地址是 Master 的 IP 地址),然后再在 Master 上進行 chang master 操作。

MySQL 主從數據同步延遲問題的調優基於局域網的 Master/Slave 機制在通常情況下已經可以滿足“實時”備份的要求了。如果延遲比較大,可以從以下幾個因素進行排查:

(1) 網絡延遲;

(2) Master 負載過高;

(3) Slave 負載過高;

一般的做法是使用多台 Slave 來分攤讀請求,再單獨配置一台 Slave 只作為備份用,不進行其他任何操作,就能相對最大限度地達到“實時”的要求了。


兩個可以減少主從復制延遲的參數(按需配置):
MySQL 可以指定 3 個參數,用於復制線程重連主庫:--master-retry-count,--master-connect-retry,--slave-net-timeout 。

其中 master-connect-retry 和 master-retry-count 需要在 Change Master 搭建主備復制時指定,而 slave-net-timeout 是一個全局變量,可以在 MySQL 運行時在線設置。

具體的重試策略為:備庫過了 slave-net-timeout 秒還沒有收到主庫來的數據,它就會開始第一次重試。

然后每過 master-connect-retry 秒,備庫會再次嘗試重連主庫。直到重試了 master-retry-count 次,它才會放棄重試。

如果重試的過程中,連上了主庫,那么它認為當前主庫是好的,又會開始 slave-net-timeout 秒的等待。

slave-net-timeout 的默認值是 3600 秒,master-connect-retry 默認為 60 秒,master-retry-count 默認為 86400 次。

就是說,如果主庫一個小時都沒有任何數據變更發送過來,備庫才會嘗試重連主庫。

這就是為什么在我們模擬的場景下,一個小時后,備庫才會重連主庫,繼續同步數據變更的原因。

這樣的話,如果你的主庫上變更比較頻繁,可以考慮將 slave-net-timeout 設置的小一點,避免主庫 Binlog dump 線程終止了,無法將最新的更新推送過來。

當然 slave-net-timeout 設置的過小也有問題,這樣會導致如果主庫的變更確實比較少的時候,備庫頻繁的重新連接主庫,造成資源浪費。
slave-net-timeout=seconds
參數說明:當 Slave 從 Master 數據庫讀取 log 數據失敗后,等待多久重新建立連接並獲取數據,單位為秒,默認設置為 3600 秒。

在做 MySQL Slave 的時候經常會遇到很多錯誤,需要根據具體原因跨過錯誤繼續同步,但有時候是因為網絡不穩定、網絡閃斷造成同步不正常,

如果 Slave 機器非常多的情況下,一個一個的登錄服務器去 stop slave、start slave 變得無聊而且重復。從 MySQL5.1 開始支持的解決方案配置:

master-connect-retry=seconds
參數說明:在主服務器宕機或連接丟失的情況下,從服務器線程重新嘗試連接主服務器之前睡眠的秒數。

如果主服務器.info文件中的值可以讀取則優先使用。如果未設置,默認值為60秒。

通常配置以上 2 個參數可以減少網絡問題導致的主從數據同步延遲。


一般網絡問題的錯誤是:
[ERROR] Error reading packet from server: Lost connection to MySQL server during query (server_errno=xxxx)
[ERROR] Slave I/O thread: Failed reading log event, reconnecting to retry, log ‘edu-mysqlbin.000256’ position 23456

 

推薦參考鏈接:
http://www.it165.net/database/html/201311/4851.html
http://blog.csdn.net/hguisu/article/details/7325124
http://www.woqutech.com/?p=1116
http://blog.chinaunix.net/uid-10661836-id-4116512.html
http://my.oschina.net/cimu/blog/165019
http://linuxguest.blog.51cto.com/195664/686813/
http://blog.itpub.net/29096438/viewspace-1409405/
http://blog.csdn.net/lxpbs8851/article/details/38455223
http://blog.csdn.net/seteor/article/details/17264633

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM