MySQL 5.7: 使用組複製(MySQL Group Replication)
MySQL 5.7: 使用MySQL Router實現應用程序的高可用
MySQL 5.7: 把現有的複製組遷移到InnoDB Cluster
MySQL 5.7: 使用PMM監視和管理數據庫html
前面一片文章說了如何配置MySQL的分組複製. 基於分組複製的機制, 當主節點崩潰離開集羣, 剩餘的其餘節點會相互協商, 而後選舉一個新的主節點. 這裏有一個問題, 就是應用程序端若是鏈接到了主節點, 這時主節點崩潰離開集羣. 可用的數據庫IP地址發生變化. 客戶端應用程序這個時候仍是會向失敗的節點嘗試鏈接, 雖然能夠修改客戶端應用程序的鏈接配置, 可是這種狀況基本是不現實的.mysql
雖然咱們能夠經過下面的SQL語句獲取主節點的IP地址sql
SELECT * FROM performance_schema.replication_group_members WHERE MEMBER_ID = ( SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME= 'group_replication_primary_member' );
可是經過應用程序動態的獲取可用數據庫的IP地址. 這種方式感受不怎麼好. 很麻煩, 要寫多餘的代碼.shell
配置MySQL Router首先須要MySQL Shell 工具, 在 MySQL Shell 部分有詳細的說明數據庫
下面是MySQL Router 和集羣的基本關係圖bootstrap
上圖充分說明了, MySQL Router 在InnoDB集羣裏面的角色. 主要做用是爲數據庫集羣提供一個虛擬IP. 做爲應用程序單一鏈接點. 經過這個單一的鏈接點實現負載均衡, 讀寫分離, 故障轉移等數據庫高可用方案.segmentfault
推薦安裝在應用程序所在的機器上, 緣由包括:服務器
經過Unix套接字鏈接, 而不是TCP/IP, 提高性能網絡
下降網絡延遲session
MySQL實例不須要額外的帳號, 只須要一個 router@198.51.100.45, 而不是 myapp@%
提高應用程序服務器的彈性
wget https://dev.mysql.com/get/mysql-apt-config_0.8.9-1_all.deb dpkg -i mysql-apt-config_0.8.9-1_all.deb aptitude update aptitude install -y mysql-router
mysqlrouter --bootstrap 172.18.149.213:3306 --directory /data/mysqlrouter --user=root --conf-use-sockets --force
Please enter MySQL password for root: Bootstrapping MySQL Router instance at /data/mysqlrouter... MySQL Router has now been configured for the InnoDB cluster 'dc'. The following connection information can be used to connect to the cluster. Classic MySQL protocol connections to cluster 'dc': - Read/Write Connections: localhost:6446 - Read/Write Connections: /data/mysqlrouter/mysql.sock - Read/Only Connections: localhost:6447 - Read/Only Connections: /data/mysqlrouter/mysqlro.sock X protocol connections to cluster 'dc': - Read/Write Connections: localhost:64460 - Read/Write Connections: /data/mysqlrouter/mysqlx.sock - Read/Only Connections: localhost:64470 - Read/Only Connections: /data/mysqlrouter/mysqlxro.sock
輸入密碼後, 文件就生成到 /data/mysqlrouter 目錄了.
--conf-use-sockets 選項還會監聽Unix套接字
關於 MySQL Router 命令行的全部參數說明, 參考這裏: https://dev.mysql.com/doc/mys...
cd /data/mysqlrouter ./start.sh PID 3976 written to /data/mysqlrouter/mysqlrouter.pid
下面列出了MySQL Router 監聽的TCP端口
netstat -anpt |grep router tcp 0 0 0.0.0.0:64460 0.0.0.0:* LISTEN 3976/mysqlrouter tcp 0 0 0.0.0.0:6446 0.0.0.0:* LISTEN 3976/mysqlrouter tcp 0 0 0.0.0.0:6447 0.0.0.0:* LISTEN 3976/mysqlrouter tcp 0 0 0.0.0.0:64470 0.0.0.0:* LISTEN 3976/mysqlrouter tcp 0 0 172.18.149.215:44350 172.18.149.213:3306 ESTABLISHED 3976/mysqlrouter
各個端口的含義咱們在以前建立MySQL Router配置時的輸出已經說明了, 另外配置文件中也詳細說明了每一個端口的含義:
cat /data/mysqlrouter/mysqlrouter.conf
# File automatically generated during MySQL Router bootstrap [DEFAULT] user=root logging_folder=/data/mysqlrouter/log runtime_folder=/data/mysqlrouter/run data_folder=/data/mysqlrouter/data keyring_path=/data/mysqlrouter/data/keyring master_key_path=/data/mysqlrouter/mysqlrouter.key [logger] level = DEBUG [metadata_cache:dc] router_id=1 bootstrap_server_addresses=mysql://172.18.149.213:3306,mysql://172.18.149.215:3306,mysql://172.18.149.214:3306 user=mysql_router1_4d98tioywyow metadata_cluster=dc ttl=300 [routing:dc_default_rw] bind_address=0.0.0.0 bind_port=6446 socket=/data/mysqlrouter/mysql.sock destinations=metadata-cache://dc/default?role=PRIMARY mode=read-write protocol=classic [routing:dc_default_ro] bind_address=0.0.0.0 bind_port=6447 socket=/data/mysqlrouter/mysqlro.sock destinations=metadata-cache://dc/default?role=SECONDARY mode=read-only protocol=classic [routing:dc_default_x_rw] bind_address=0.0.0.0 bind_port=64460 socket=/data/mysqlrouter/mysqlx.sock destinations=metadata-cache://dc/default?role=PRIMARY mode=read-write protocol=x [routing:dc_default_x_ro] bind_address=0.0.0.0 bind_port=64470 socket=/data/mysqlrouter/mysqlxro.sock destinations=metadata-cache://dc/default?role=SECONDARY mode=read-only protocol=x
下面列舉除了MySQL Router監聽的Unix套接字(若是使用了--conf-use-sockets選項)
netstat -anpx |grep router unix 2 [ ACC ] STREAM LISTENING 41668 3791/mysqlrouter /tmp/myrouter/mysql.sock unix 2 [ ACC ] STREAM LISTENING 42187 3791/mysqlrouter /tmp/myrouter/mysqlro.sock unix 2 [ ACC ] STREAM LISTENING 43361 3791/mysqlrouter /tmp/myrouter/mysqlx.sock unix 2 [ ACC ] STREAM LISTENING 42189 3791/mysqlrouter /tmp/myrouter/mysqlxro.sock
咱們看到有4個Unix套接字
Unix 套接字 | 說明 | 讀寫模式 |
---|---|---|
mysql.sock | MySQL協議 | 讀寫 |
mysqlro.sock | MySQL協議 | 只讀 |
mysqlx.sock | X 協議 | 讀寫 |
mysqlxro.sock | X 協議 | 只讀 |
注意: 該表只是說明了每一個Unix套接字承擔的角色, 沒有限制你鏈接到只讀模式的端口執行寫操做.
mysql -u root -h 172.18.149.215 -P 6446 -p # 建立數據庫 mysql> create database b; Query OK, 1 row affected (0.00 sec) # 切換 mysql> use b; Database changed # 建立表 mysql> create table a (c int); Query OK, 0 rows affected (0.00 sec) # 插入值 # 出錯了, 由於沒有主鍵 mysql> insert into a values(1); ERROR 3098 (HY000): The table does not comply with the requirements by an external plugin. # 添加主鍵列 mysql> alter table a add column a_id int(4); Query OK, 0 rows affected (0.00 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> alter table a add primary key pk (a_id); Query OK, 0 rows affected (0.00 sec) Records: 0 Duplicates: 0 Warnings: 0 # 插入值 mysql> insert into a values (1,2); Query OK, 1 row affected (0.01 sec)
OK, MySQL Router到這裏就配置好了, 在應用程序代碼裏面直接鏈接到MySQL Router的IP地址能夠了.
MySQL Router 在初始化配置的時候是鏈接到集羣節點讀取集羣的元數據的. 若是在集羣中新增或減小節點. 須要同步更新MySQL Router的配置, 從新執行如下命令便可:
mysqlrouter --bootstrap 172.18.149.213:3306 --directory /data/mysqlrouter --user=root --conf-use-sockets --force
固然, 更新了MySQL Router的配置的配置, 須要重啓MySQL Router:
cd /data/mysqlrouter ./stop.sh ./start.sh
MySQL Router 目前只支持500併發鏈接(https://dev.mysql.com/doc/mys... 官方建議把 MySQL Router 部署到和應用程序相同的一臺機器上. 經過MySQL Router 的 --conf-use-sockets 啓動選項, 咱們能夠把MySQL Router做爲一個本地代理來使用.
爲了解決MySQL Router的單點問題. 咱們能夠在MySQL Router的上層在搭建一個負載均衡服務器. 我如今的環境所有是基於阿里雲的, 所以很天然的選擇了阿里雲的SLB做爲負載均衡解決方案. 若是自建服務器能夠選擇LVS, HAProxy等方案.
在MySQL Router之上再作負載均衡. 管理上更復雜了, 這裏仍是採用一個應用程序部署一個本地MySQL Router的策略.
交互式代碼執行
支持的語言: Javascript, Python, SQL
批處理
輸出格式: 製表符, 表格, JSON
多行支持
日誌
MySQL協議支持, X Protocol支持
wget https://dev.mysql.com/get/mysql-apt-config_0.8.9-1_all.deb dpkg -i mysql-apt-config_0.8.9-1_all.deb aptitude update aptitude install -y mysql-shell
mysqlsh --uri ${uri}
URI 支持系列各類形式
mysqlx://user@localhost:33065 mysql://user@localhost:3333 mysqlx://user@server.example.com/ mysqlx://user@198.51.100.14:123 mysqlx://user@[2001:db8:85a3:8d3:1319:8a2e:370:7348] mysqlx://user@198.51.100.1/world%5Fx mysqlx://user@198.51.100.2:33060/world
--dbuser (-u) value --dbpassword value --host (-h) value --port (-P) value --schema (-D) value --password (-p) --socket (-S)
--user is equivalent to --dbuser --password is equivalent to --dbpassword --database is equivalent to --schema
參數的優先級比URL高, 下面的例子經過 otheruser 用戶進行鏈接而不是URL中指定的 user
mysqlsh --uri user@localhost:33065 --user otheruser
# MySQL協議 mysqlsh --mysql -u user -h localhost # X協議 mysqlsh --mysqlx -u user -h localhost -P 33065
# X協議 var session=mysqlx.getSession('root@localhost:33060', 'password'); # MySQL協議 var session = mysql.getClassicSession('root@localhost:3306', 'password');
var session=mysqlx.getSession({host: 'localhost', dbUser: 'root', dbPassword: 'password', ssl_ca: "path_to_ca_file", ssl_cert: "path_to_cert_file", ssl_key: "path_to_key_file" });
若是從支持X Protocol的客戶端鏈接到數據庫, 在數據庫端須要安裝X Plugin以提供對 X Protocol的支持, 安裝X Plugin只須要對 mysql.plugin 表有 INSERT 權限便可.
1.經過 mysqlsh 安裝
# 安裝須要的倉庫, 選中 MySQL Tools & Connectors (Currently selected: Enabled) wget https://dev.mysql.com/get/mysql-apt-config_0.8.9-1_all.deb dpkg -i mysql-apt-config_0.8.9-1_all.deb
執行以下命令, 輸入密碼:
mysqlsh -u root -h localhost --classic --dba enableXProtocol
若是看到以下輸出, 標識安裝完成:
mysqlsh -u root -h 172.18.149.213 --classic --dba enableXProtocol
Creating a Classic Session to 'root@172.18.149.213' Enter password: Your MySQL connection id is 70 Server version: 5.7.20-log MySQL Community Server (GPL) No default schema selected; type \use <schema> to set one. enableXProtocol: Installing plugin mysqlx... enableXProtocol: done
2.經過MySQL客戶端
mysql -u user -p mysql> INSTALL PLUGIN mysqlx SONAME 'mysqlx.so';
插件的加載須要 mysql.session 用戶, mysql.session 用戶在 MySQL 5.7.19 中已經添加. 早期的版本須要執行 mysql_upgrade, 不然加載X插件的時候回報錯:
There was an error when trying to access the server with user: mysql.session@localhost. Make sure the user is present in the server and that mysql_upgrade was ran after a server update..
mysqlsh -u root --sqlc -e "show plugins" mysql -u root -p -e "show plugins" mysql> select * from plugin; +-------------------+----------------------+ | name | dl | +-------------------+----------------------+ | group_replication | group_replication.so | | mysqlx | mysqlx.so | +-------------------+----------------------+
若是在輸出中看到 mysqlx.so 標識X插件安裝成功. X插件安裝過程會自動建立一個用戶: mysqlxsys@localhost
UNINSTALL PLUGIN mysqlx;
刪除插件的同時也會刪除 mysqlxsys@localhost 用戶.
https://dev.mysql.com/doc/ref...
https://dev.mysql.com/doc/mys...
https://dev.mysql.com/doc/mys...
https://dev.mysql.com/doc/mys...