如何使用 MySQL 5.7 內置的 InnoDB 集群

最近到處查資料的時候,發現MySQL 5.7 終於實現了原生的基於InnoDB的集群功能,於是在此寫一篇文章介紹如何配置。

我在資料庫領域見識尚淺,本文只解釋如何配置和使用,不涉及和其他方案的對比和調優。

核心架構

  • MySQL 5.7 引入了 Group Replication 功能,可以在一組 MySQL 伺服器之間實現自動主機選舉,形成一主多從結構。經過高級配置後,可以實現多主多從結構。
  • MySQL Router 是一個輕量級透明中間件,可以自動獲取上述集群的狀態,規劃 SQL 語句,分配到合理的 MySQL 後端進行執行。
  • MySQL Shell 是一個同時支持 JavaScript 和 SQL 的交互程序,可以快速配置 InnoDB Cluster。

以上三個組件構成了 MySQL InnoDB Cluster

配置演示

1) 創建環境

使用 VirtualBox 創建三個 CentOS 7.4 伺服器,命名為 db1,db2,db3,並配置為 「NAT 網路」(而非 「網路地址轉換(NAT)」)。

# 安裝 mysql.com yum 源nwget https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpmn# 安裝 mysql-community-server、mysql-shellnyum install mysql57-community-release-el7-11.noarch.rpmnyum install mysql-community-server mysql-shelln# 啟動 mysqldnsystemctl enable mysqldnsystemctl start mysqldn# 找到隨機密碼ncat /var/log/mysqld.log | grep passwordn# 配置,注意允許 remote root 訪問nmysql_secure_installationn# 允許 root 遠程訪問necho "UPDATE mysql.user SET host = % WHERE user = root;FLUSH PRIVILEGES;" | mysql -u root -pn# firewalld 配置nfirewall-cmd --add-service=mysql --permanentnfirewall-cmd --add-port=13306/tcp --permanentnfirewall-cmd --reloadn# selinux 配置nyum install policycoreutils-pythonnsemanage port -a -t mysqld_port_t -p tcp 13306n

以上配置了三個獨立的 MySQL 伺服器,互相可以通過內網訪問,並可以互相使用 root 用戶。

生產環境上不建議直接使用 root 用戶,如何配置專用用戶許可權,參見官方文檔 20.2.5 Production Deployment of InnoDB Cluster

然後配置 hosts 表,使得這三台伺服器互相可以使用 db1, db2, db3 解析到對方內網地址。

配置每台服務 my.cnf 中 report_host 欄位,為自己的 hostname

2) 檢查 MySQL 配置

在任一台伺服器上啟動 mysql-shell

mysqlshn

使用JS命令,檢查每台伺服器的配置。

dba.checkInstanceConfiguration(root@db1:3306) // 生產模式下此處使用專用用戶n

上述命令會執行一系列檢查,列出有問題的配置,比如:

+----------------------------------+---------------+----------------+--------------------------------------------------+n| Variable | Current Value | Required Value | Note |n+----------------------------------+---------------+----------------+--------------------------------------------------+n| binlog_checksum | CRC32 | NONE | Update the server variable or restart the server |n| enforce_gtid_consistency | OFF | ON | Restart the server |n| gtid_mode | OFF | ON | Restart the server |n| log_bin | 0 | 1 | Restart the server |n| log_slave_updates | 0 | ON | Restart the server |n| master_info_repository | FILE | TABLE | Restart the server |n| relay_log_info_repository | FILE | TABLE | Restart the server |n| transaction_write_set_extraction | OFF | XXHASH64 | Restart the server |n+----------------------------------+---------------+----------------+--------------------------------------------------+n

3)修正 MySQL 配置

此時,可以在各台伺服器自己的 mysqlsh 上執行

dba.configureLocalInstance(root@localhost:3306) // 此處必須使用 root 用戶n

可以自動修復配置並寫入 my.cnf

也可以按照給出的建議,手工修改各個伺服器 my.cnf 中的配置。注意,在啟用 binlog 的時候,需要額外增加 server_id 選項,分別設置為 1, 2, 3

自動配置或手動配置後,重啟MySQL,並重新執行 dba.checkInstanceConfiguration,當輸出

{n "status": "ok"n}n

的時候,表示該伺服器檢查通過。按上述步驟,完成三台伺服器的配置

3) 創建集群

以 db1 為起始主節點,在上面運行 mysqlsh

mysqlsh --uri root@db1:3306 // 生產模式下,此處使用專用用戶n

執行命令,完成集群創建和子節點添加

// 創建集群nvar cluster = dba.createCluster(main)n// 添加子節點ncluster.addInstance(root@db2:3306) // 生產模式下,此處使用專用用戶ncluster.addInstance(root@db3:3306) // 生產模式下,此處使用專用用戶n// 查看節點信息ncluster.status()n

至此,一個3節點,一主多從節點創建完成

創建節點後,在兩個子節點上執行 dba.configureLocalInstance,更新 METADATA

4) MySQL Router 的配置

假設將 mysqlrouter 安裝在 db2 上,實際生產中可以安裝在其他的伺服器上。

yum install mysql-routern

使用主節點獲取配置

mysqlrouter --bootstrap root@db1:3306 --user mysqlrouter #生產模式下,此處使用專用用戶n

此命令會更新 /etc/mysqlrouter/mysqlrouter.conf 中的配置信息

啟動 mysqlrouter

systemctl start mysqlrouternsystemctl enable mysqlroutern

查看日誌,就能看到 mysqlrouter 已經啟動並準備就緒。

此時嘗試連接 6446 埠(讀/寫)

mysql -u root -h 127.0.0.1 -P 6446 -pn

執行命令

SELECT @@port;n

就能夠看到輸出的結果是 3306,也就是已經經由 SQL Router 負載給後端 MySQL 伺服器了。

當主節點失效的時候,集群會自動重新選舉主節點,SQL Router 也會自動感知這一過程,更新路由。

更多詳細信息,諸如多主節點配置,請參閱 mysql.com 上的官方文檔 MySQL 5.7 Reference Manual :: 20 InnoDB Cluster


推薦閱讀:

GitHub 的 MySQL 基礎架構自動化測試
MySQL中的 MyISAM 讀的效率高,InnoDB 寫的效率高,原理是什麼?(只針對這兩種存儲引擎的對比)
mysql DBA技術難度低為什麼工資比oracle高?
mysql注入篇

TAG:MySQL | InnoDB | 数据库 |