1. 概述
MySQL Innodb ReplicaSet 是 MySQL 團隊在 2020 年推出的一款產品,用來幫助用戶快速部署和管理主從復制,在數據庫層仍然使用的是主從復制技術。
ReplicaSet 主要包含三個組件:MySQL Router、MySQL Server 以及 MySQL Shell 高級客戶端。
MySQL Shell 負責管理 ReplicaSet 包括部署、切換、節點加入等,都可以通過內置 AdminAPI 自動化完成。
MySQL Router 是一款輕量級中間件,可在應用程序和 ReplicaSet 之間提供透明路由和讀寫分離功能。
2. 適用場景
InnoDB ReplicaSet至少由兩臺MySQL服務器實例組成,提供MySQL主從復制功能。InnoDB ReplicaSet基于異步的主從復制實現,因此適用于用戶對高可用性要求不高的環境。可以通過MySQL Shell快速搭建及管理主從復制,避免了搭建主從復制時大量的手動操作。
InnoDB ReplicaSet的不足之處有:
-
不支持自動故障轉移。主庫不可用時,需要通過AdminAPI手動發起故障轉移。
-
發生計劃外的服務不可用時,可能會丟失部分數據。由于主備之間是異步復制,主庫發生故障時,未提交的事務會丟失。
-
發生計劃外的服務不可用時,可能會產生數據不一致。例如由于網絡原因導致主庫連不上,將備庫提升為主庫后,可能會同時存在兩個主庫,即發生“腦裂”。
-
不支持多主模式,即同一時刻只有一個主庫可寫。
-
讀擴展受限,不能像組復制那樣對流量進行控制。
-
所有的備庫都從同一個主庫復制數據。在有大量的小更新時,可能會對主庫造成影響。
-
僅支持MySQL 8.0及其以后的版本。
-
僅支持基于GTID的日志復制。
-
僅支持基于行的日志復制(Row-Based Replication, RBR),不支持基于SQL語句的復制(Statement-Based Replication, SBR)。
-
不支持復制過濾。
-
RS為一個主庫加多個從庫的架構。需要通過MySQL Router監視RS中的實例,因此從庫的數量不能無限制增加。
-
必須通過MySQL Shell配置和管理,包括復制用戶的創建。
3. 安裝部署
IP | role | hostname | 版本 | OS |
---|---|---|---|---|
192.168.10.31 | Master | mysql-rs-1 | MySQL 8.2 | Centos_7.9_x86_x64 |
192.168.10.32 | Secondary | mysql-rs-2 | MySQL 8.2 | Centos_7.9_x86_x64 |
3.1. 安裝MySQL servers
分別在兩個MySQL服務器下載MySQL Server安裝包,并進行安裝。
# 配置主機名
echo "192.168.10.31 ? mysql-rs-1" >> /etc/hosts
echo "192.168.10.32 ? mysql-rs-2" >> /etc/hosts
?
# 192.168.10.31執行
hostnamectl set-hostname mysql-rs-1
bash
# 192.168.10.32執行
hostnamectl set-hostname mysql-rs-2
bash
# 下載rpm安裝包
wget https://cdn.mysql.com//Downloads/MySQL-8.2/mysql-8.2.0-1.el7.x86_64.rpm-bundle.tar
?
# 解壓
tar -xvf mysql-8.2.0-1.el7.x86_64.rpm-bundle.tar
?
# 卸載mariadb
rpm -e mariadb-libs-5.5.68-1.el7.x86_64 --nodeps
?
# 安裝MySQL
yum localinstall -y *.rpm
分別配置root密碼:
[root@mysql-rs-2 server]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.2.0
?
Copyright (c) 2000, 2023, 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 '\h' for help. Type '\c' to clear the current input statement.
?
mysql>
mysql>
mysql> alter user root@'localhost' identified by 'Abcd@1234';
Query OK, 0 rows affected (0.00 sec)
?
mysql> create user root@'%' identified by 'Abcd@1234';
Query OK, 0 rows affected (0.01 sec)
3.2. 安裝mysqlsh
# 下載mysqlshell
wget https://cdn.mysql.com//Downloads/MySQL-Shell/mysql-shell-8.2.0-1.el7.x86_64.rpm
# 安裝mysqlshell
rpm -ivh mysql-shell-8.2.0-1.el7.x86_64.rpm
驗證mysql shell鏈接數據庫
[root@mysql-rs-1 software]# mysqlsh --mysql -u root -h localhost -C
Please provide the password for 'root@localhost': ************
Save password for 'root@localhost'? [Y]es/[N]o/Ne[v]er (default No):
Error during auto-completion cache update: You must reset your password using ALTER USER statement before executing this statement.
MySQL Shell 8.2.0
?
Copyright (c) 2016, 2023, 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 Classic session to 'root@localhost?compression=REQUIRED'
Your MySQL connection id is 8
No default schema selected; type \use <schema> to set one.MySQL localhost JS >
3.3. 配置實例
在其中一個主機上啟動mysqlsh連接
[root@mysql-rs-1 software]# mysqlsh root@mysql-rs-1:3306
MySQL Shell 8.2.0
?
Copyright (c) 2016, 2023, 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 'root@mysql-rs-1:3306'
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 21
Server version: 8.2.0 MySQL Community Server - GPL
No default schema selected; type \use <schema> to set one.
分別給root用戶授權:
GRANT CLONE_ADMIN, CONNECTION_ADMIN, CREATE USER, EXECUTE, FILE, GROUP_REPLICATION_ADMIN, PERSIST_RO_VARIABLES_ADMIN, PROCESS, RELOAD, REPLICATION CLIENT, REPLICATION SLAVE, REPLICATION_APPLIER, REPLICATION_SLAVE_ADMIN, ROLE_ADMIN, SELECT, SHUTDOWN, SYSTEM_VARIABLES_ADMIN ON *.* TO 'root'@'%' WITH GRANT OPTION;
GRANT DELETE, INSERT, UPDATE ON mysql.* TO 'root'@'%' WITH GRANT OPTION;
GRANT ALTER, ALTER ROUTINE, CREATE, CREATE ROUTINE, CREATE TEMPORARY TABLES, CREATE VIEW, DELETE, DROP, EVENT, EXECUTE, INDEX, INSERT, LOCK TABLES, REFERENCES, SHOW VIEW, TRIGGER, UPDATE ON mysql_innodb_cluster_metadata.* TO 'root'@'%' WITH GRANT OPTION;
GRANT ALTER, ALTER ROUTINE, CREATE, CREATE ROUTINE, CREATE TEMPORARY TABLES, CREATE VIEW, DELETE, DROP, EVENT, EXECUTE, INDEX, INSERT, LOCK TABLES, REFERENCES, SHOW VIEW, TRIGGER, UPDATE ON mysql_innodb_cluster_metadata_bkp.* TO 'root'@'%' WITH GRANT OPTION;
GRANT ALTER, ALTER ROUTINE, CREATE, CREATE ROUTINE, CREATE TEMPORARY TABLES, CREATE VIEW, DELETE, DROP, EVENT, EXECUTE, INDEX, INSERT, LOCK TABLES, REFERENCES, SHOW VIEW, TRIGGER, UPDATE ON mysql_innodb_cluster_metadata_previous.* TO 'root'@'%' WITH GRANT OPTION;
在MySQL Shell中執行:
配置mysql-rs-1:
MySQL mysql-rs-1:3306 ssl JS > dba.configureReplicaSetInstance('root@mysql-rs-1:3306', {clusterAdmin: "rs_admin"})
Configuring local MySQL instance listening at port 3306 for use in an InnoDB ReplicaSet...
?
This instance reports its own address as mysql-rs-1: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.
Assuming full account name 'rs_admin'@'%' for rs_admin
Password for new account: *********
Confirm password: *********
?
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
?
Creating user rs_admin@%.
Account rs_admin@% was successfully created.
?
Configuring instance...
?
WARNING: '@@binlog_transaction_dependency_tracking' is deprecated and will be removed in a future release. (Code 1287).
The instance 'mysql-rs-1:3306' was configured to be used in an InnoDB ReplicaSet.
Restarting MySQL...
NOTE: MySQL server at mysql-rs-1:3306 was restarted.
配置mysql-rs-2:
MySQL mysql-rs-1:3306 ssl JS > dba.configureReplicaSetInstance('root@mysql-rs-2:3306', {clusterAdmin: "rs_admin"})
Please provide the password for 'root@mysql-rs-2:3306': *********
Save password for 'root@mysql-rs-2:3306'? [Y]es/[N]o/Ne[v]er (default No): Y
Configuring MySQL instance at mysql-rs-2:3306 for use in an InnoDB ReplicaSet...
?
This instance reports its own address as mysql-rs-2: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.
Assuming full account name 'rs_admin'@'%' for rs_admin
Password for new account: *********
Confirm password: *********
?
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
?
Creating user rs_admin@%.
Account rs_admin@% was successfully created.
?
Configuring instance...
?
WARNING: '@@binlog_transaction_dependency_tracking' is deprecated and will be removed in a future release. (Code 1287).
The instance 'mysql-rs-2:3306' was configured to be used in an InnoDB ReplicaSet.
Restarting MySQL...
NOTE: MySQL server at mysql-rs-2:3306 was restarted.
3.4. 創建ReplicationSet
創建ReplicationSet,默認會將當前進入的實例為主庫實例:
MySQL mysql-rs-1:3306 ssl JS > dba.createReplicaSet('ReplicaSet')
A new replicaset with instance 'mysql-rs-1:3306' will be created.
?
* Checking MySQL instance at mysql-rs-1:3306
?
This instance reports its own address as mysql-rs-1:3306
mysql-rs-1:3306: Instance configuration is suitable.
?
* Checking connectivity and SSL configuration...
* Updating metadata...
?
ReplicaSet object successfully created for mysql-rs-1:3306.
Use rs.addInstance() to add more asynchronously replicated instances to this replicaset and rs.status() to check its status.
?
<ReplicaSet:ReplicaSet>
3.5. 將另一個實例加入到創建的 ReplicaSet
MySQL mysql-rs-1:3306 ssl JS > var rs = dba.getReplicaSet()You are connected to a member of replicaset 'ReplicaSet'.MySQL mysql-rs-1:3306 ssl JS > rs.addInstance('mysql-rs-2:3306')
Adding instance to the replicaset...
?
* Performing validation checks
?
This instance reports its own address as mysql-rs-2:3306
mysql-rs-2:3306: Instance configuration is suitable.
?
* Checking async replication topology...
?
* Checking connectivity and SSL configuration...
?
* Checking transaction state of the instance...
?
NOTE: The target instance 'mysql-rs-2:3306' has not been pre-provisioned (GTID set is empty). The Shell is unable to decide whether replication can completely recover its state.
The safest and most convenient way to provision a new instance is through automatic clone provisioning, which will completely overwrite the state of 'mysql-rs-2:3306' with a physical snapshot from an existing replicaset member. To use this method by default, set the 'recoveryMethod' option to 'clone'.
?
WARNING: It should be safe to rely on replication to incrementally recover the state of the new instance if you are sure all updates ever executed in the replicaset were done with GTIDs enabled, there are no purged transactions and the new instance contains the same GTID set as the replicaset or a subset of it. To use this method by default, set the 'recoveryMethod' option to 'incremental'.
?
?
Please select a recovery method [C]lone/[I]ncremental recovery/[A]bort (default Clone):
* Updating topology
Monitoring Clone based state recovery of the new member. Press ^C to abort the operation.
Clone based state recovery is now in progress.
?
NOTE: A server restart is expected to happen as part of the clone process. If the
server does not support the RESTART command or does not come back after a
while, you may need to manually start it back.
?
* Waiting for clone to finish...
NOTE: mysql-rs-2:3306 is being cloned from mysql-rs-1:3306
** Stage DROP DATA: Completed
** Clone Transfer ?FILE COPY ?############################################################ 100% CompletedPAGE COPY ?############################################################ 100% CompletedREDO COPY ?############################################################ 100% Completed
* Clone process has finished: 76.80 MB transferred in about 1 second (~76.80 MB/s)
?
** Changing replication source of mysql-rs-2:3306 to mysql-rs-1:3306
** Waiting for new instance to synchronize with PRIMARY...
** Transactions replicated ?############################################################ 100%
?
The instance 'mysql-rs-2:3306' was added to the replicaset and is replicating from mysql-rs-1:3306.
?
* Waiting for instance 'mysql-rs-2:3306' to synchronize the Metadata updates with the PRIMARY...
** Transactions replicated ?############################################################ 100%
3.6. 查看副本集狀態
MySQL mysql-rs-1:3306 ssl JS > var rs = dba.getReplicaSet()
You are connected to a member of replicaset 'ReplicaSet'.MySQL mysql-rs-1:3306 ssl JS > rs.status()
{"replicaSet": {"name": "ReplicaSet", "primary": "mysql-rs-1:3306", "status": "AVAILABLE", "statusText": "All instances available.", "topology": {"mysql-rs-1:3306": {"address": "mysql-rs-1:3306", "instanceRole": "PRIMARY", "mode": "R/W", "status": "ONLINE"}, "mysql-rs-2:3306": {"address": "mysql-rs-2:3306", "instanceRole": "SECONDARY", "mode": "R/O", "replication": {"applierStatus": "APPLIED_ALL", "applierThreadState": "Waiting for an event from Coordinator", "applierWorkerThreads": 4, "receiverStatus": "ON", "receiverThreadState": "Waiting for source to send event", "replicationLag": null, "replicationSsl": "ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2", "replicationSslMode": "REQUIRED"}, "status": "ONLINE"}}, "type": "ASYNC"}
}
3.7. 配置MySQL Router
# 下載MySQL Router
wget https://cdn.mysql.com//Downloads/MySQL-Router/mysql-router-community-8.2.0-1.el7.x86_64.rpm
# 安裝
rpm -ivh mysql-router-community-8.2.0-1.el7.x86_64.rpmMySQL mysql-rs-1:3306 ssl JS > var rs = dba.getReplicaSet()
You are connected to a member of replicaset 'ReplicaSet'.MySQL mysql-rs-1:3306 ssl JS > rs.setupRouterAccount('rs_router1')
?
Missing the password for new account rs_router1@%. Please provide one.
Password for new account: *********
Confirm password: *********
?
?
Creating user rs_router1@%.
Account rs_router1@% was successfully created.
3.8. 引導啟動MySQL Router
[root@mysql-rs-1 software]# mysqlrouter --bootstrap root@mysql-rs-1:3306 --user mysqlrouter
Please enter MySQL password for root:
# Bootstrapping system MySQL Router 8.2.0 (MySQL Community - GPL) instance...
?
- Creating account(s) (only those that are needed, if any)
- Verifying account (using it to run SQL queries that would be run by Router)
- Storing account in keyring
- Adjusting permissions of generated files
- Creating configuration /etc/mysqlrouter/mysqlrouter.conf
?
Existing configuration backed up to '/etc/mysqlrouter/mysqlrouter.conf.bak'
?
# MySQL Router configured for the InnoDB ReplicaSet 'ReplicaSet'
?
After this MySQL Router has been started with the generated configuration
?$ /etc/init.d/mysqlrouter restart
or$ systemctl start mysqlrouter
or$ mysqlrouter -c /etc/mysqlrouter/mysqlrouter.conf
?
InnoDB ReplicaSet 'ReplicaSet' can be reached by connecting to:
?
## MySQL Classic protocol
?
- Read/Write Connections: localhost:6446
- Read/Only Connections: localhost:6447
- Read/Write Split Connections: localhost:6450
?
## MySQL X protocol
?
- Read/Write Connections: localhost:6448
- Read/Only Connections: localhost:6449
3.9. 讀寫分離驗證
檢查ReplicaSet,可以看到主節點(讀寫)為mysql-rs-1:3306,從節點(只讀)為mysql-rs-2:3306
MySQL mysql-rs-1:3306 ssl JS > rs.status()
{"replicaSet": {"name": "ReplicaSet", "primary": "mysql-rs-1:3306", "status": "AVAILABLE", "statusText": "All instances available.", "topology": {"mysql-rs-1:3306": {"address": "mysql-rs-1:3306", "instanceRole": "PRIMARY", "mode": "R/W", "status": "ONLINE"}, "mysql-rs-2:3306": {"address": "mysql-rs-2:3306", "instanceRole": "SECONDARY", "mode": "R/O", "replication": {"applierStatus": "APPLIED_ALL", "applierThreadState": "Waiting for an event from Coordinator", "applierWorkerThreads": 4, "receiverStatus": "ON", "receiverThreadState": "Waiting for source to send event", "replicationLag": null, "replicationSsl": "ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2", "replicationSslMode": "REQUIRED"}, "status": "ONLINE"}}, "type": "ASYNC"}
}
檢查mysqlrouter,可以看到MySQL Router讀寫端口為6450
MySQL mysql-rs-1:3306 ssl JS > rs.listRouters()
{"replicaSetName": "ReplicaSet", "routers": {"mysql-rs-1::system": {"hostname": "mysql-rs-1", "lastCheckIn": "2023-11-14 11:40:21", "roPort": "6447", "roXPort": "6449", "rwPort": "6446", "rwSplitPort": "6450", "rwXPort": "6448", "version": "8.2.0"}}
}
下面通過MySQL Router的讀寫端口6450連接mysql數據庫:
[root@mysql-rs-1 ~]# mysqlsh mysql://root@mysql-rs-1:6450 --sql
MySQL Shell 8.2.0
?
Copyright (c) 2016, 2023, 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 Classic session to 'root@mysql-rs-1:6450'
Fetching global names for auto-completion... Press ^C to stop.
Your MySQL connection id is 0
Server version: 8.2.0 MySQL Community Server - GPL
No default schema selected; type \use <schema> to set one.MySQL mysql-rs-1:6450 ssl SQL >
查詢數據,發現當前節點為從節點:
MySQL mysql-rs-1:6450 ssl SQL > select @@hostname, @@port;
+------------+--------+
| @@hostname | @@port |
+------------+--------+
| mysql-rs-2 | ? 3306 |
+------------+--------+
1 row in set (0.0035 sec)
Statement ID: 13700
開啟事務,會自動切換到主節點:
MySQL mysql-rs-1:6450 ssl SQL > start transaction;
Query OK, 0 rows affected (0.0031 sec)
Statement ID: 20477MySQL mysql-rs-1:6450 ssl ★ SQL > select @@hostname, @@port;
+------------+--------+
| @@hostname | @@port |
+------------+--------+
| mysql-rs-1 | ? 3306 |
+------------+--------+
1 row in set (0.0007 sec)
Statement ID: 20563
提交或者回滾事務后,自動切換到從節點:
MySQL mysql-rs-1:6450 ssl ★ SQL > rollback;
Query OK, 0 rows affected (0.0006 sec)
Statement ID: 21909MySQL mysql-rs-1:6450 ssl SQL > select @@hostname, @@port;
+------------+--------+
| @@hostname | @@port |
+------------+--------+
| mysql-rs-2 | ? 3306 |
+------------+--------+
1 row in set (0.0020 sec)
Statement ID: 15489
只讀事務中,也會切換到從節點:
MySQL mysql-rs-1:6450 ssl SQL > start transaction read only;
Query OK, 0 rows affected (0.0029 sec)
Statement ID: 16970MySQL mysql-rs-1:6450 ssl ☆ SQL > select @@hostname, @@port;
+------------+--------+
| @@hostname | @@port |
+------------+--------+
| mysql-rs-2 | ? 3306 |
+------------+--------+
1 row in set (0.0010 sec)
Statement ID: 16996
用戶還可以在會話中使用ROUTER SET access_mode=命令來定義應用要連接的實例類型:
MySQL mysql-rs-1:6450 ssl SQL > router set access_mode='read_write';
Query OK, 0 rows affected (0.0004 sec)MySQL mysql-rs-1:6450 ssl ?- SQL > select @@hostname, @@port;
+------------+--------+
| @@hostname | @@port |
+------------+--------+
| mysql-rs-1 | ? 3306 |
+------------+--------+
1 row in set (0.0017 sec)
Statement ID: 25535MySQL mysql-rs-1:6450 ssl SQL > router set access_mode='read_only';
Query OK, 0 rows affected (0.0006 sec)MySQL mysql-rs-1:6450 ssl ?- SQL > select @@hostname, @@port;
+------------+--------+
| @@hostname | @@port |
+------------+--------+
| mysql-rs-2 | ? 3306 |
+------------+--------+
1 row in set (0.0043 sec)
Statement ID: 18508
4. 總結
總之,MySQL Router 8.2支持讀寫分離。這是一項有價值的功能,可以優化數據庫性能和可擴展性,而無需在應用程序中進行任何更改。這種配置使您能夠將所有讀流量引導到只讀實例,將所有寫流量引導到讀寫實例。這不僅增強了用戶的整體體驗,還簡化了數據庫管理和部署。
讀寫實例是主實例或源實例。只讀實例是副本(InnoDB集群的非主實例、ReplicaSet的非主實例或復制集群中的非主實例)。