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上安裝好mysql
與mysql-shell
node01上安裝mysql-router
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"
}
status
為ok
說明配置沒問題了,可以用來建立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;