1. 程式人生 > >MySQL InnoDB Cluster搭建高可用資料庫叢集(centos7.x)

MySQL InnoDB Cluster搭建高可用資料庫叢集(centos7.x)

MySQL官方在4月終於推出了一套完整的、高可用的Mysql解決方案--MySQL InnoDB Cluster。這絕對是程式設計師的福音。以往做mysql主從高可用非常繁瑣,很多坑。現在利用官方的解決方案--MySQL InnoDB Cluster可以比較方便的搭建mysql高可用叢集,雖然也挺多坑的。

至於--MySQL InnoDB Cluster有什麼優點缺點,這裡不比較了,可以到官網直接看就好。

最近剛好專案需要搭建資料庫高可用,於是便嘗試使用官方推薦的方案--MySQL InnoDB Cluster。

因為這個是新推出的,網上這方面的資料比較少,官方的文件也介紹太簡單,我在搭建過程中也遇到很多問題。

最後還是成功搭建,這裡把搭建過程給大家分享一下,希望對需要的朋友有所幫助。

開始:

1、準備需要的環境

我使用的系統版本:centos7.x

首先下載搭建需要的軟體:

mysql 下載地址:

https://dev.mysql.com/downloads/mysql/

mysql-shell 下載地址:

https://dev.mysql.com/downloads/shell/

mysql-router 下載地址:

https://dev.mysql.com/downloads/router/

都選擇Linux Generic版本即可

準備3臺伺服器,node01、node02、node03 

node01作為 cluster 節點,負責建立 cluster,並作為 cluster 的路由


2、環境配置

在各臺伺服器中配置好 hosts,這一步很重要,否則可能會出現無法同步的情況,因為資料庫需要根據member_host同步,如果不配置,預設就是localhost,這樣時無法通訊的。

# vim /etc/hosts

如:

172.30.12.20 node03 
172.30.12.17 node02 
172.30.12.14 node01 

讓hosts檔案生效

# source /etc/hosts
然後重啟伺服器:
# reboot -f 

通過命令 hostnamectl  檢視瞬態主機名稱是否是設定的名稱

 Static hostname: localhost.localdomain
Transient hostname: node01  #這個就是瞬態主機名稱,mysql會根據這個來設定host
         Icon name: computer-desktop
           Chassis: desktop
        Machine ID: 9ac67df3c56f4ff18f0a7855490589bc
           Boot ID: f6f4356539884b8ba2ee79774b918359
  Operating System: CentOS Linux 7 (Core)
       CPE OS Name: cpe:/o:centos:centos:7
            Kernel: Linux 3.10.0-514.el7.x86_64
      Architecture: x86-64

如果你不想重啟伺服器,也可以通過下面的命令動態設定:

hostnamectl --transient set-hostname node01

(1)安裝基礎軟體

node 01、02、03上安裝好mysqlmysql-shell

node01上安裝mysql-router

mysql怎麼安裝這裡不介紹了,請移步另外一篇博文:http://blog.csdn.net/kokjuis/article/details/78215020

2. shell

# 直接解壓即可
tar zxf mysql-shell-1.0.9-linux-glibc2.12-x86-64bit.tar.gz mysql-shell

3. router

# 直接解壓即可
tar zxf mysql-router-2.1.3-linux-glibc2.12-x86-64bit.tar.gz mysql-router

在node01的mysql配置檔案加入高可用和叢集配置(根據自己的情況設定目錄):

[mysql]  
# 設定mysql客戶端預設字符集  
default-character-set=utf8   
socket=/usr/mysql/mysql/lib/mysql.sock  
  
[mysqld]  
#skip-name-resolve  
#設定3306埠  
port = 3306   
socket=/usr/mysql/mysql/lib/mysql.sock  
# 設定mysql的安裝目錄  
basedir=/usr/mysql/mysql 
# 設定mysql資料庫的資料的存放目錄  
datadir=/usr/mysql/mysql/data
# 允許最大連線數  
max_connections=200  
# 服務端使用的字符集預設為8位元編碼的latin1字符集  
character-set-server=utf8  
# 建立新表時將使用的預設儲存引擎  
default-storage-engine=INNODB  

max_allowed_packet=16M  

#高可用
server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW

transaction_write_set_extraction=XXHASH64

#主從複製配置
loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
#注意:這裡的地址不能用 node01:24901 這種寫法,要用IP,否則無法通訊
loose-group_replication_local_address= "172.30.12.14:24901"
loose-group_replication_group_seeds= "172.30.12.14:24901,172.30.12.17:24901,172.30.12.20:24901"
loose-group_replication_single_primary_mode=TRUE

#loose-group_replication_bootstrap_group= off
#loose-group_replication_enforce_update_everywhere_checks= FALSE
#loose-group_replication_start_on_boot=off

disabled_storage_engines = MyISAM,BLACKHOLE,FEDERATED,CSV,ARCHIVE
report_port = 3306

然後重啟mysql。

進到 mysql-shell 的安裝目錄,登入 shell ,執行配置

bin/mysqlsh

連線到本機MySQL,執行配置命令

# 連線,需要輸入密碼(123456)
mysql-js> shell.connect('[email protected]:3306');

# 執行配置命令,也需要密碼
mysql-js> dba.configureLocalInstance();
Please provide the password for '[email protected]:3306':

Detecting the configuration file...
Default file not found at the standard locations.
Please specify the path to the MySQL configuration file: /etc/my.cnf
MySQL user 'root' cannot be verified to have access to other hosts in the network.
Detecting the configuration file...
Found configuration file at standard location: /etc/my.cnf
Do you want to modify this file? [Y|n]:  [Y|n]: y
Validating instance...

The instance 'localhost:3306' is valid for Cluster usage
You can now use it in an InnoDB Cluster.

{
    "status": "ok"
}

statusok說明配置沒問題了,可以用來建立cluster

  • 通過 mysql-shell 連線 node01 建立 cluster

  • 登入 shell,連線 node01,建立 cluster

bin/mysqlsh 

# 連線01
mysql-js> shell.connect('[email protected]:3306');

# 建立一個 cluster,命名為 'myCluster'
mysql-js> var cluster = dba.createCluster('myCluster');

# 建立成功後,檢視cluster狀態
mysql-js> cluster.status();

{
    "clusterName": "myCluster", 
    "defaultReplicaSet": {
        "name": "default", 
        "primary": "node01:3306", 
        "status": "OK_NO_TOLERANCE", 
        "statusText": "Cluster is NOT tolerant to any failures. 1 member is not active", 
        "topology": {
            "node01:3306": {
                "address": "node01:3306", 
                "mode": "R/W", 
                "readReplicas": {}, 
                "role": "HA", 
                "status": "ONLINE"
            }        
        }
    }
}

(3)新增例項節點 node02

  • 配置 node02 的 mysql 並啟動

編輯配置檔案my.cnf,內容與 node01 上的一樣,只有2行不同

server_id=2
改成本機的IP:loose-group_replication_local_address= "172.30.12.17:24901"
  • 通過本機 mysql-shell 對 mysql 進行配置

登入 shell ,執行配置

bin/mysqlsh 

mysql-js> shell.connect('[email protected]:3306');
mysql-js> dba.configureLocalInstance();
  • 停掉 mysql,修改 my.cnf,新增配置項

# 在末尾新增
group_replication_allow_local_disjoint_gtids_join=ON

重啟MySQL

  • 通過 node01 的 mysql-shell 新增 node02 到 cluster

# 新增例項
cluster.addInstance('[email protected]:3306');

# 建立成功後,檢視cluster狀態
mysql-js> cluster.status();

(4)新增例項節點 node03

過程與 node02 完全相同,只需要注意 my.cnf 中的 'server_id' 值改為 3,

也是改成node03的ip:loose-group_replication_local_address= "172.30.12.20:24901"

重啟MySQL

  • 通過 node01 的 mysql-shell 新增 node03 到 cluster

# 新增例項
cluster.addInstance('[email protected]:3306');

# 建立成功後,檢視cluster狀態
mysql-js> cluster.status();

(5)安裝 router

進入 node01 中 mysql-router 安裝目錄執行命令

./bin/mysqlrouter --bootstrap [email protected]:3306 -d myrouter --user=root 

這裡會在mysql-router 目錄生成router配置檔案,我們把配置檔案修改一下:

# File automatically generated during MySQL Router bootstrap
[DEFAULT]
user=root
logging_folder=/usr/mysql/mysql-router/myrouter/log
runtime_folder=/usr/mysql/mysql-router/myrouter/run
data_folder=/usr/mysql/mysql-router/myrouter/data
keyring_path=/usr/mysql/mysql-router/myrouter/data/keyring
master_key_path=/usr/mysql/mysql-router/myrouter/mysqlrouter.key

[logger]
level = INFO

[routing:read_write]
#指定mysql router繫結的伺服器
bind_address = 172.30.12.14
#指定繫結的埠
bind_port = 7001
#讀寫模式(read-write, read_only)
mode = read-write
#指定mysql server 列表 (ip:port 格式,使用逗號分隔)
destinations = 172.30.12.14:3306
#最大連線數
max_connections = 1000
#最大錯誤連線數
#max_connect_errors = 100
#連線超時時間
connect_timeout = 9

[routing:read_only]
bind_address = 172.30.12.14
bind_port = 7002
mode = read-only
destinations = 172.30.12.17:3306,172.30.12.20:3306
max_connections = 1000
#max_connect_errors = 100
connect_timeout = 9

然後啟動
mysqlrouter --config /usr/mysql/mysql-router/myrouter/mysqlrouter.conf &

然後把mysql連線埠改成7001(配置檔案中配置的讀寫埠)即可。

可能遇到的問題:

一般可以這樣解決,停止叢集:

在資料庫上執行:

STOP GROUP_REPLICATION;

RESET MASTER;
RESET SLAVE;

登入 shell ,執行

bin/mysqlsh 

mysql-js> shell.connect('[email protected]:3306');
mysql-js> dba.rebootClusterFromCompleteOutage('myCluster');#上面配置的名稱
一般就會恢復,然後重新
cluster.addInstance('[email protected]:3306');
cluster.addInstance('[email protected]:3306');


在資料庫中檢視:

SELECT * FROM performance_schema.replication_group_members;


這樣就表示叢集成功了。

如果你的主從不同步,一般可以這樣解決:

從master中匯出資料庫,到slave中匯入資料。

在master通過命令:SHOW MASTER STATUS; 

記下 file 和 position

在slave中執行:

CHANGE MASTER TO MASTER_HOST = '172.30.12.14',MASTER_PORT = 3306,MASTER_USER = 'root',MASTER_PASSWORD='123456',MASTER_LOG_FILE='master-bin.000001',MASTER_LOG_POS=1172;

然後從新enjoin一下即可。 新增一個新的從機,可以有兩種方式:從 master 機器複製; 另一種是直接從 slave 複製. 複製主庫要步驟: ==================== 1.將記憶體中的資料同步到表中. 2.鎖定表,不讓出現髒資料 3.備份 4.解鎖 5.在另一臺機器上同步資料,並且設定 master_log_file 和 master-log_pos 命令: a.同步資料,並鎖表: mysql> flush tables with read lock; b.記住當前 binlog 的偏移值,後面設定 slave 上的值. show master status; 記下 file 和 position 命令: [[email protected] ~] mysqldump --all-databases --host=master-1 > backup.sql d.解鎖 mysql> unlock tables; e.同步從機.將 backup.sql 複製到從機上.[[email protected] ~] mysql --host=slave-1 < backup.sql 設定從機:  mysql>change master to master_host = '192.168.3.119',master_port = 3306,master_user = 'repl_user',master_password='root',master_log_file='master-bin.000005',master_log_pos=194244; 這裡的 master_log_file 和 master_log_pos 就是前面第 2 步中記下來的兩個值. 開啟從機 start slave; 複製從庫要步驟: ==================== 可以看到,從主庫複製會有段時間鎖表,這段時間會影響主庫的使用。如果我們能直接從從庫進行復制,就不會對主庫產生影響了。但是,從從庫複製要保證的是複製過程中從庫上的資料不會發生變化,所以要先停掉從庫。 1.停止從庫: mysql> stop slave; 2.看當前從庫的狀態。和前面的看主庫狀態一樣。但現在是從從庫複製,所以檢視從庫狀態:mysql> show slave status; 記下 Relay_Master_Log_file 和 Exec_Master_Log_Pos, 用處和前面一樣. 3.備份從庫資料.用 mysqldump 4.在新的從庫上還原資料 5.設定新從庫的 slave 引數.change master to master_host = '192.168.3.119',master_port = 3306,master_user = 'repl_user',master_password='root',master_log_file='master-bin.000005',master_log_pos=194244; 可以看到,雖然新從庫是從從庫複製的資料,但實際上 binlog 的 master 還是指向的主庫。 另外,這裡將 master_log_file 和 master_log_pos 設定成第 2 步中的 Relay_Master_Log_file 和 Exec_Master_Log_Pos start slave;