MySQL 8 InnoDB 集群管理


使用 dba.checkInstanceConfiguration()

在添加實例到集群中前,使用該方法檢查實例配置是否滿足InnoDB 集群要求。

 

使用 dba.configureLocalInstance() 配置實例

在MySQL Server版本不支持持久化功能的實例上,需要使用該方法添加修改配置信息到本地實例的選項文件中。比如下面的更改集群配置的操作:

 

• dba.configureInstance()
• dba.createCluster()
• Cluster.addInstance()
• Cluster.removeInstance()
• Cluster.rejoinInstance()

 

使用 dba.getCluster() 接收 InnoDB 集群

dba.createCluster() 返回集群對象。該對象可以賦值給變量。如果后面需要獲取已創建集群對象,可以通過該方法。

 

使用 cluster.describe()

 

該方法用於獲取集群結構信息。

 

使用 Cluster.status() 檢查實例狀態

 

在檢查集群狀態之前,需要通過連接到集群中的任意實例獲取集群對象的引用(reference)。如果需要更改集群對象,需要連接到R/W 實例。

實例狀態直接反應集群狀態報告提供的信息,因而需要連接到一個在線實例。

擴展信息:cluster.status({'extended':0}) 支持extended擴展操作,可取值包括:0、1、2、3.

 

監控恢復操作

cluster.status()如果顯示為Recovering狀態。存在兩種恢復方式:克隆、增量。

 

InnoDB集群和組復制協議

從MySQL 8.0.16版本,組復制有一個通信協議。這個通信協議一般需要顯式的管理。因為通信協議的版本要兼容最久組復制成員數據庫版本。但是如果是使用AdminAPI管理集群,一般就不需要管理員干預了。AdminAPI會自動根據集群成員版本的變更而自動調整。

 

檢查實例的MySQL版本

MySQL文檔給出了三個方法都可以查看實例的MySQL版本,但測試只有cluster.status() 方法可行。

其他兩個方法:cluster.describe() 和 cluster.rescan()

 

super read-only 和 實例

當組復制停止的時候,會將實例設置為 super read only。有三個方法可以修改這個設置,如果再將super_read_only設置為off時,注意是否有應用程序在修改實例。

 

• dba.configureInstance()
• dba.configureLocalInstance()

• dba.dropMetadataSchema()

 

注:強制設置super_read_only=off,在方法中添加選項:clearReadOnly.比如:

dba.configureInstance(instance, {clearReadOnly: true})

 

配置管理InnoDB集群的用戶

前面也提到了,在使用dba.configureInstance() 或者 dba.configureLocalInstance() 配置實例時,可以通過clusterAdmin 選項生成一個集群管用戶。這也是MySQL推薦的。

也可以通過手工方法配置集群管理用戶,賦予適當的權限。如果用戶只是用於監控集群可以賦予更少的權限。

 

配置實例自動重新加入

MySQL 8.0.16 版本開始,支持組復制自動重新加入功能。 在實例從集群中剔除后,自動重新加入集群。AdminAPI 提供autoRejoinTries 選項控制嘗試次數。默認情況下,自動重新加入功能沒有開啟。可以通過下面方法在集群級或者實例級配置該功能。

• dba.createCluster()
• Cluster.addInstance()
• Cluster.setOption()
• Cluster.setInstanceOption()

在網絡環境不穩定的集群中,這個參數可以考慮設置。但是如果集群quorum數量的成員丟失了,autoRejoinTries 選項不起作用。

與這個參數相關的另一個參數exitStateActio,在MySQL 8.0.12版本,這個參數可以設置為READ_ONLY,即在實例異常從集群中離開后的動作。在MySQL 8.0.18版本,這個參數可以設置為OFFLINE_MODE。這個模式是比較推薦的,因為如果是READ_ONLY,客戶端應用程序可能從該實例讀取舊的數據。exitStateActio 選項起作用是在嘗試完autoRejoinTries 選項配置的次數后而沒有加入到集群中的話。

如果實例正在重新加入集群,下面的操作可能受影響:

• Cluster.status()
• dba.getCluster()
• Cluster.rejoinInstance()
• Cluster.addInstance()
• Cluster.removeInstance()
• Cluster.rescan()
• Cluster.checkInstanceState()

注:Cluster.removeInstance() 如果發生在正在重新加入集群,操作失敗,除非指定froce:true 選項。

 

從InnoDB集群中刪除實例

Cluster.removeInstance(instance) 方法可以從集群中刪除實例。這個方法確保從集群在線的實例中刪除該實例的元數據,以及該實例本身的存儲的元數據。

 MySQL Shell dba.gtidWaitTimeout 選項控制如果在刪除實例時有GTID事務正在應用的等待時間。如果超時,刪除操作失敗。如果指定force 選項會刪除實例。

force 選項一般不應該使用,除非實例不可達,或者不可處理。如果指定force可能導致刪除的實例不能重新加入到集群中。

在刪除時,可以指定interactive 選項,交互式的刪除實例,在實例不可達(unreachable)時,提示是否繼續。

 

重新加入集群

如果實例離開集群,比如丟失連接,並且沒有自動重新加入集群。可以通過cluster.rejoinInstance() 方法將實例重新加入到集群中。如果實例 super_read_only=on,傳遞給這個方法的URI-Like要有權限設置super_read_only=off。

一種可能的情況就是實例加入集群時,沒有持久化配置,導致重啟后不能自動加入集群。在MySQL 8.0.17,支持PERSIST 命令后這個問題基本不存在了。如果是之前的版本,可以通過這個方法重新加入到集群中,同時注意配置的持久化。

如果實例離開集群后,做了一些操作,比如還原備份,導致實例Server UUID不同了。可能導致實例不能加入集群。因為集群中Server UUID標識實例。可以通過下面的方法處理:

cluster.removeInstance("root@instanceWithOldUUID:3306", {force: true})
cluster.rescan()

注:使用cluster.removeInstance() 方法時,必須指定force 選項,因為從集群角度,實例已經不可達了(unreachable)。先從集群中刪除舊的配置信息。通過cluster.rescan() 方法將實例添加到集群元數據中。

 

定制InnoDB 集群

當創建集群、添加實例到集群的時候,組名、本地地址、seed 實例都由AdminAPI自動配置,這在絕大部分情況下都是推薦的。MySQL也給出了自定義這些選項的方法。在dba.createCluster()或者cluster.addInstance()時傳遞指定的選項即可。

dba.createCluster()命令傳遞groupName 選項配置集群組名,對應於組復制的變量:group_replication_group_name。這個值必須要是一個有效的Server UUID。如果看過組復制那一章節,很多時候會把集群中不同實例組名設置為各自的Server UUID。這種做法是不對的。

在dba.createCluster()或者cluster.addInstance()方法中,定制實例用於集群成員通信的本地地址:localAdress 選項。對應於組復制的 group_replication_local_address 系統變量。這個地址:localAdress:port 用於集群成員內部通信。不能使用這個地址連接實例。

默認是主機名:實例端口 * 10 + 1

注意這個地址:端口在集群中所有成員可以訪問。

在dba.createCluster()或者cluster.addInstance()方法中,定制seed 實例,使用選項:groupSeeds選項。對應組復制系統變量:group_replication_group_seeds。

seed 實例是在添加實例到集群中時,用於給新增的成員作為數據源。

 

更改集群拓撲

從MySQL 8.0.15開始,支持在線更改集群拓撲。之前的版本需要先解除集群,重建集群。

Cluster.setPrimaryInstance(instance) 方法在線設置 primary 實例。

通過AdminAPI命令在線修改集群拓撲:

switchToMultiPrimaryMode() 方法切換為多 primary 模式。

注:在切換為多 primary 模式后,6447端口(默認只讀)接收讀寫,並且可通過該端口訪問所有集群成員。而6446端口(默認讀寫)只能連接到其中一個成員(之前是 primary 成員)。

Cluster.switchToSinglePrimaryMode([instance]) 方法切換到單 primary 模式。

 

設置InnoDB 集群選項

cluster.options() 方法查看當前集群、實例選項設置。添加 all 選項可以查看組復制系統變量設置。

Cluster.setOption(option, value) 方法設置集群、集群所有實例。

Cluster.setInstanceOption(instance, option, value) 方法設置單獨的集群實例。

集群和實例級選項:

 

• exitStateAction
• memberWeight

僅實例級:

• label

僅集群級:

• consistency
• expelTimeout
• clusterName

 

 

檢查實例狀態

cluster.checkInstanceState() 方法檢查實例上已存在的數據。通過對比實例上GTID與集群中的GTID作比較。這里會涉及到實例添加到集群時,如果做恢復操作。配合dba.checkInstanceConfiguration() 方法。

 

創建服務器白名單

dba.createCluster() 或者 cluster.addInstance() ,ipWhitelist 選項配置白名單,對應於組復制的group_replication_ip_whitelist 系統變量。

 

配置故障轉移一致性

從MySQL 8.0.14版本開始支持使用AdminAPI命令的 consistency 選項。在調用createCluster() 方法時,可以指定一致性選項。默認值是:EVENTUAL。對應於組復制的group_replication_consistency 系統變量。這個值在單 primary 選 primary 時,可能導致客戶端應用程序讀取舊的(stable)數據。推薦值是:consistency=1 對應於BEFORE_ON_PRIMARY_FAILOVER。

 

配置選舉過程

在single primary 模式下,在 primary 故障,集群選 primary 時,默認是通過優先通過 memberWeight 選項,對應於組復制的 group_replication_member_weight 系統變量。如果成員權重相同,對比Server UUID。

可以通過指定memberWeight 選項,這樣在做primary 選舉時優先選擇。

 

AdminAPI 腳本

MySQL Shell支持腳本配置、管理集群。比如:

shell> mysqlsh -f setup-innodb-cluster.js

注:腳本名稱后的選項是傳給給腳本的。可以通過JS中的os.argv 或者 Python 中的 sys.argv 傳遞參數。

 

解散 InnoDB 集群

Cluster.dissolve() 提供了解散現有集群的方法。刪除元數據和集群配置。但保留集群成員之間復制的數據。

如果有集群實例不可達,先考慮將其加入集群中,然后再解散集群,保證集群成員的一致性。

MySQL Shell 選項:dba.gtidWaitTimeout 指定解散集群時允許處理的GTID時間。超時導致解散操作失敗,可以通過指定force:true強制解散集群。

 

恢復丟失Quorum的集群 

Cluster.forceQuorumUsingPartitionOf(instance) 方法用於恢復集群中majority 實例丟失。這個方法具有一定的危險性,可能認為產生腦裂問題。給該方法傳遞一個在線實例,通過讀取該實例的元數據,恢復集群。

 

重啟集群

dba.rebootClusterFromCompleteOutage() 方法用於在集群完全斷電后重新配置集群。使用這個方法前先確認集群成員是否啟動,連接到集群中GTID 超集的實例。在交互模型下,對於發現的實例,MySQL Shell提示是否加入集群;對於不可達的實例,MySQL Shell提示是否從集群中刪除實例。如果不是運行在交互模式下,可以通過cluster.rejoinInstance() 和 cluster.removeInstance() 實現類似功能選項。

如果dba.rebootClusterFromCompleteOutage() 方法失敗,可以通過dba.dropMetadataSchema() 方法刪除集群元數據,然后dba.createCluster() 重建集群。

 

RESCAN 集群

 如果使用非AdminAPI命令更改集群配置,比如:手工更改實例配置以解決配置問題或者實例丟失連接。可以通過cluster.rescan()方法更新InnoDB元數據以匹配當前實力配置。

 

InnoDB集群和Auto-Increment

在InnoDB集群中使用實例時,為避免多 primary 集群模式下自增長碰撞(collisions),InnoDB集群自動根據集群模式以及實例數量配置 auto_increment_increment 和 auto_increment_offset 系統變量。

單 primary 模式下,設置auto_increment_increment=1 和 auto_increment_offset=2。

多 primary 模式下配置:

If the group is running in multi-primary mode, then when the cluster has 7 instances or less set auto_increment_increment to 7 and auto_increment_offset to 1 + server_id % 7. If a multiprimary cluster has 8 or more instances set auto_increment_increment to the number of instances and auto_increment_offset to 1 + server_id % the number of instances.

 

保護集群

 可以配置服務器使用安全連接。

創建的集群使用了SSL,則必須將服務器加入到ipWhitelist中。

dba.createCluster() 創建集群時,如果seed 實例支持SSL連接。則創建的集群支持SSL。通過cluster.addInstance() 方法添加的實例也需要支持SSL。

memberSslMode 選項支持三個可選值:AUTO(默認)、REQUIRED、DISABLED.

通過組復制adoptFromGR方法生成的集群,沒有SSL設置選項。集群的SSL配置根據組復制設置而定。

 

MySQL Router 和 元數據服務器

 如果在MySQL Router bootstrap 集群后,集群添加實例,需要MySQL Router 重新 bootstrap 更新服務器記錄的實例地址列表。

 可以bootstrap 多個 MySQL Router,信息會記錄在元數據中。從MySQL 8.0.19 版本開始,cluster.listRouters() 方法可以查看元數據中注冊的MySQL Router列表。

 MySQL 8.0.19 版本,提供方法:Cluster.removeRouterMetadata(router) 從元數據中刪除MySQL Router信息。

 

MySQL 克隆和InnoDB 集群

 添加實例到集群中,可能存在一個分布式恢復的過程:實例同步集群中的數據。之前只有一種方法:增量恢復,也就是異步復制技術。存在一個問題:如果實例需要復制的GTID事務已經PURGED,即@@gtid_purged > 0。實例所需要的事務不能在二進制日志中完全找到。這樣情況類似做MySQL 主從復制,解決的方法是利用最近的備份先恢復到實例(Slave)中。再利用復制技術同步二進制日志。

MySQL 8.0.17 版本對於這種情況提供了方便的解決方案:MySQL 克隆技術。克隆技術也是在集群中的donor(數據發送者)做數據快照,這個集群在使用cluster.addInstance() 方法添加實例時會自動判斷是否需要通過克隆來做分布式恢復。cluster.addInstance() 方法提供了3個可選值:auto(默認)、clone、incremental。

注:如果實例是通過克隆技術完成加入集群的。在克隆操作時會將實例之前的數據清除,所有沒有保存在表中的MySQL設置保存。在cluster.status() 方法中也會提供額外信息。

即使donor 實例的GTID_EXECUTED=0,也不能說明donor instance 二進制日志包含所有的事務,因為有可能donor server 之前運行時並沒有啟用GTID。因為簡單地使用 recoveryMethod 選項值:incremental 不是合理的。

recoveryMethod 默認值:auto。集群會確定在交互模式下,使用什么方法添加實例是合理的。如果是非交互模式,恢復方法需要顯示的設置。

recoveryMethod 可選值的一些說明:

clone:如果准備加入進群的實例不好數據,或者數據可丟棄。可以使用clone方式。這種方式下,MySQL Clone 插件自動安裝,恢復賬號自動創建。

incremental:使用異步復制做增量恢復。這種情況發生在:確定所有事務使用GTID,待加入實例包含集群所有GTID或者子集。

如果增量恢復與克隆技術都可以使用的話,MySQL 推薦使用克隆技術,這種做法一般會比較快的恢復事務,而且可以清除實例上不需要的數據。

 

Cluster.checkInstanceState() 與 MySQL Clone

dba.checkInstanceConfiguration() 和 Cluster.checkInstanceState() :前者驗證實例配置,后者驗證實例數據。

使用Cluster.checkInstanceState() 方法可以驗證如果donor instances 如果GTID_PURGED <> 0,而clone方法可用時,會給出建議。如果克隆方法不可用,會給出實例不可恢復警告。

 

 

dba.checkInstanceConfiguration() 和 MySQL Clone

如果dba.checkInstanceConfiguration() 發現MySQL Clone 可用,但是被disable了,會給出警告信息。 


免責聲明!

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



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