MySQL InnoDB Cluster部署方案与实践
MySQL InnoDB Cluster
一、InnoDB Cluster 基本概述
MySQL InnoDB Cluster 為 MySQL 提供了一個(gè)完整的高可用解決方案。通過使用 MySQL Shell 提供的 AdminAPI,你可以輕松地配置和管理一組至少由3個(gè)MySQL服務(wù)器實(shí)例組成的 InnoDB 集群。
InnoDB 集群中的每個(gè) MySQL 服務(wù)器實(shí)例都運(yùn)行 MySQL Group Replication(組復(fù)制),該復(fù)制提供了在 InnoDB 集群中復(fù)制數(shù)據(jù)的機(jī)制,具有內(nèi)置的故障切換功能。AdminAPI 使我們避免了直接在 InnoDB 集群中使用組復(fù)制。從 MySQL 8.0.27開始,你還可以通過鏈接一個(gè)主 InnoDB 集群及其一個(gè)或多個(gè)異地(例如不同數(shù)據(jù)中心)副本來組成 InnoDB ClusterSet,以此來提供異地容災(zāi)功能。
MySQL Router 可以根據(jù)你部署的集群自動(dòng)配置自己,并將客戶端應(yīng)用程序透明地連接到 MySQL 服務(wù)器實(shí)例。如果 MySQL 服務(wù)器實(shí)例發(fā)生意外故障,集群將自動(dòng)重新配置。在默認(rèn)的單主模式下,InnoDB 集群只有一個(gè)讀寫服務(wù)器實(shí)例–主服務(wù)器,多個(gè)輔助服務(wù)器實(shí)例是主服務(wù)器的副本。如果主服務(wù)器故障,輔助服務(wù)器將自動(dòng)升級(jí)為主服務(wù)器角色。MySQL Router 檢測(cè)到這一點(diǎn)后,會(huì)將客戶端應(yīng)用程序的請(qǐng)求轉(zhuǎn)發(fā)到新的 MySQL 主服務(wù)器上。高級(jí)用戶還可以將集群配置為具有多個(gè)主節(jié)點(diǎn),但大多情況都不必要這樣做。
InnoDB 集群至少由三個(gè) MySQL 服務(wù)器實(shí)例組成,并提供高可用性和可擴(kuò)展性功能。將使用到以下 MySQL 技術(shù):
- MySQL Shell,它是MySQL官方提供的高級(jí)客戶端和代碼編輯器。
- MySQL Server 和 Group Replication(組復(fù)制),它們配合工作可以使一組MySQL實(shí)例對(duì)外提供高可能性。InnoDB Cluster提供了另一種易于使用的編程方式來使用Group Replication(組復(fù)制)功能。
- MySQL Router,一個(gè)能在應(yīng)用程序和InnoDB集群之間提供透明路由的輕量級(jí)中間件,是官方提供的MySQL實(shí)例負(fù)載均衡器(不再需要借助類似HAProxy的第三方負(fù)載均衡器了)。
基于MySQL的Group Replication(組復(fù)制)構(gòu)建的集群,可提供自動(dòng)成員管理、容錯(cuò)、自動(dòng)故障切換等功能。InnoDB集群通常以單主模式(single-primary)運(yùn)行,具有一個(gè)主實(shí)例(primary讀寫)和多個(gè)輔助實(shí)例(secondary只讀)。高級(jí)用戶還可以利用多主模式(multi-primary),其中所有實(shí)例都是主實(shí)例。
你可以使用 MySQL Shell 提供的 AdminAPI 來操作 InnoDB集群。AdminAPI 有 JavaScript 和 Python 兩種版本,非常適合通過編寫腳本來自動(dòng)化部署MySQL,以實(shí)現(xiàn)高可用性和可擴(kuò)展性。通過使用 MySQL Shell 的 AdminAPI,你可以避免手動(dòng)配置許多實(shí)例。AdminAPI 為 MySQL 實(shí)例集(組)提供了一個(gè)高效的現(xiàn)代化接口,可以方便地在一個(gè)統(tǒng)一的工具中進(jìn)行配置、管理和監(jiān)控部署工作。
InnoDB Cluster支持MySQL Clone(克隆),這使你可以方便地向集群配置新的實(shí)例。在過去,一個(gè)新的實(shí)例加入到MySQL集群實(shí)例集之前,你可能需要通過某種方式手動(dòng)將事務(wù)傳輸?shù)酱尤氲男聦?shí)例中。這可能涉及制作文件副本、手動(dòng)復(fù)制它們等等。使用InnoDB Cluster,你只需向集群添加一個(gè)實(shí)例,它就會(huì)被自動(dòng)配置。類似地,InnoDB Cluster與 MySQL Router 也進(jìn)行了緊密集成,你可以使用AdminAPI來使它們一起工作。MySQL Router可以基于InnoDB Cluster,通過一個(gè)被稱為bootstrapping(引導(dǎo))的過程自動(dòng)化的配置它自己,你無需手動(dòng)配置路由。然后 MySQL Router 便可透明地將客戶端應(yīng)用程序連接到InnoDB集群,為客戶端連接提供路由和負(fù)載平衡。這種集成還允許你使用 AdminAPI 管理基于 InnoDB Cluster 引導(dǎo)的 MySQL Router 的某些方面。InnoDB Cluster 的集群狀態(tài)信息包含了基于集群引導(dǎo)的 MySQL Router 的詳細(xì)信息。Operations 使你可以在集群級(jí)別創(chuàng)建 MySQL Router 用戶,以使用基于集群引導(dǎo)的 MySQL Router 等等。
二、重點(diǎn)知識(shí)
2.1 InnoDB集群要求
在進(jìn)行 InnoDB Cluster 的生產(chǎn)部署安裝之前,請(qǐng)確保要使用的 MySQL 服務(wù)器實(shí)例滿足以下要求:
- InnoDB Cluster使用組復(fù)制,因此你的服務(wù)器實(shí)例必須滿足相同的要求(參考組復(fù)制要求)。AdminAPI 提供 dba.checkInstanceConfiguration() 方法來驗(yàn)證某個(gè)實(shí)例是否滿足組復(fù)制要求,以及 dba.configureInstance() 方法來配置某個(gè)實(shí)例以滿足要求。(注意:使用沙箱部署時(shí),實(shí)例會(huì)自動(dòng)配置為滿足這些要求。)
- 用于組復(fù)制的數(shù)據(jù)以及用于 InnoDB 集群的數(shù)據(jù),必須存儲(chǔ)在 InnoDB 事務(wù)存儲(chǔ)引擎中。使用其他存儲(chǔ)引擎(包括臨時(shí)內(nèi)存存儲(chǔ)引擎)可能會(huì)導(dǎo)致組復(fù)制錯(cuò)誤。在使用組復(fù)制和 InnoDB 集群之前,需要將使用其他存儲(chǔ)引擎的所有表轉(zhuǎn)換為使用 InnoDB 引擎。你可以通過在MySQL服務(wù)器實(shí)例上設(shè)置 disabled_storage_engines 系統(tǒng)變量來防止使用其他存儲(chǔ)引擎,例如:disabled_storage_engines=“MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY”
- 在安裝配置集群時(shí),任何MySQL服務(wù)器實(shí)例都不能有入站復(fù)制通道(到達(dá)型)。在一個(gè)復(fù)制組上,由Group Replication(組復(fù)制)自動(dòng)創(chuàng)建的通道才允許被采用(group_replication_applier 和 group_replication_recovery)。InnoDB 集群不支持手工配置的異步復(fù)制通道,使用 AdminAPI 管理的除外。如果要將現(xiàn)有復(fù)制拓?fù)溥w移到一個(gè)InnoDB集群部署,并且需要在安裝過程中暫時(shí)跳過此驗(yàn)證,則可以在創(chuàng)建集群時(shí)使用force選項(xiàng)繞過它。
- 必須在要與 InnoDB Cluster 一起使用的所有實(shí)例上啟用Performance Schema。
- MySQL Shell 用于配置 InnoDB 集群中的服務(wù)器時(shí)使用到的配置腳本需要訪問Python。Windows版本的 MySQL Shell 中已經(jīng)包含了 Python,不需要用戶再做配置。在類 Unix 系統(tǒng)上,Python 必須配置為 shell 環(huán)境的一部份。要檢查你的 Unix 類系統(tǒng)是否正確配置了Python,請(qǐng)執(zhí)行以下操作:$ /usr/bin/env python ,如果Python解釋器啟動(dòng),則無需進(jìn)一步操作。如果前面的命令失敗,請(qǐng)?jiān)谀愕?Unix類系統(tǒng)上安裝正確版本的Python,并在 /usr/bin/python 和你安裝的 Python 二進(jìn)制可執(zhí)行文件之間創(chuàng)建一個(gè)軟鏈接。
- 從8.0.17版開始,MySQL實(shí)例必須在 InnoDB 集群中使用唯一的 server_id 。當(dāng)你使用 Cluster.addInstance(instance) 操作時(shí),如果 instance 的 server_id 已經(jīng)被集群中的其他實(shí)例使用,那么該操作將失敗并報(bào)錯(cuò)。
- 從8.0.23版開始,應(yīng)將MySQL實(shí)例配置為使用并行復(fù)制申請(qǐng)者(applier)。
- 在配置 InnoDB 集群的某個(gè)MySQL實(shí)例過程中,實(shí)例要使用的絕大部分系統(tǒng)變量都已經(jīng)被配置好了。但是 AdminAPI 不會(huì)進(jìn)行 transaction_isolation 系統(tǒng)變量的配置,這意味著它將保持默認(rèn)值 REPEATABLE READ 。這不會(huì)影響單主模式(single-primary)集群,但是如果你使用的是多主模式(multi-primary)集群,那么除非你的應(yīng)用程序確實(shí)依賴默認(rèn)值 REPEATABLE READ ,否則我們強(qiáng)列建議將值設(shè)置為 READ COMMITTED 隔離級(jí)別。
- 實(shí)例的相關(guān)配置項(xiàng),尤其是組復(fù)制配置項(xiàng),必須位于單個(gè) option 文件中。InnoDB Cluster只支持服務(wù)器實(shí)例的單個(gè) option 文件,不支持使用–defaults-extra-file 選項(xiàng)指定附加的 option 文件。對(duì)于任何使用實(shí)例 option 文件的 AdminAPI 操作,必須指定主文件。 如果你想為與 InnoDB Cluster 無關(guān)的配置項(xiàng)使用多 option 文件,你必須手動(dòng)配置這些文件,并考慮多 option 文件的使用優(yōu)先規(guī)則,確保它們被正確更新,并確保與 InnoDB Cluster 相關(guān)的設(shè)置沒有錯(cuò)誤地被一個(gè)未被認(rèn)可的額外 option 文件中的選項(xiàng)覆蓋。
2.2 InnoDB集群限制
由于InnoDB Cluster使用了Group Replication(組復(fù)制),所以除了下面列的限制外,還要考慮組復(fù)制的限制:
- InnoDB 集群不管理手動(dòng)配置的異步復(fù)制通道。Group Replication(組復(fù)制)和 AdminAPI 不確保異步復(fù)制僅在主服務(wù)器上處于活動(dòng)狀態(tài),并且不跨實(shí)例復(fù)制狀態(tài)。這可能會(huì)導(dǎo)致復(fù)制不再工作的各種情況,并且可能導(dǎo)致集群出現(xiàn)腦裂。只有從 MySQL 8.0.27 版本開始可用的 InnoDB ClusterSet 才支持在一個(gè) InnoDB 集群與另一個(gè)集群之間的復(fù)制,它管理著從一個(gè)活動(dòng)的主讀寫 InnoDB 集群到多個(gè)只讀副本集群的復(fù)制工作。
- InnoDB Cluster 被設(shè)計(jì)為在局域網(wǎng)中部署。在廣域網(wǎng)上部署單個(gè) InnoDB 集群對(duì)寫性能有顯著影響。穩(wěn)定且低延遲的網(wǎng)絡(luò)對(duì)于InnoDB 集群成員服務(wù)器使用底層 Group Replication(組復(fù)制)技術(shù)相互通信以達(dá)成事務(wù)共識(shí)非常重要。然而,InnoDB ClusterSet 是被設(shè)計(jì)為跨多個(gè)數(shù)據(jù)中心部署的,每個(gè) InnoDB 集群部署在單個(gè)數(shù)據(jù)中心中,通過異步復(fù)制通道將它們連接起來。
- 對(duì)于 AdminAPI 操作,你只能使用 TCP/IP 連接和經(jīng)典的 MySQL 協(xié)議連接到InnoDB集群中的服務(wù)器實(shí)例。AdminAPI操作不支持使用 Unix sockets 和 named pipes(命名管道),AdminAPI 操作也不支持使用 X 協(xié)議。同樣的限制也適用于MySQL 服務(wù)器實(shí)例本身之間的連接。(注意:客戶端應(yīng)用程序可以使用 X 協(xié)議、Unix sockets 和 named pipes(命名管道)連接到InnoDB集群中的實(shí)例,這些限制僅適用于使用 AdminAPI 命令的管理操作,以及集群內(nèi)實(shí)例之間的連接)
- AdminAPI 和 InnoDB Cluster支持 MySQL Server 5.7 版本的實(shí)例。但是對(duì)這些實(shí)例會(huì)有一些限制,并且有一些功能在這版本上不支持。
- 使用多主模式時(shí),不支持針對(duì)同一對(duì)象但在不同服務(wù)器上發(fā)出的并發(fā)DDL語句和DML語句。在某個(gè)對(duì)象上發(fā)出數(shù)據(jù)定義語句(DDL)期間,在同一對(duì)象上但從不同服務(wù)器實(shí)例發(fā)出并發(fā)數(shù)據(jù)操作語句(DML),可能會(huì)導(dǎo)致在不同實(shí)例上執(zhí)行的DDL沖突風(fēng)險(xiǎn)而未被檢測(cè)到。(參考組復(fù)制的限制)
2.3 InnoDB集群的用戶賬戶
InnoDB集群中的成員服務(wù)器使用三種類型的用戶帳戶。一個(gè) InnoDB 集群服務(wù)器配置帳戶用于為集群配置服務(wù)器實(shí)例。可以為管理員創(chuàng)建一個(gè)或多個(gè) InnoDB 集群管理員帳戶,以便在集群安裝后管理服務(wù)器實(shí)例。可以為 MySQL Router 實(shí)例創(chuàng)建一個(gè)或多個(gè) MySQL Router 帳戶,用于連接到集群。這些用戶帳戶必須存在 InnoDB 集群中的所有成員服務(wù)器上都存在,并且使用相同的用戶名和密碼。
2.3.1 InnoDB 集群服務(wù)器配置帳戶
此帳戶用于創(chuàng)建和配置 InnoDB 集群的成員服務(wù)器。每個(gè)成員服務(wù)器只有一個(gè)服務(wù)器配置帳戶。集群中的每個(gè)成員服務(wù)器必須使用相同的用戶帳戶名和密碼。為此,你可以在服務(wù)器上使用 root 帳戶,但如果這樣做,集群中每個(gè)成員服務(wù)器上的 root 帳戶必須具有相同的密碼。出于安全原因,不建議這樣做。
首選方法是使用 clusterAdmin 選項(xiàng)中的 dba.configureInstance()命令創(chuàng)建一個(gè) InnoDB集群服務(wù)器配置賬號(hào)。為提高安全性,請(qǐng)?jiān)诮换ヌ崾鞠轮付艽a,也可以使用 clusterAdminPassword 選項(xiàng)指定密碼。在將成為 InnoDB 集群一部分的每個(gè)服務(wù)器實(shí)例上以相同的方式創(chuàng)建相同的帳戶,使用相同的用戶名和密碼——包括你連接以創(chuàng)建集群的實(shí)例,以及之后將加入集群的實(shí)例。
dba.configureInstance()命令會(huì)自動(dòng)授予帳戶所需的權(quán)限(你也可以手動(dòng)設(shè)置該帳戶并授權(quán),但不建議這么做)。除了完整的 MySQL 管理員權(quán)限外,該帳戶還需要對(duì) InnoDB 集群元數(shù)據(jù)表擁有完整的讀寫權(quán)限。
使用 dba.configureInstance()命令創(chuàng)建一個(gè) InnoDB集群服務(wù)器配置賬號(hào)不會(huì)復(fù)制到集群內(nèi)的其他服務(wù)器上。MySQL Shell 禁用了 dba.configureInstance()命令的二進(jìn)制日志記錄。這意味著你必須在每個(gè) MySQL 服務(wù)器實(shí)例上單獨(dú)創(chuàng)建該帳戶。
2.3.2 InnoDB 集群管理員帳戶
這些帳戶在你完成集群配置之后,可用于管理 InnoDB 集群。你可以設(shè)置多個(gè),每個(gè)帳戶必須存在于 InnoDB 集群中的每個(gè)成員服務(wù)器上,并具有相同的用戶名和密碼。
為了給 InnoDB ClusterSet 創(chuàng)建 InnoDB 集群管理員賬號(hào),你需要在將所有實(shí)例添加到集群后執(zhí)行 cluster.setupAdminAccount()命令。該命令將使用你給定的用戶名和密碼創(chuàng)建賬號(hào),并賦予必要的權(quán)限。使用cluster.setupAdminAccount()創(chuàng)建一個(gè)賬號(hào)的事務(wù)將被寫入到二進(jìn)制日志,并發(fā)送到集群內(nèi)所有其他服務(wù)器實(shí)例上,用于在這些服務(wù)器上創(chuàng)建相同的賬號(hào)。(備注:如果主InnoDB 集群是在MySQL Shell 8.0.20之前版本部署的,cluster.setupAdminAccount()命令可能與 update 選項(xiàng)一起使用,以更新 InnoDB集群服務(wù)器配置帳戶的權(quán)限,這是未寫入二進(jìn)制日志的命令的特殊用法)
2.3.3 MySQL Router 帳戶
這些賬號(hào)被 MySQL Router 用于連接到 InnoDB 集群中的MySQL服務(wù)器實(shí)例。你可以設(shè)置多個(gè)此類賬號(hào),每個(gè)帳戶必須存在于InnoDB 集群中的每個(gè)成員服務(wù)器上,并具有相同的用戶名和密碼。創(chuàng)建 MySQL Router 帳戶的過程與創(chuàng)建 InnoDB 群集管理員帳戶相同,但使用的是 cluster.setupRouterAccount() 命令。(也會(huì)寫binary log 進(jìn)行同步創(chuàng)建)
2.3.4 InnoDB集群創(chuàng)建的內(nèi)部用戶帳戶
作為使用組復(fù)制的一部分,InnoDB 集群會(huì)創(chuàng)建內(nèi)部恢復(fù)用戶,以實(shí)現(xiàn)群集中服務(wù)器之間的連接。這些用戶是集群的內(nèi)部用戶,生成的用戶名遵循 mysql_innodb_cluster_server_id@% 的命名方案,其中 server_id 對(duì)每個(gè)實(shí)例是唯一的。在 8.0.17 之前的版本中,生成用戶的用戶名遵循 mysql_innodb_cluster_r[10_numbers] 的命名方案。
這些內(nèi)部用戶使用的主機(jī)名設(shè)置為“%”。在 v8.0.17 之前,ipAllowlist 會(huì)通過在 ipAllowlist 中每個(gè)主機(jī)一個(gè)賬號(hào)來影響主機(jī)名行為。
每個(gè)內(nèi)部用戶都有一個(gè)隨機(jī)生成的密碼。從 8.0.18 版開始,AdminAPI 允許你更改內(nèi)部用戶生成的密碼。請(qǐng)參閱【重置恢復(fù)帳戶密碼】。隨機(jī)生成的用戶將獲得以下授權(quán):GRANT REPLICATION SLAVE ON . to internal_user;
內(nèi)部用戶帳戶在 seed 實(shí)例上創(chuàng)建,然后復(fù)制到集群中的其他實(shí)例。內(nèi)部用戶包括:
- 通過執(zhí)行 dba.createCluster()命令創(chuàng)建一個(gè)新集群時(shí)生成的
- 通過執(zhí)行 Cluster.addInstance()命令向集群添加一個(gè)新實(shí)例時(shí)生成的
- 使用主要成員正在使用的身份驗(yàn)證插件時(shí)生成的
在 v8.0.17 之前,ipAllowlist 會(huì)導(dǎo)致 Cluster.rejoinInstance()命令移除老的內(nèi)部用戶并生成新的用戶,而不是重用它們。
2.3.5 重置恢復(fù)帳戶密碼
從8.0.18版開始,你可以使用 Cluster.resetRecoveryAccountsPassword()命令重置InnoDB群集創(chuàng)建的內(nèi)部恢復(fù)帳戶的密碼,例如為了遵循自定義密碼生存期策略。使用 Cluster.resetRecoveryAccountsPassword()命令重置群集使用的所有內(nèi)部恢復(fù)帳戶的密碼。該命令為每個(gè)聯(lián)機(jī)實(shí)例的內(nèi)部恢復(fù)帳戶設(shè)置一個(gè)新的隨機(jī)密碼,如果無法訪問實(shí)例,則操作失敗。你可以使用 force 選項(xiàng)忽略此類脫機(jī)的實(shí)例,但不建議這樣做,在使用此命令之前將實(shí)例重新聯(lián)機(jī)更安全。此命令僅適用于InnoDB Cluster創(chuàng)建的密碼,不能用于更新手動(dòng)創(chuàng)建的密碼。
備注:執(zhí)行此操作的用戶必須具有所有必需的管理權(quán)限,尤其是創(chuàng)建用戶權(quán)限CREATE USER,以確保無論所需的密碼驗(yàn)證策略如何,都可以更改恢復(fù)帳戶的密碼。換句話說,這與系統(tǒng)變量 password_require_current 是否啟用無關(guān)。
三、生產(chǎn)環(huán)境部署
在生產(chǎn)環(huán)境中,組成 InnoDB 集群的MySQL服務(wù)器實(shí)例運(yùn)行在以網(wǎng)絡(luò)鏈接的多個(gè)主機(jī)上,而不是一臺(tái)機(jī)器上。在組建 InnoDB 集群之前,我們必須將所需的軟件安裝到要作為集群服務(wù)器實(shí)例的每臺(tái)機(jī)器上。
下圖說明了將組建的 InnoDB 集群的邏輯架構(gòu)(IP只是做示例作用):
注意:對(duì)于生產(chǎn)部署,必須持久化實(shí)例上的任何配置變更,如何做到這一點(diǎn)取決于實(shí)例上運(yùn)行的MySQL版本。
為了將服務(wù)器的連接信息傳遞給 AdminAPI,可以使用類似 URI 的連接字符串或數(shù)據(jù)字典,本例中我們將使用類似 URI 的連接字符串。
3.1 環(huán)境規(guī)劃
| 192.168.10.51 | node1 | MGR/mysqlshell | CentOS 7.9 | mysql 8.0.31 |
| 192.168.10.52 | node2 | MGR/mysqlshell | CentOS 7.9 | mysql 8.0.31 |
| 192.168.10.53 | node3 | MGR/mysqlshell | CentOS 7.9 | mysql 8.0.31 |
| 192.168.10.54 | node0 | mysqlrouter/mysqlshell | CentOS 7.9 | mysql 8.0.31 |
3.1.1基礎(chǔ)環(huán)境準(zhǔn)備
- 關(guān)閉防火墻
- 永久關(guān)閉selinux
- 設(shè)置主機(jī)名
- 配置SSH互信
- yum配置
離線環(huán)境下,需要為每個(gè)節(jié)點(diǎn)配置本地yum源。
#將鏡像文件mount至/media [root@node1 ~]# mount -o loop -t iso9660 CentOS-7-x86_64-DVD-2009.iso /media [root@node1 ~]# cat /etc/yum.repos.d/local.repo [local] name=local baseurl=file:///media gpgcheck=0 enabled=1 gpgkey=file:///media/RPM-GPG-KEY-CentOS-7 #校驗(yàn)yum [root@node1 ~]# yum clean all3.2 安裝mysql
前往mysql官方下載地址:https://dev.mysql.com/downloads/。下載操作系統(tǒng)適配的MySQL Shell安裝包,MySQL Router安裝包以及MySQL Server。以下以8.0.31為例:
將以上文件上傳至各個(gè)服務(wù)器臨時(shí)安裝目錄,準(zhǔn)備進(jìn)行下一步安裝。
3.2.1 安裝3個(gè)數(shù)據(jù)庫實(shí)例
安裝并初始化3個(gè)數(shù)據(jù)庫實(shí)例,這里步驟省略,跟安裝部署MySQL步驟一樣,以node1為例進(jìn)行說明。
#清理操作系統(tǒng)自帶的 MySQL或者 Mariadb rpm -qa | grep mariadb | xargs rpm -e --nodeps rpm -qa | grep mysql | xargs rpm -e --nodeps#解壓mysql安裝壓縮包 tar -xvf mysql-8.0.31-1.el7.x86_64.rpm-bundle.tar #yum安裝mysql server相關(guān)的安裝包,可以自動(dòng)處理依賴關(guān)系 yum install -y mysql-community-* #改命令安裝mysql全部包 yum install -y mysql-community-{server,client,common,libs}-*#亦有此命令安裝mysql基礎(chǔ)包 #以上兩種安裝方式都可以,一個(gè)是安裝全部安裝包,一個(gè)是安裝基本安裝包。建議全部安裝。3.2.2 初始化3個(gè)數(shù)據(jù)庫實(shí)例
在第一次啟動(dòng)的/var/log/mysqld.log中找到初始密碼,并使用該密碼進(jìn)行登錄。而后分別在每個(gè)數(shù)據(jù)庫節(jié)點(diǎn)執(zhí)行以下操作。
#啟動(dòng)mysql [root@node1 ~]# systemctl start mysqld [root@node1 ~]# cat /var/log/mysqld.log | grep 'temporary password' 2022-11-13T09:54:43.615664Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: oVdjq0vrAd/C #登錄并修改root用戶初始密碼 [root@node1 ~]# mysql -u root -p mysql> alter user 'root'@'localhost' identified with mysql_native_password by 'Abcd@1234'; #修改root訪問權(quán)限 mysql> use mysql; mysql> update user set host='%' where user='root'; mysql> grant all on *.* to 'root'@'%' with grant option;3.2.3 在所有節(jié)點(diǎn)安裝MySQL Shell
yum install -y mysql-shell-8.0.31-1.el7.x86_64.rpm3.3 InnoDB Cluster 配置及初始化
因root用戶權(quán)限較大,不建議將其作為集群配置用戶。可以參考以下權(quán)限,新建用戶。
CREATE USER 'ic_admin'@'%' IDENTIFIED BY 'Abcd@1234'; GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,ALTER,DROP ON *.* TO 'ic_admin'@'%' WITH GRANT OPTION; GRANT CREATE USER, FILE, PROCESS, RELOAD, REPLICATION CLIENT, REPLICATION SLAVE, SHUTDOWN, SUPER ON *.* TO 'ic_admin'@'%' WITH GRANT OPTION; GRANT ALTER ROUTINE, CREATE ROUTINE, CREATE TEMPORARY TABLES, CREATE VIEW, EVENT, EXECUTE, INDEX, LOCK TABLES, REFERENCES, SHOW VIEW, TRIGGER ON mysql_innodb_cluster_metadata.* TO 'ic_admin'@'%' WITH GRANT OPTION; GRANT ALTER ROUTINE, CREATE ROUTINE, CREATE TEMPORARY TABLES, CREATE VIEW, EVENT, EXECUTE, INDEX, LOCK TABLES, REFERENCES, SHOW VIEW, TRIGGER ON mysql_innodb_cluster_metadata_bkp.* TO 'ic_admin'@'%' WITH GRANT OPTION; GRANT ALTER ROUTINE, CREATE ROUTINE, CREATE TEMPORARY TABLES, CREATE VIEW, EVENT, EXECUTE, INDEX, LOCK TABLES, REFERENCES, SHOW VIEW, TRIGGER ON mysql_innodb_cluster_metadata_previous.* TO 'ic_admin'@'%' WITH GRANT OPTION; GRANT CLONE_ADMIN, CONNECTION_ADMIN, EXECUTE, GROUP_REPLICATION_ADMIN, PERSIST_RO_VARIABLES_ADMIN, REPLICATION_APPLIER, REPLICATION_SLAVE_ADMIN, ROLE_ADMIN, SYSTEM_VARIABLES_ADMIN ON *.* TO 'ic_admin'@'%' WITH GRANT OPTION; flush privileges;在三個(gè)MySQL Server所在虛擬機(jī)上用mysqlsh命令打開MySQL Shell,并分執(zhí)行以下命令將其上的MySQL實(shí)例配置為用于InnoDB集群的實(shí)例(實(shí)際上這些命令會(huì)查找MySQL的配置文件my.cnf,將集群需要的配置寫入其中,當(dāng)然還有其他些方面的配置變更),同時(shí)指定 InnoDB 集群管理員賬號(hào)——icadmin,必須是相同的賬號(hào)名稱和密碼(注意:MySQL 5.7用的是configureLocalInstance(),不是configureInstance()):
3.3.1 節(jié)點(diǎn)配置檢查
- 檢查
執(zhí)行每個(gè)節(jié)點(diǎn)的參數(shù)及權(quán)限配置預(yù)需求檢測(cè)。
mysqlsh ic_admin@node1 MySQL node1:33060+ ssl JS > dba.checkInstanceConfiguration('ic_admin@node1') MySQL node1:33060+ ssl JS > dba.checkInstanceConfiguration('ic_admin@node2') MySQL node1:33060+ ssl JS > dba.checkInstanceConfiguration('ic_admin@node3')檢測(cè)通過會(huì)顯示如下:
檢測(cè)失敗會(huì)顯示如下:
- 配置
對(duì)每個(gè)節(jié)點(diǎn),通過dba.configureInstance()進(jìn)行集群相關(guān)信息配置。
MySQL node1:33060+ ssl JS > dba.configureInstance('ic_admin@node1') MySQL node1:33060+ ssl JS > dba.configureInstance('ic_admin@node2') MySQL node1:33060+ ssl JS > dba.configureInstance('ic_admin@node3')以下為對(duì)node1節(jié)點(diǎn)的配置,在交互式窗口中輸入’y’進(jìn)行確認(rèn)。執(zhí)行完成后,再次通過上面的檢測(cè)命令進(jìn)行每個(gè)節(jié)點(diǎn)檢測(cè),直到所有節(jié)點(diǎn)狀態(tài)都是ok為止。
MySQL node1:33060+ ssl JS > dba.configureInstance('ic_admin@node1') Configuring local MySQL instance listening at port 3306 for use in an InnoDB cluster...This instance reports its own address as node1:3306 Clients and other cluster members will communicate with it through this address by default. If this is not correct, the report_host MySQL system variable should be changed.applierWorkerThreads will be set to the default value of 4.NOTE: Some configuration options need to be fixed: +----------------------------------------+---------------+----------------+--------------------------------------------------+ | Variable | Current Value | Required Value | Note | +----------------------------------------+---------------+----------------+--------------------------------------------------+ | binlog_transaction_dependency_tracking | COMMIT_ORDER | WRITESET | Update the server variable | | enforce_gtid_consistency | OFF | ON | Update read-only variable and restart the server | | gtid_mode | OFF | ON | Update read-only variable and restart the server | | server_id | 1 | <unique ID> | Update read-only variable and restart the server | +----------------------------------------+---------------+----------------+--------------------------------------------------+Some variables need to be changed, but cannot be done dynamically on the server. Do you want to perform the required configuration changes? [y/n]: y Do you want to restart the instance after configuring it? [y/n]: y Configuring instance... The instance 'node1:3306' was configured to be used in an InnoDB cluster. Restarting MySQL... NOTE: MySQL server at node1:3306 was restarted.3.3.2 創(chuàng)建集群
- 創(chuàng)建集群
將node1規(guī)劃為創(chuàng)建集群的種子節(jié)點(diǎn),在node1上使用集群管理員賬號(hào)重新進(jìn)入MySQL Shell中,執(zhí)行以下命令創(chuàng)建一個(gè)名為 "myCluster"的集群:
[root@node1 software]# mysqlsh --uri ic_admin@node1 MySQL Shell 8.0.31Copyright (c) 2016, 2022, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.Type '\help' or '\?' for help; '\quit' to exit. Creating a session to 'ic_admin@node1' Fetching schema names for auto-completion... Press ^C to stop. Your MySQL connection id is 22 (X protocol) Server version: 8.0.31 MySQL Community Server - GPL No default schema selected; type \use <schema> to set one. #在創(chuàng)建集群添加Seed Instance的過程中可能會(huì)報(bào)錯(cuò),這個(gè)時(shí)候要 cat /var/log/mysqld.log 打開日志看看具體報(bào)錯(cuò),比如我的就是由于防火器阻止了端口33061上的連接所致:MySQL node1:33060+ ssl JS > var cluster=dba.createCluster('myCluster') A new InnoDB Cluster will be created on instance 'node1:3306'.Validating instance configuration at node1:3306...This instance reports its own address as node1:3306Instance configuration is suitable. NOTE: Group Replication will communicate with other members using 'node1:3306'. Use the localAddress option to override.Creating InnoDB Cluster 'myCluster' on 'node1:3306'...Adding Seed Instance... Cluster successfully created. Use Cluster.addInstance() to add MySQL instances. At least 3 instances are needed for the cluster to be able to withstand up to one server failure.- 添加節(jié)點(diǎn)
如果你前面使用 dba.createCluster(‘myCluster’);創(chuàng)建集群時(shí),沒用 var cluster來承接,或者你創(chuàng)建完集群后重新進(jìn)入MySQL Shell的,那么你可以通過下面命令來獲取的目標(biāo)集群對(duì)象(舊時(shí)代叫【句柄】):
MySQL node1:33060+ ssl JS > var cluster=dba.getCluster('myCluster') #添加節(jié)點(diǎn)MySQL node1:33060+ ssl JS > cluster.addInstance('ic_admin@node2')MySQL node1:33060+ ssl JS > cluster.addInstance('ic_admin@node3')添加節(jié)點(diǎn)顯示如下:
3.3.3 查看集群
#查看集群狀態(tài)MySQL node1:33060+ ssl JS > cluster.status()至此,集群配置完成。查看集群狀態(tài),正常顯示如下,所有節(jié)點(diǎn)ONLINE。
3.4 安裝mysql router
3.4.1 mysql router簡(jiǎn)介
從前面出現(xiàn)過的這兩張集群邏輯架構(gòu)圖中我們可以清楚的看到:在一個(gè)MySQL InnoDB集群中,MySQL Router 是獨(dú)立出來放在集群外面的,這也是由它在整個(gè)集群中所充當(dāng)?shù)慕巧鶝Q定的。
MySQL Router作為整個(gè)InnoDB集群的流量入口(門神),肩負(fù)著流量承接、負(fù)載均衡、成員管理以及故障轉(zhuǎn)移的重任(就像前置Nginx服務(wù)器一樣),非常有必要使用一臺(tái)高性能的獨(dú)立服務(wù)器進(jìn)行部署,還要配以足夠的帶寬(事實(shí)上,如果僅有一臺(tái)集中式MySQL Router服務(wù)器的話,它將成為整個(gè)集群性能和可用性的瓶頸,而解決這個(gè)問題方法是接下來要講的內(nèi)容)。另外, MySQL Shell 作為InnoDB集群的管理入口,其實(shí)也可以放在整個(gè)集群之上安裝,但在用MySQL Shell的指令dba.configureInstance(“configer@linux01:3306”);將MySQL Server實(shí)例配置為用于InnoDB集群的實(shí)例時(shí),會(huì)在命令執(zhí)行的本機(jī)查找MySQL Server的配置文件my.cnf,找不到將會(huì)報(bào)錯(cuò),所以上面三臺(tái)MySQL Server實(shí)例所在主機(jī)上也安裝上MySQL Shell。
實(shí)際生產(chǎn)中,為了獲得最佳性能,MySQL Router通常會(huì)與它服務(wù)的客戶端應(yīng)用程序安裝在同一臺(tái)主機(jī)上,主要原因有:
- 這將允許客戶端應(yīng)用程序使用本地UNIX域socket來與MySQL Router建立鏈接,而不需要走TCP/IP;(注意:本地UNIX域socket只能在應(yīng)用程序和MySQL Router之間發(fā)揮作用,在MySQL Router和MySQL Server之間不行)
- 這將減少網(wǎng)絡(luò)延遲;
- 這將允許MySQL Router直接使用分配給客戶端應(yīng)用程序的MySQL賬號(hào)(例如myapp@192.168.0.254)來連接MySQL,而不需要單獨(dú)為MySQL Router的宿主機(jī)再分配一個(gè)額外的MySQL賬號(hào)(例如放大可登錄范圍的賬號(hào)myapp@%);
- 這將允許MySQL Router跟隨應(yīng)用程序服務(wù)器一起橫向擴(kuò)展,形成一對(duì)一的服務(wù),消除集中式MySQL Router性能和可用性問題;
當(dāng)然,你也可以在網(wǎng)絡(luò)上運(yùn)行多個(gè)MySQL Router實(shí)例,并且不需要將MySQL Router 獨(dú)立部署到一臺(tái)機(jī)器上。這是因?yàn)镸ySQL Router不會(huì)依賴于何特定的服務(wù)器或主機(jī)!
下面是官方給出的MySQL Router的系統(tǒng)要求:
- 硬件:至少需要1核CPU和256MB的內(nèi)存,建議使用4核CPU和4GB以上的內(nèi)存;
- 磁盤空間:最少需要100MB的空間;
- 外部庫依賴:大部分外部依賴都已經(jīng)打包在了MySQL Router包中(例如protobuf和rapidjson),有一個(gè)例外,那就是OpenSSL,它僅在Windows版本的MySQL Router包中有捆綁。類Linux系統(tǒng)的包管理器會(huì)自動(dòng)解決OpenSSL依賴,并根據(jù)需要安裝正確的OpenSSL版本。
3.4.2 安裝mysql router
在node4安裝mysql router
yum install -y mysql-router-community-8.0.31-1.el7.x86_64.rpm3.4.3 配置mysql router
- 配置MySQL Router,實(shí)現(xiàn)InnoDB集群讀寫分離和故障自動(dòng)轉(zhuǎn)移:
MySQL Router通過使用–bootstrap和其他命令行選項(xiàng)為現(xiàn)有的InnoDB集群自動(dòng)配置MySQL Router。在引導(dǎo)過程中,MySQL Route連接到目標(biāo)集群,獲取其元數(shù)據(jù)來實(shí)現(xiàn)自我配置(如果對(duì)應(yīng)的InnoDB集群重新創(chuàng)建了,使用它的MySQL Router需要?jiǎng)h除舊引導(dǎo)生成的配置文件(/etc/mysqlrouter/mysqlrouter.conf),并重新初始化引導(dǎo))。
mysqlrouter --bootstrap ic_admin@node1:3306 --user root # ic_admin 是InnoDB集群管理員賬號(hào),node1:3306是集群主節(jié)點(diǎn)或成員節(jié)點(diǎn),如果給的是成員節(jié)點(diǎn)引導(dǎo)模塊會(huì)自動(dòng)轉(zhuǎn)發(fā)到主節(jié)點(diǎn)(PRIMARY); # --user root指定的是操作系統(tǒng)賬號(hào),不MySQL Router用于連接到 InnoDB 集群的賬號(hào),該賬號(hào)你可以重新建一個(gè)專用的,也可以直接用了root賬號(hào);可以看到配置完成后顯示:MySQL經(jīng)典協(xié)議讀寫操作走的是6446端口,而只讀協(xié)議走的是6647端口,有興趣的話你可以進(jìn)一步查看一下生成的MySQL Router配置文件 /etc/mysqlrouter/mysqlrouter.conf。后面啟動(dòng)MySQL Router時(shí),如不做特殊指定的話將使用這個(gè)生成的默認(rèn)配置文件!
如果開啟了防火墻,要第一時(shí)間記得對(duì)它們進(jìn)行防火墻例外設(shè)置,并重新載入防火墻。
- 為集群配置 MySQL Router 帳戶:
在安裝有MySQL Shell的主機(jī)上連接上集群,使用MySQL Shell AdminAPI為集群添加MySQL Router專用賬號(hào)(可以多個(gè),但實(shí)際上可以不添加MySQL Router賬號(hào),直接使用分配給應(yīng)用程序的MySQL賬號(hào)即可,否則你還得為這個(gè)新添加的專用賬號(hào)到MySQL服務(wù)器上做授權(quán)操作,默認(rèn)權(quán)限很少)。
[root@node4 software]# mysqlsh --uri ic_admin@node1MySQL node1:33060+ ssl JS > var cluster =dba.getCluster('myCluster')MySQL node1:33060+ ssl JS > cluster.setupRouterAccount('myrouter') #以上命令為集群創(chuàng)建了一個(gè)可以在任意位置向集群發(fā)起連接的MySQL Router賬號(hào)——myrouter@%。如果要限制在某個(gè)IP或域名下才能發(fā)起連接,可以這樣做:MySQL node1:33060+ ssl JS > cluster.setupRouterAccount('myrouter@192.168.10.%')輸入密碼和再次確認(rèn)密碼后,賬戶創(chuàng)建成功,顯示如下:
注意:該命令創(chuàng)建的myrouter用戶只有基礎(chǔ)權(quán)限,在實(shí)際應(yīng)用中,應(yīng)當(dāng)秉承最小權(quán)限原則,在主節(jié)點(diǎn)對(duì)myrouter用戶進(jìn)行正確的授權(quán)。
3.4.4 啟動(dòng)mysql router
mysqlrouter -c /etc/mysqlrouter/mysqlrouter.conf &3.4.5 驗(yàn)證
在只裝有mysql client的服務(wù)器或者其他客戶端上面進(jìn)行登錄、數(shù)據(jù)操作等驗(yàn)證。以windows端navicat客戶端為例進(jìn)行驗(yàn)證。
以上配置中,主機(jī)地址為mysql routher服務(wù)器的ip地址,端口為讀寫端口,用戶名和密碼為3.4.3中配置的MySQL Router 帳戶。同樣的方式進(jìn)行只讀端口驗(yàn)證。
應(yīng)用程序通過MySQL Router連接上MySQL InnoDB集群里MySQL Server實(shí)例的過程:
- MySQL客戶端或Connector連接器連接到MySQL Router的指定端口,例如這里的6446或6447;
- MySQL Router檢查可用的MySQL Server實(shí)例;
- MySQL Router向合適的MySQL Server實(shí)例建立連接并打開(根據(jù)端口類型:讀寫(RW)端口發(fā)給主節(jié)點(diǎn),只讀(RO)端口會(huì)進(jìn)行負(fù)載均衡選取從節(jié)點(diǎn));
- MySQL Router在應(yīng)用程序和MySQL服務(wù)器之間來回轉(zhuǎn)發(fā)數(shù)據(jù)包。
- 如果連接的MySQL服務(wù)器出現(xiàn)故障,MySQL Router將斷開應(yīng)用程序的連接。然后,應(yīng)用程序可以重試連接到MySQL Router,MySQL Router會(huì)選擇另一個(gè)可用的MySQL服務(wù)器建立連接。
3.5 驗(yàn)證
3.5.1 讀寫分離
通過Mysql命令show variables like ‘server_id’; 先查看一下InnoDB集群中三臺(tái)MySQL Server實(shí)例的server_id是多少,并將它們記下來:
node1:2861026507
node2:770008088
node3:1770854672
可以看到,讀寫請(qǐng)求被分發(fā)到node1,只讀請(qǐng)求分別被分發(fā)到node2和node3:
3.5.2 故障轉(zhuǎn)移
在上一步的基礎(chǔ)上,保持上一步的各個(gè)會(huì)話連接不要斷開,直接停掉當(dāng)前的主節(jié)點(diǎn)(node1上的MySQL Server實(shí)例),我們看看會(huì)發(fā)生什么:
登錄node2節(jié)點(diǎn),查看集群狀態(tài):
我們看到故障轉(zhuǎn)移在上一步實(shí)驗(yàn)的客戶端會(huì)話連接未關(guān)閉的情況下就自動(dòng)發(fā)生了,但卻有一個(gè)只讀(RO)端口的連接連在了當(dāng)前的新主節(jié)點(diǎn)上!這是為什么呢?不是說只讀(RO)端口建立連接時(shí)只會(huì)選擇從節(jié)點(diǎn)嗎?其實(shí)原因是:我們是在沒有關(guān)閉上一步的會(huì)話連接的情況下做的本次實(shí)驗(yàn),這次關(guān)掉舊主節(jié)點(diǎn)時(shí),其它節(jié)點(diǎn)上原先保持住的會(huì)話連接并不會(huì)重新建立,只有原來建立在舊的主節(jié)點(diǎn)上的連接會(huì)重新進(jìn)行連接!當(dāng)然后續(xù)新發(fā)起的連接還是會(huì)根據(jù)端口類型:讀寫(RW)端口發(fā)給主節(jié)點(diǎn),只讀(RO)端口會(huì)進(jìn)行負(fù)載均衡選取從節(jié)點(diǎn)!
四、集群相關(guān)操作
4.1 查看集群狀態(tài)
cluster.status()
MySQL node1:33060+ ssl JS > var cluster=dba.getCluster('myCluster')MySQL node1:33060+ ssl JS > cluster.status() {"clusterName": "myCluster", "defaultReplicaSet": {"name": "default", "primary": "node1:3306", "ssl": "REQUIRED", "status": "OK", "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.", "topology": {"node1:3306": {"address": "node1:3306", "memberRole": "PRIMARY", "mode": "R/W", "readReplicas": {}, "replicationLag": "applier_queue_applied", "role": "HA", "status": "ONLINE", "version": "8.0.31"}, "node2:3306": {"address": "node2:3306", "memberRole": "SECONDARY", "mode": "R/O", "readReplicas": {}, "replicationLag": "applier_queue_applied", "role": "HA", "status": "ONLINE", "version": "8.0.31"}, "node3:3306": {"address": "node3:3306", "memberRole": "SECONDARY", "mode": "R/O", "readReplicas": {}, "replicationLag": "applier_queue_applied", "role": "HA", "status": "ONLINE", "version": "8.0.31"}}, "topologyMode": "Single-Primary"}, "groupInformationSourceMember": "node1:3306" }MySQL node1:33060+ ssl JS >4.2 配置節(jié)點(diǎn)權(quán)重
memberWeight選項(xiàng)的值域?yàn)?到100之間的整數(shù),缺省值為50。該值是故障轉(zhuǎn)移時(shí)自動(dòng)選舉主節(jié)點(diǎn)的百分比權(quán)重,具有較高memberWeight值的實(shí)例更有可能在單主群集中被選為主節(jié)點(diǎn)
// 在集群創(chuàng)建完成后修改權(quán)重 var cluster = dba.getCluster() cluster.setInstanceOption('node1:3306','memberWeight',100) cluster.setInstanceOption('node2:3306','memberWeight',50) cluster.setInstanceOption('node3:3306','memberWeight',25)// 查看集群的參數(shù)配置(包括memberWeight優(yōu)先級(jí)配置) cluster.options()// 在集群創(chuàng)建時(shí)配置 dba.createCluster('myCluster', {memberWeight:75}) // 第一個(gè)節(jié)點(diǎn)配置方式 var cluster = dba.getCluster() cluster.addInstance('node2:3306',{memberWeight:50}) cluster.addInstance('node3:3306',{memberWeight:25})4.3 將節(jié)點(diǎn)重新加入集群
狀態(tài)為mssing的節(jié)點(diǎn),通常是組復(fù)制關(guān)閉或中斷狀態(tài),可以用cluster.rejoinInstance()重新加入集群,會(huì)重新對(duì)該節(jié)點(diǎn)設(shè)置MGR相關(guān)參數(shù)(持久化到mysqld-auto.conf中)
4.3.1 rejoinInstance
{"node1:3306": {"address": "node1:3306", "memberRole": "PRIMARY", "mode": "R/W", "readReplicas": {}, "replicationLag": "applier_queue_applied", "role": "HA", "status": "ONLINE", "version": "8.0.31"}, "node2:3306": {"address": "node2:3306", "memberRole": "SECONDARY", "mode": "R/O", "readReplicas": {}, "replicationLag": "applier_queue_applied", "role": "HA", "status": "(MISSING)", "version": "8.0.31"}, "node3:3306": {"address": "node3:3306", "memberRole": "SECONDARY", "mode": "R/O", "readReplicas": {}, "replicationLag": "applier_queue_applied", "role": "HA", "status": "ONLINE", "version": "8.0.31"} }// 重新加入集群 cluster.rejoinInstance("ic_admin@node2:3306")4.3.2 removeInstance && addInstance
如果一些參數(shù)做了修改,如server_uuid變更,導(dǎo)致rejoin失敗,則需要將節(jié)點(diǎn)從集群中刪除后重新加入
cluster.removeInstance("root@node2:3306",{force:true}) cluster.rescan() cluster.addInstance("root@node2:3306")4.4 集群多數(shù)節(jié)點(diǎn)異常恢復(fù)
當(dāng)集群多個(gè)節(jié)點(diǎn)異常,則失去了仲裁機(jī)制,剩下的一個(gè)節(jié)點(diǎn)
// 將集群剝離為單節(jié)點(diǎn)運(yùn)行 JS > cluster.forceQuorumUsingPartitionOf("ic_admin@node3:3306")// 重新加另外2個(gè)節(jié)點(diǎn)加入 JS > cluster.rejoinInstance("ic_admin@node1:3306") JS > cluster.rejoinInstance("ic_admin@node2:3306")4.5 完整關(guān)閉的集群如何恢復(fù)
每個(gè)節(jié)點(diǎn)都是正常的停止且正常的觸發(fā)stop group_replication停止的,當(dāng)重新啟動(dòng)時(shí)如果手工我們需要做以下操作才可拉起集群
-
判斷哪個(gè)節(jié)點(diǎn)的GTID最新
-
將最新的GTID節(jié)點(diǎn)group_replication_bootstrap_group設(shè)置為on表示以這個(gè)節(jié)點(diǎn)為基礎(chǔ)啟動(dòng)組復(fù)制
-
再將其他節(jié)點(diǎn)的組復(fù)制啟動(dòng),集群恢復(fù)
我們也可以用mysqlsh的功能來讓其自行判斷最新數(shù)據(jù)的節(jié)點(diǎn),再采用dba.rebootClusterFromCompleteOutage()方式啟動(dòng)集群
// 通過node1節(jié)點(diǎn)觸發(fā)命令 MySQL node1:3306 ssl JS > dba.rebootClusterFromCompleteOutage() Restoring the default cluster from complete outage...// 檢測(cè)到node2服務(wù)器也包含在集群中,確認(rèn)添加 The instance 'node2:3306' was part of the cluster configuration. Would you like to rejoin it to the cluster? [y/N]: y// 檢測(cè)到node3服務(wù)器也包含在集群中,確認(rèn)添加 The instance 'node3:3306' was part of the cluster configuration. Would you like to rejoin it to the cluster? [y/N]: y// 檢測(cè)到node1不是最新的節(jié)點(diǎn),node2才是 Dba.rebootClusterFromCompleteOutage: The active session instance (node1:3306) isn't the most updated in comparison with the ONLINE instances of the Cluster's metadata. Please use the most up to date instance: 'node2:3306'. (RuntimeError)// 重新連接到node2上執(zhí)行相同操作 MySQL node1:3306 ssl JS > \connect "ic_admin@node2:3306" MySQL node1:3306 ssl JS > dba.rebootClusterFromCompleteOutage()// 完成后查看集群狀態(tài)是否正常 var cluster = dba.getCluster() cluster.status()4.6 集群節(jié)點(diǎn)角色切換
在MGR的管理下提供了一下3中方式進(jìn)行角色切換,mysqlsh對(duì)其進(jìn)行了封裝調(diào)用
- group_replication_set_as_primary(member_uuid);
- cluster.setPrimaryInstance("IP:PORT")
- group_replication_switch_to_single_primary_mode()
- cluster.switchToSinglePrimaryMode("IP:PORT")
- group_replication_switch_to_multi_primary_mode()
- cluster.switchToMultiPrimaryMode()
4.6.1 單主模式-指定主節(jié)點(diǎn)切換
var cluster = dba.getCluster() cluster.setPrimaryInstance('node2:3306') cluster.status()切換結(jié)果如下:
4.6.2 單主模式和多主模式相互切換
// 切換為多主模式 var cluster = dba.getCluster() cluster.switchToMultiPrimaryMode()// 指定明確的主節(jié)點(diǎn)將多主模式切換為單主模式 cluster.switchToSinglePrimaryMode("node1:3306")4.7 參數(shù)配置
可以用cluster.options()查看當(dāng)前集群的配置屬性,集群參數(shù)配置分為兩種方式:
- cluster.setOption() 用來設(shè)置所有節(jié)點(diǎn)的參數(shù)
- cluster.setInstanceOption() 用來對(duì)指定節(jié)點(diǎn)配置屬性
4.8 銷毀集群
刪除與群集關(guān)聯(lián)的所有元數(shù)據(jù)和配置,并禁用實(shí)例上的組復(fù)制,但不會(huì)刪除在實(shí)例之間復(fù)制的任何數(shù)據(jù)。要再次創(chuàng)建集群,使用,dba.createCluster()
var cluster = dba.getCluster() cluster.dissolve()4.9 常見錯(cuò)誤
4.9.1 getCluster() 報(bào)錯(cuò)
// 獲取集群報(bào)錯(cuò),集群中的該節(jié)點(diǎn)MGR功能未啟動(dòng)MySQL 10.186.63.65:3310 ssl JS > var cluster = dba.getCluster() Dba.getCluster: This function is not available through a session to a standalone instance (metadata exists, instance belongs to that metadata, but GR is not active) (RuntimeError)// 可以切換到sql模式查看集群當(dāng)前狀態(tài) // 可以看到當(dāng)前集群只有一個(gè)節(jié)點(diǎn)且處于OFFLINE狀態(tài)MySQL 10.186.63.65:3310 ssl SQL > \sql select * from performance_schema.replication_group_members\G *************************** 1. row ***************************CHANNEL_NAME: group_replication_applierMEMBER_ID: 67c08e33-92c4-11eb-803d-02000aba3f41MEMBER_HOST: 10.186.63.65MEMBER_PORT: 3310MEMBER_STATE: OFFLINEMEMBER_ROLE: MEMBER_VERSION: 1 row in set (0.0038 sec)-- 可以將該節(jié)點(diǎn)作為引導(dǎo)節(jié)點(diǎn)啟動(dòng)集群 set global group_replication_bootstrap_group=on; start group_replication;-- 啟動(dòng)完畢后需關(guān)閉該參數(shù) set global group_replication_bootstrap_group=off;-- 再次查看可看到第一個(gè)節(jié)點(diǎn)恢復(fù)正常MySQL 10.186.63.65:3310 ssl SQL > select * from performance_schema.replication_group_members\G *************************** 1. row ***************************CHANNEL_NAME: group_replication_applierMEMBER_ID: 67c08e33-92c4-11eb-803d-02000aba3f41MEMBER_HOST: 10.186.63.65MEMBER_PORT: 3310MEMBER_STATE: ONLINEMEMBER_ROLE: PRIMARY MEMBER_VERSION: 8.0.22 1 row in set (0.0016 sec)4.9.2 addInstance 報(bào)錯(cuò) Unknown MySQL server host
報(bào)這個(gè)錯(cuò)誤需要配置/etc/hosts將主機(jī)名和IP對(duì)應(yīng)關(guān)系配置上
Cluster.addInstance: Unknown MySQL server host '10-186-63-65' (2) (MySQL Error 2005)// cluster.status() 命令也會(huì)有如下顯示 "shellConnectError": "MySQL Error 2005 (HY000): Unknown MySQL server host '10-186-63-65' (2)",4.9.3 清理殘留的mgr信息
dba.dropMetadataSchema()
Dba.checkInstanceConfiguration: Dba.checkInstanceConfiguration: This function is not available through a session to a standalone instance (metadata exists, instance belongs to that metadata, but GR is not active) (RuntimeError)4.9.4 克隆插件不能設(shè)置為force_plus_permanent
在多次對(duì)同一個(gè)實(shí)例做集群初始化時(shí),不管是全量還是增量都會(huì)對(duì)克隆插件做一次重新加載,會(huì)如果對(duì)克隆插件開啟了force_plus_permanent屬性,則無法卸載。
Cluster.addInstance: error uninstalling plugin 'clone': 10.186.63.67:3310: Plugin 'clone' is force_plus_permanent and can not be unloaded (RuntimeError)總結(jié)
以上是生活随笔為你收集整理的MySQL InnoDB Cluster部署方案与实践的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分布式异步任务框架之Celery定义、异
- 下一篇: Cluster 集群