MySQL Shell对关系表进行操作

MySQL Shell不仅可以操作JSON文档,还可以操作关系表。

在MySQL中,每个关系表都与特定的存储引擎相关联。本节中的例子使用world_x数据库中的InnoDB表。

确认模式
要显示分配给模式变量的值,请输入db。

 MySQL  localhost:33060+  world_x  JS > db

如果schema值不是schema:world_x,则设置db变量如下:

mysql-js> \use world_x

显示所有表
要显示world_x数据库中的所有关系表,可以在schema对象上使用getTables()方法。

 MySQL  localhost:33060+  world_x  JS > db.getTables()
[
    ,
    ,
    ,
    
]

基本表操作
表的基本操作范围包括:
db.name.insert():insert()方法向指定的表中插入一条或多条记录。
db.name.select():select()方法返回指定表中的部分或全部记录。
db.name.update():update()方法更新指定表中的记录。
db.name.delete():delete()方法从指定的表中删除一条或多条记录。

向表中插入记录
可以结合values()方法使用insert()方法将记录插入到现有的关系表中。insert()方法接受单个列或表中的所有列作为参数。使用一个或 多个values()方法指定要插入的值。

插入完整记录
要插入完整的记录,向insert()方法传递表中的所有列。然后向values()方法传递表中的每一列的一个值。例如,要向world_x数据库中的 city表中添加一条新记录,插入下面的记录并按两次Enter键。

 MySQL  localhost:33060+  world_x  JS > db.city.insert("ID", "Name", "CountryCode", "District", "Info").values(null,  "Olympia", "USA", "Washington", '{"Population": 5000}')
Query OK, 1 item affected (0.0250 sec)

城市表有5列:ID、Name、CountryCode、District和Info。每个值必须与它表示的列的数据类型匹配。

插入部分记录
下面的示例将值插入city表的ID、Name和CountryCode列。

 MySQL  localhost:33060+  world_x  JS > db.city.insert("ID", "Name", "CountryCode").values(null, "Little Falls",  "USA").values(null, "Happy Valley", "USA")
Query OK, 2 items affected (0.0092 sec)

Records: 2  Duplicates: 0  Warnings: 0

使用insert()方法指定列时,值的数量必须与列的数量匹配。在前面的例子中,必须提供三个值来匹配指定的三列。

查询表记录
你可以使用select()方法从数据库的表中查询并返回记录。X DevAPI提供了与select()方法一起使用的其他方法,用于过滤和排序返回的记 录。

MySQL提供了以下运营商指定搜索条件:OR(| |),AND(& &),XOR IS,NOT,BETWEEN,IN,LIKE, !=, <>, >, >=, < , <=, &, |, <<, >>, +, -, *, /, ~, 和%。

查询所有记录
要查询已存在表中的所有记录,只需使用select()方法,而无需指定搜索条件。下面的示例从world_x数据库中的city表中选择所有记录。

将空的select()方法限制为交互式语句。始终在应用程序代码中使用显式的列名选择。

 MySQL  localhost:33060+  world_x  JS > db.city.select()
+------+--------------------------------+-------------+----------------------+-------------------------+
| ID   | Name                           | CountryCode | District             | Info                    |
+------+--------------------------------+-------------+----------------------+-------------------------+
|    1 | Kabul                          | AFG         | Kabol                | {"Population": 1780000} |
|    2 | Qandahar                       | AFG         | Qandahar             | {"Population": 237500}  |
|    3 | Herat                          | AFG         | Herat                | {"Population": 186800}  |
|    4 | Mazar-e-Sharif                 | AFG         | Balkh                | {"Population": 127800}  |
..................
| 4078 | Nablus                         | PSE         | Nablus               | {"Population": 100231}  |
| 4079 | Rafah                          | PSE         | Rafah                | {"Population": 92020}   |
| 4082 | Olympia                        | USA         | Washington           | {"Population": 5000}    |
| 4089 | Little Falls                   | USA         |                      | NULL                    |
| 4096 | Happy Valley                   | USA         |                      | NULL                    |
+------+--------------------------------+-------------+----------------------+-------------------------+
4082 rows in set (0.0024 sec)

过滤搜索
要发出一个返回一组表列的查询,可以使用select()方法,并在方括号中指定要返回的列。这个查询返回city表中的Name和CountryCode列。

 MySQL  localhost:33060+  world_x  JS > db.city.select(["Name", "CountryCode"])
+--------------------------------+-------------+
| Name                           | CountryCode |
+--------------------------------+-------------+
| Kabul                          | AFG         |
| Qandahar                       | AFG         |
| Herat                          | AFG         |
| Mazar-e-Sharif                 | AFG         |
.................
| Jabaliya                       | PSE         |
| Nablus                         | PSE         |
| Rafah                          | PSE         |
| Olympia                        | USA         |
| Little Falls                   | USA         |
| Happy Valley                   | USA         |
+--------------------------------+-------------+
4082 rows in set (0.0023 sec)

要查询返回符合特定搜索条件的行,可以使用where()方法来包含这些条件。例如,下面的示例返回以字母Z开头的城市的名称和国家代码。

 MySQL  localhost:33060+  world_x  JS > db.city.select(["Name", "CountryCode"]).where("Name like 'Z%'")
+-----------------+-------------+
| Name            | CountryCode |
+-----------------+-------------+
| Zaanstad        | NLD         |
| Zoetermeer      | NLD         |
| Zwolle          | NLD         |
| Zenica          | BIH         |
| Zagazig         | EGY         |
| Zaragoza        | ESP         |
| Zamboanga       | PHL         |
| Zahedan         | IRN         |
| Zanjan          | IRN         |
| Zabol           | IRN         |
| Zama            | JPN         |
| Zhezqazghan     | KAZ         |
| Zhengzhou       | CHN         |
| Zibo            | CHN         |
| Zhangjiakou     | CHN         |
| Zhuzhou         | CHN         |
| Zhangjiang      | CHN         |
| Zigong          | CHN         |
| Zaozhuang       | CHN         |
| Zhenjiang       | CHN         |
| Zhongshan       | CHN         |
| Zunyi           | CHN         |
| Zhaoqing        | CHN         |
| Zhangzhou       | CHN         |
| Zhaodong        | CHN         |
| Zhuhai          | CHN         |
| Zaoyang         | CHN         |
| Zhoushan        | CHN         |
| Zhoukou         | CHN         |
| Zalantun        | CHN         |
| Zhumadian       | CHN         |
| Zixing          | CHN         |
| Zhucheng        | CHN         |
| Zhangjiagang    | CHN         |
| Zagreb          | HRV         |
| Zapopan         | MEX         |
| Zamora          | MEX         |
| Zitácuaro       | MEX         |
| Zacatecas       | MEX         |
| Zinacantepec    | MEX         |
| Zumpango        | MEX         |
| Zinder          | NER         |
| Zaria           | NGA         |
| Zabrze          | POL         |
| Zielona Góra    | POL         |
| Zwickau         | DEU         |
| Ziguinchor      | SEN         |
| Zürich          | CHE         |
| Zanzibar        | TZA         |
| Zonguldak       | TUR         |
| Zaporizzja      | UKR         |
| Zytomyr         | UKR         |
| Zelenograd      | RUS         |
| Zlatoust        | RUS         |
| Zelenodolsk     | RUS         |
| Zeleznodoroznyi | RUS         |
| Zeleznogorsk    | RUS         |
| Zukovski        | RUS         |
| Zeleznogorsk    | RUS         |
+-----------------+-------------+
59 rows in set (0.0049 sec)

可以使用bind()方法将值与搜索条件分开。例如,不使用“Name = ‘Z%’ ”作为条件,而是使用冒号和以字母开头的名称组成的命名占位符, 例如Name。然后在bind()方法中包含占位符和值,如下所示:

 MySQL  localhost:33060+  world_x  JS > db.city.select(["Name", "CountryCode"]).where("Name like :name").bind("name", "Z%")
+-----------------+-------------+
| Name            | CountryCode |
+-----------------+-------------+
| Zaanstad        | NLD         |
| Zoetermeer      | NLD         |
| Zwolle          | NLD         |
| Zenica          | BIH         |
| Zagazig         | EGY         |
| Zaragoza        | ESP         |
| Zamboanga       | PHL         |
| Zahedan         | IRN         |
| Zanjan          | IRN         |
| Zabol           | IRN         |
| Zama            | JPN         |
| Zhezqazghan     | KAZ         |
| Zhengzhou       | CHN         |
| Zibo            | CHN         |
| Zhangjiakou     | CHN         |
| Zhuzhou         | CHN         |
| Zhangjiang      | CHN         |
| Zigong          | CHN         |
| Zaozhuang       | CHN         |
| Zhenjiang       | CHN         |
| Zhongshan       | CHN         |
| Zunyi           | CHN         |
| Zhaoqing        | CHN         |
| Zhangzhou       | CHN         |
| Zhaodong        | CHN         |
| Zhuhai          | CHN         |
| Zaoyang         | CHN         |
| Zhoushan        | CHN         |
| Zhoukou         | CHN         |
| Zalantun        | CHN         |
| Zhumadian       | CHN         |
| Zixing          | CHN         |
| Zhucheng        | CHN         |
| Zhangjiagang    | CHN         |
| Zagreb          | HRV         |
| Zapopan         | MEX         |
| Zamora          | MEX         |
| Zitácuaro       | MEX         |
| Zacatecas       | MEX         |
| Zinacantepec    | MEX         |
| Zumpango        | MEX         |
| Zinder          | NER         |
| Zaria           | NGA         |
| Zabrze          | POL         |
| Zielona Góra    | POL         |
| Zwickau         | DEU         |
| Ziguinchor      | SEN         |
| Zürich          | CHE         |
| Zanzibar        | TZA         |
| Zonguldak       | TUR         |
| Zaporizzja      | UKR         |
| Zytomyr         | UKR         |
| Zelenograd      | RUS         |
| Zlatoust        | RUS         |
| Zelenodolsk     | RUS         |
| Zeleznodoroznyi | RUS         |
| Zeleznogorsk    | RUS         |
| Zukovski        | RUS         |
| Zeleznogorsk    | RUS         |
+-----------------+-------------+
59 rows in set (0.0040 sec)

要使用AND操作符进行查询,在where()方法的搜索条件之间添加操作符。

 MySQL  localhost:33060+  world_x  JS > db.city.select(["Name", "CountryCode"]).where("Name like 'Z%' and CountryCode =  'CHN'")
+--------------+-------------+
| Name         | CountryCode |
+--------------+-------------+
| Zhengzhou    | CHN         |
| Zibo         | CHN         |
| Zhangjiakou  | CHN         |
| Zhuzhou      | CHN         |
| Zhangjiang   | CHN         |
| Zigong       | CHN         |
| Zaozhuang    | CHN         |
| Zhenjiang    | CHN         |
| Zhongshan    | CHN         |
| Zunyi        | CHN         |
| Zhaoqing     | CHN         |
| Zhangzhou    | CHN         |
| Zhaodong     | CHN         |
| Zhuhai       | CHN         |
| Zaoyang      | CHN         |
| Zhoushan     | CHN         |
| Zhoukou      | CHN         |
| Zalantun     | CHN         |
| Zhumadian    | CHN         |
| Zixing       | CHN         |
| Zhucheng     | CHN         |
| Zhangjiagang | CHN         |
+--------------+-------------+
22 rows in set (0.0051 sec)

要指定多个条件运算符,可以将搜索条件放在括号中以更改运算符的优先级。下面的例子演示了AND和OR操作符的位置。

 MySQL  localhost:33060+  world_x  JS > db.city.select(["Name", "CountryCode"]).where("Name like 'Z%' and (CountryCode = 'CHN'  or CountryCode = 'RUS')")
+-----------------+-------------+
| Name            | CountryCode |
+-----------------+-------------+
| Zhengzhou       | CHN         |
| Zibo            | CHN         |
| Zhangjiakou     | CHN         |
| Zhuzhou         | CHN         |
| Zhangjiang      | CHN         |
| Zigong          | CHN         |
| Zaozhuang       | CHN         |
| Zhenjiang       | CHN         |
| Zhongshan       | CHN         |
| Zunyi           | CHN         |
| Zhaoqing        | CHN         |
| Zhangzhou       | CHN         |
| Zhaodong        | CHN         |
| Zhuhai          | CHN         |
| Zaoyang         | CHN         |
| Zhoushan        | CHN         |
| Zhoukou         | CHN         |
| Zalantun        | CHN         |
| Zhumadian       | CHN         |
| Zixing          | CHN         |
| Zhucheng        | CHN         |
| Zhangjiagang    | CHN         |
| Zelenograd      | RUS         |
| Zlatoust        | RUS         |
| Zelenodolsk     | RUS         |
| Zeleznodoroznyi | RUS         |
| Zeleznogorsk    | RUS         |
| Zukovski        | RUS         |
| Zeleznogorsk    | RUS         |
+-----------------+-------------+
29 rows in set (0.0042 sec)

可以使用limit()、orderBy()和offSet()方法来管理select()方法返回的记录的数量和顺序。

要指定结果集中包含的记录数,可以在limit()方法后面添加一个值给select()方法。例如,下面的查询返回country表中的前5条记录。

 MySQL  localhost:33060+  world_x  JS > db.country.select(["Code", "Name"]).limit(5)
+------+-------------+
| Code | Name        |
+------+-------------+
| ABW  | Aruba       |
| AFG  | Afghanistan |
| AGO  | Angola      |
| AIA  | Anguilla    |
| ALB  | Albania     |
+------+-------------+
5 rows in set (0.0013 sec)

要指定结果的顺序,可以在select()方法后面添加orderBy()方法。向orderBy()方法传递一个列表,其中包含一个或多个用于排序的列, 还可以根据需要传递降序(desc)或升序(asc)属性。升序是默认的排序类型。

例如,下面的查询按Name列对所有记录进行排序,然后按降序返回前三条记录。

 MySQL  localhost:33060+  world_x  JS > db.country.select(["Code", "Name"]).orderBy(["Name desc"]).limit(3)
+------+------------+
| Code | Name       |
+------+------------+
| ZWE  | Zimbabwe   |
| ZMB  | Zambia     |
| YUG  | Yugoslavia |
+------+------------+
3 rows in set (0.0016 sec)

默认情况下,limit()方法从表中的第一条记录开始。可以使用offset()方法修改起始记录。例如,要忽略第一条记录并返回符合条件的后 三条记录,可以向offset()方法传递一个值1。

 MySQL  localhost:33060+  world_x  JS > db.country.select(["Code", "Name"]).orderBy(["Name desc"]).limit(3).offset(1)
+------+------------+
| Code | Name       |
+------+------------+
| ZMB  | Zambia     |
| YUG  | Yugoslavia |
| YEM  | Yemen      |
+------+------------+
3 rows in set (0.0015 sec)

更新表记录
可以使用update()方法修改表中的一条或多条记录。update()方法的工作原理是过滤一个查询,只包含需要更新的记录,然后对这些记录应 用指定的操作。

要替换city表中的城市名,向set()方法传递新的城市名。然后,向where()方法传递要定位和替换的城市名。下面的例子将北京这个城市替 换为北京。

 MySQL  localhost:33060+  world_x  JS > db.city.update().set("Name", "Beijing").where("Name = 'Peking'")
Query OK, 1 item affected (0.0299 sec)

Rows matched: 1  Changed: 1  Warnings: 0

使用select()方法验证修改。

 MySQL  localhost:33060+  world_x  JS > db.city.select(["ID", "Name", "CountryCode", "District", "Info"]).where("Name =  'Beijing'")
+------+---------+-------------+----------+-------------------------+
| ID   | Name    | CountryCode | District | Info                    |
+------+---------+-------------+----------+-------------------------+
| 1891 | Beijing | CHN         | Peking   | {"Population": 7472000} |
+------+---------+-------------+----------+-------------------------+
1 row in set (0.0072 sec)

删除表记录
你可以使用delete()方法从数据库的一张表中删除部分或全部记录。X DevAPI提供了额外的方法与delete()方法一起使用,用于过滤和排序 要删除的记录。

使用条件删除记录
下面的例子将搜索条件传递给delete()方法。所有符合条件的记录都将从city表中删除。在这个例子中,只有一条记录符合条件。

 MySQL  localhost:33060+  world_x  JS > db.city.delete().where("Name = 'Olympia'")
Query OK, 1 item affected (0.0130 sec)

删除第一条记录
要删除city表中的第一条记录,可以使用limit()方法将值设为1。

 MySQL  localhost:33060+  world_x  JS > db.city.delete().limit(1)
Query OK, 1 item affected (0.0060 sec)

删除表中的所有记录
可以删除表中的所有记录。为此,可以使用delete()方法,但不指定搜索条件。在没有指定搜索条件的情况下删除记录时要小心。该操作将从 表中删除所有记录。

MySQL 文档与集合

文档和集合
在MySQL中,集合包含JSON文档,你可以添加、查找、更新和删除这些文档。集合是模式中的容器,可以创建、列出和删除。

文档
在MySQL中,文档表示为JSON对象。在内部,它们以高效的二进制格式存储,支持快速查找和更新。
.JavaScript的简单文档格式:

{field1: "value", field2 : 10, "field 3": null}

文档数组由一组用逗号分隔、用[和]字符包裹的文档组成。

[{Name: "Aruba", _id: "ABW"}, {Name: "Angola", _id: "AGO"}]

MySQL支持JSON文档中的以下JavaScript值类型:
.数字(整数和浮点数)
.字符串
.布尔值(false和true)
.null
.包含更多JSON值的数组
.具有更多JSON值的嵌套(或嵌入)对象

集合
集合是用于共享目的的文档的容器,并且可能共享一个或多个索引。每个集合都有唯一的名称,并且存在于单一的模式中。
术语模式等同于数据库,意味着一组数据库对象(与之相对的是用于强制数据的结构和约束的关系模式)。模式并不强制集合中的文档保持一致性。基本对象包括:
.db:
db是一个全局变量,该变量分配给您在命令行上指定的当前活动模式。你可以在MySQL Shell中输入db来打印对象的描述,在本例中就是它所代表的模式的名称。

.db.getCollections():db.getCollections()保存了模式中的集合列表。使用列表获取集合对象的引用,迭代它们,等等。

集合作用域的基本操作包括:
.db.name.add():add()方法将一个文档或一个文档列表插入到指定的集合中。
.db.name.find():find()方法返回指定集合中的部分或全部文档。
.db.name.modify():方法modify()更新指定集合中的文档。
.db.name.remove():remove()方法从指定集合中删除一个文档或一个文档列表。

创建、显示和删除集合
在MySQL Shell中,你可以创建新的集合,获取模式中已存在集合的列表,或者从模式中删除已存在的集合。集合名称区分大小写,每个集合名称必须唯一。
确认模式
要显示分配给模式变量的值,请输入db。

 MySQL  localhost:33060+  world_x  JS > db

 MySQL  localhost:33060+  world_x  JS > 

如果schema值不是schema:world_x,则设置db变量如下:

 MySQL  localhost:33060+  JS > db
 MySQL  localhost:33060+  JS > \use world_x
Default schema `world_x` accessible through db.
 MySQL  localhost:33060+  world_x  JS > db

 MySQL  localhost:33060+  world_x  JS > 

创建一个集合
要在现有模式中创建新集合,可以使用createCollection()方法。下面的示例在world_x数据库中创建一个名为flags的集合。该方法返回一个集合对象。

 MySQL  localhost:33060+  world_x  JS > db.createCollection("flags")

 MySQL  localhost:33060+  world_x  JS > 

显示集合
要显示world_x数据库中的所有集合,可以在schema对象上使用getCollections()方法。服务器返回的集合出现在括号中。

 MySQL  localhost:33060+  world_x  JS > db.getCollections()
[
    
]
 MySQL  localhost:33060+  world_x  JS > 

删除集合
要从数据库中删除已有的集合,可以在session对象上调用dropCollection()方法。例如,要从world_x数据库中删除flags集合,输入:

 MySQL  localhost:33060+  world_x  JS > db.dropCollection("flags")
 MySQL  localhost:33060+  world_x  JS > db.getCollections()
[]

添加文档
使用MySQL Shell,可以使用add()方法将一个文档或一个列表文档插入到现有的集合中。本节中的所有示例都使用flags集合。
确认模式
要显示分配给模式变量的值,请输入db。

 MySQL  localhost:33060+  world_x  JS > db

如果schema值不是schema:world_x,则设置db变量如下:

 MySQL  localhost:33060+  JS > db
 MySQL  localhost:33060+  JS > \use world_x
Default schema `world_x` accessible through db.

添加文档
将下面的文档插入flags集合。按两次Enter键插入文档。

  MySQL  localhost:33060+  world_x  JS > db.createCollection("flags")


mysql> desc flags
    -> ;
+-------+-------------+------+-----+---------+------------------+
| Field | Type        | Null | Key | Default | Extra            |
+-------+-------------+------+-----+---------+------------------+
| doc   | json        | YES  |     | NULL    |                  |
| _id   | varchar(32) | NO   | PRI | NULL    | STORED GENERATED |
+-------+-------------+------+-----+---------+------------------+
2 rows in set (0.00 sec)



 MySQL  localhost:33060+  world_x  JS > db.getCollections()
[
    
]
 MySQL  localhost:33060+  world_x  JS >  db.flags.add(
                                     ->  {
                                     ->   GNP: .6,
                                     ->   IndepYear: 1967,
                                     ->   Name: "Sealand",
                                     ->   _id: "SEA",
                                     ->   demographics: {
                                     ->       LifeExpectancy: 79,
                                     ->       Population: 27
                                     ->   },
                                     ->   geography: {
                                     ->       Continent: "Europe",
                                     ->       Region: "British Islands",
                                     ->       SurfaceArea: 193
                                     ->   },
                                     ->   government: {
                                     ->       GovernmentForm: "Monarchy",
                                     ->       HeadOfState: "Michael Bates"
                                     ->   }
                                     ->  }
                                     -> )
                                     -> 
Query OK, 1 item affected (0.0073 sec)
 MySQL  localhost:33060+  world_x  JS > 

该方法返回操作的状态。

每个文档都需要一个名为_id的标识符字段。_id字段的值必须在同一个集合中的所有文档中唯一。如果传递给add()方法的文档不包含_id字段
,MySQL Shell会自动在文档中插入一个字段,并设置该字段的值为生成的UUID (universal unique identifier,通用唯一标识符)。

查找文档
可以使用find()方法从数据库中的集合中查询并返回文档。MySQL Shell为find()方法提供了额外的方法来过滤和排序返回的文档。
MySQL提供了以下运营商指定搜索条件:OR (||), AND (&&), XOR, IS, NOT,BETWEEN, IN, LIKE, !=, <>, >, >=, < , <=, &, |, <<, >>, +, -, *, /, ~, 和 %.

查找集合中的所有文档
要返回集合中的所有文档,可以使用find()方法,但不指定搜索条件。例如,下面的操作返回flags集合中的所有文档。

Query OK, 1 item affected (0.0154 sec)
 MySQL  localhost:33060+  world_x  JS > db.flags.find();
{
    "GNP": 351182,
    "_id": "AUS",
    "Name": "Australia",
    "IndepYear": 1901,
    "geography": {
        "Region": "Australia and New Zealand",
        "Continent": "Oceania",
        "SurfaceArea": 7741220
    },
    "government": {
        "HeadOfState": "Elisabeth II",
        "GovernmentForm": "Constitutional Monarchy, Federation"
    },
    "demographics": {
        "Population": 18886000,
        "LifeExpectancy": 79.80000305175781
    }
}
{
    "GNP": 0.6,
    "_id": "SEA",
    "Name": "Sealand",
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 27,
        "LifeExpectancy": 79
    }
}
2 documents in set (0.0009 sec)

该方法生成的结果除了包含集合中的所有文档外,还包含操作信息。
一个空集合(没有匹配的文档)返回以下信息:

Empty set (0.00 sec)

过滤搜索
你可以在find()方法中包含搜索条件。组成搜索条件的表达式的语法与传统MySQL相同。所有表达式必须用引号括起来。
本节中的所有示例都使用world_x数据库中的flags集合。为简洁起见,有些示例不显示输出。
一个简单的搜索条件由_id字段和文档的唯一标识符组成。下面的例子返回一个与标识符字符串匹配的文档:

 MySQL  localhost:33060+  world_x  JS > db.flags.find("_id = 'SEA'")
{
    "GNP": 0.6,
    "_id": "SEA",
    "Name": "Sealand",
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 27,
        "LifeExpectancy": 79
    }
}
1 document in set (0.0023 sec)
 MySQL  localhost:33060+  world_x  JS > 

下面的示例搜索GNP高于3000亿美元的所有国家。国家信息收集以百万为单位衡量国民生产总值。

 MySQL  localhost:33060+  world_x  JS > db.flags.find("GNP > 300000");
{
    "GNP": 351182,
    "_id": "AUS",
    "Name": "Australia",
    "IndepYear": 1901,
    "geography": {
        "Region": "Australia and New Zealand",
        "Continent": "Oceania",
        "SurfaceArea": 7741220
    },
    "government": {
        "HeadOfState": "Elisabeth II",
        "GovernmentForm": "Constitutional Monarchy, Federation"
    },
    "demographics": {
        "Population": 18886000,
        "LifeExpectancy": 79.80000305175781
    }
}
1 document in set (0.0012 sec)

下面查询中的Population字段嵌入到人口统计对象中。要访问嵌入式字段,使用人口统计数据和人口之间的句号来识别关系。文档名和字段名区分大小写。

 MySQL  localhost:33060+  world_x  JS > db.flags.find("GNP > 300000 and demographics.Population <100000000")
{
    "GNP": 351182,
    "_id": "AUS",
    "Name": "Australia",
    "IndepYear": 1901,
    "geography": {
        "Region": "Australia and New Zealand",
        "Continent": "Oceania",
        "SurfaceArea": 7741220
    },
    "government": {
        "HeadOfState": "Elisabeth II",
        "GovernmentForm": "Constitutional Monarchy, Federation"
    },
    "demographics": {
        "Population": 18886000,
        "LifeExpectancy": 79.80000305175781
    }
}
1 document in set (0.0012 sec)

可以使用bind()方法将值与搜索条件分开。例如,与其指定硬编码的国家名作为条件,不如用冒号和以字母开头的名称(如country)组成的命名占位符。然后在bind()方法中包含占位符和值,如下所示:

 MySQL  localhost:33060+  world_x  JS > db.flags.find("Name = :country").bind("country", "Sealand")
{
    "GNP": 0.6,
    "_id": "SEA",
    "Name": "Sealand",
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 27,
        "LifeExpectancy": 79
    }
}
1 document in set (0.0059 sec)

在程序中,绑定使您能够在表达式中指定占位符,这些占位符在执行之前被填充值,并且可以根据需要从自动转义中获益。始终使用绑定来清理输入。使用字符串连接避免在查询中引入值,这会产生无效的输入,在某些情况下,可能会导致安全问题。
可以返回文档的特定字段,而不是返回所有字段。下面的示例返回flags集合中匹配搜索条件的所有文档的GNP和Name字段。
使用fields()方法传递要返回的字段列表

 MySQL  localhost:33060+  world_x  JS > db.flags.find("GNP > 300000").fields(["GNP","Name"])
{
    "GNP": 351182,
    "Name": "Australia"
}
1 document in set (0.0017 sec)

此外,您可以使用描述要返回的文档的表达式来更改返回的文档——添加、重命名、嵌套甚至计算新的字段值。例如,使用下面的表达式更改字段的名称,使其仅返回两个文档。

 MySQL  localhost:33060+  world_x  JS > db.flags.find().fields(mysqlx.expr('{"Name": upper(Name), "GNPPerCapita": 

GNP*1000000/demographics.Population}')).limit(2)
{
    "Name": "AUSTRALIA",
    "GNPPerCapita": 18594.832150799535
}
{
    "Name": "SEALAND",
    "GNPPerCapita": 22222.222222222223
}
2 documents in set (0.0019 sec)

限制、排序和跳过结果
可以应用limit()、sort()和skip()方法来管理find()方法返回的文档数量和顺序。
要指定结果集中包含的文档数量,请将带有值的limit()方法附加到find()方法。下面的查询返回flags集合中的第一个文档。

 MySQL  localhost:33060+  world_x  JS > db.flags.find().limit(1)
{
    "GNP": 351182,
    "_id": "AUS",
    "Name": "Australia",
    "IndepYear": 1901,
    "geography": {
        "Region": "Australia and New Zealand",
        "Continent": "Oceania",
        "SurfaceArea": 7741220
    },
    "government": {
        "HeadOfState": "Elisabeth II",
        "GovernmentForm": "Constitutional Monarchy, Federation"
    },
    "demographics": {
        "Population": 18886000,
        "LifeExpectancy": 79.80000305175781
    }
}
1 document in set (0.0031 sec)

要指定结果的顺序,请将sort()方法附加到find()方法后。将一个或多个要排序的字段的列表传递给sort()方法,并根据需要可选地传递降序(desc)或升序(asc)属性。升序是默认的顺序类型。
例如,下面的查询按IndepYear字段对所有文档进行排序,然后按降序返回前2个文档。

 MySQL  localhost:33060+  world_x  JS > db.flags.find().sort(["IndepYear desc"]).limit(2)
{
    "GNP": 0.6,
    "_id": "SEA",
    "Name": "Sealand",
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 27,
        "LifeExpectancy": 79
    }
}
{
    "GNP": 351182,
    "_id": "AUS",
    "Name": "Australia",
    "IndepYear": 1901,
    "geography": {
        "Region": "Australia and New Zealand",
        "Continent": "Oceania",
        "SurfaceArea": 7741220
    },
    "government": {
        "HeadOfState": "Elisabeth II",
        "GovernmentForm": "Constitutional Monarchy, Federation"
    },
    "demographics": {
        "Population": 18886000,
        "LifeExpectancy": 79.80000305175781
    }
}
2 documents in set (0.0032 sec)

默认情况下,limit()方法从集合中的第一个文档开始。您可以使用skip()方法来更改起始文档。例如,要忽略第一个文档并返回后面1个匹配条件的文档,可以将值1传递给skip()方法。

 MySQL  localhost:33060+  world_x  JS > db.flags.find().sort(["IndepYear desc"]).limit(1).skip(1)
{
    "GNP": 351182,
    "_id": "AUS",
    "Name": "Australia",
    "IndepYear": 1901,
    "geography": {
        "Region": "Australia and New Zealand",
        "Continent": "Oceania",
        "SurfaceArea": 7741220
    },
    "government": {
        "HeadOfState": "Elisabeth II",
        "GovernmentForm": "Constitutional Monarchy, Federation"
    },
    "demographics": {
        "Population": 18886000,
        "LifeExpectancy": 79.80000305175781
    }
}
1 document in set (0.0015 sec)

修改文档
可以使用modify()方法更新集合中的一个或多个文档。X DevAPI提供了与modify()方法一起使用的附加方法:
.设置和取消设置文档中的字段。
.追加、插入和删除数组。
.对要修改的文档进行绑定、限制和排序。

设置和取消设置文档中的字段
modify()方法的工作原理是过滤一个集合,使其只包含要修改的文档,然后将您指定的操作应用于这些文档。
在下面的示例中,modify()方法使用搜索条件来标识要更改的文档,然后set()方法替换嵌套的人口统计对象中的两个值。

 MySQL  localhost:33060+  world_x  JS > db.flags.modify("_id = 'SEA'").set("demographics", {LifeExpectancy: 78, Population: 

28})
Query OK, 1 item affected (0.0333 sec)

Rows matched: 1  Changed: 1  Warnings: 0

在修改文档之后,使用find()方法来验证更改。

 MySQL  localhost:33060+  world_x  JS > db.flags.find("_id = 'SEA'")
{
    "GNP": 0.6,
    "_id": "SEA",
    "Name": "Sealand",
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 28,
        "LifeExpectancy": 78
    }
}
1 document in set (0.0010 sec)

要从文档中删除内容,请使用modify()和unset()方法。例如,下面的查询从匹配搜索条件的文档中删除GNP。

 MySQL  localhost:33060+  world_x  JS > db.flags.modify("Name = 'Sealand'").unset("GNP")
Query OK, 1 item affected (0.0072 sec)

Rows matched: 1  Changed: 1  Warnings: 0

使用find()方法验证更改。

 MySQL  localhost:33060+  world_x  JS > db.flags.find("Name = 'Sealand'")
{
    "_id": "SEA",
    "Name": "Sealand",
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 28,
        "LifeExpectancy": 78
    }
}
1 document in set (0.0010 sec)

追加、插入和删除数组
使用arrayAppend()、arrayInsert()或arrayDelete()方法向数组字段添加元素,或在数组中插入或删除元素。下面的示例修改了flags集合,以启用对国际机场的跟踪。
第一个示例使用modify()和set()方法在所有文档中创建一个新的Airports字段。
在不指定搜索条件的情况下修改文档时要小心。此操作将修改集合中的所有文档。

 MySQL  localhost:33060+  world_x  JS > db.flags.modify("true").set("Airports", [])
Query OK, 3 items affected (0.0071 sec)

Rows matched: 3  Changed: 3  Warnings: 0

添加了Airports字段后,下一个示例将使用arrayAppend()方法向其中一个文档添加一个新机场。美元。下面示例中的Airports表示当前文档的Airports字段。

 MySQL  localhost:33060+  world_x  JS > db.flags.modify("Name = 'France'").arrayAppend("$.Airports", "ORY")
Query OK, 1 item affected (0.0069 sec)

Rows matched: 1  Changed: 1  Warnings: 0

使用db.flags.find”Name = ‘France'”)查看更改。

 MySQL  localhost:33060+  world_x  JS > db.flags.find("Name = 'France'")
{
    "GNP": 5000000,
    "_id": "FRA",
    "Name": "France",
    "Airports": [
        "ORY"
    ],
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 27,
        "LifeExpectancy": 79
    }
}
1 document in set (0.0013 sec)

要在数组的不同位置插入元素,可以使用arrayInsert()方法在路径表达式中指定要插入的索引。在这个例子中,索引是0,即数组的第一个元素。

 MySQL  localhost:33060+  world_x  JS > db.flags.modify("Name = 'France'").arrayInsert("$.Airports[0]", "CDG")
Query OK, 1 item affected (0.0078 sec)

Rows matched: 1  Changed: 1  Warnings: 0
 MySQL  localhost:33060+  world_x  JS > db.flags.find("Name = 'France'")
{
    "GNP": 5000000,
    "_id": "FRA",
    "Name": "France",
    "Airports": [
        "CDG",
        "ORY"
    ],
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 27,
        "LifeExpectancy": 79
    }
}
1 document in set (0.0010 sec)

要从数组中删除一个元素,必须将要删除的元素的索引传递给arrayDelete()方法。

 MySQL  localhost:33060+  world_x  JS > db.flags.modify("Name = 'France'").arrayDelete("$.Airports[1]")
Query OK, 1 item affected (0.0057 sec)

Rows matched: 1  Changed: 1  Warnings: 0
 MySQL  localhost:33060+  world_x  JS > db.flags.find("Name = 'France'")
{
    "GNP": 5000000,
    "_id": "FRA",
    "Name": "France",
    "Airports": [
        "CDG"
    ],
    "IndepYear": 1967,
    "geography": {
        "Region": "British Islands",
        "Continent": "Europe",
        "SurfaceArea": 193
    },
    "government": {
        "HeadOfState": "Michael Bates",
        "GovernmentForm": "Monarchy"
    },
    "demographics": {
        "Population": 27,
        "LifeExpectancy": 79
    }
}
1 document in set (0.0009 sec)

删除文档
可以使用remove()方法从数据库集合中删除部分或全部文档。X DevAPI为remove()方法提供了额外的方法,用于过滤和排序要删除的文档。

使用条件删除文档
下面的例子向remove()方法传递了一个搜索条件。所有符合条件的文档都将从countryinfo集合中删除。在这个例子中,有一个文档符合条件。

 MySQL  localhost:33060+  world_x  JS > db.flags.remove("_id = 'SEA'")
Query OK, 1 item affected (0.0159 sec)

删除第一个文档
要删除flags集合中的第一个文档,可使用limit()方法,将值设为1。

 MySQL  localhost:33060+  world_x  JS > db.flags.remove("true").limit(1)
Query OK, 1 item affected (0.0058 sec)

按顺序删除最后一个文档
下面的示例按国家名删除countryinfo集合中的最后一个文档。

 MySQL  localhost:33060+  world_x  JS > db.flags.remove("true").sort(["Name desc"]).limit(1)
Query OK, 1 item affected (0.02 sec)

删除集合中的所有文档
可以删除集合中的所有文档。为此,可以使用remove(”true”)方法,但不指定任何搜索条件。

 MySQL  localhost:33060+  world_x  JS > db.flags.remove("true");
Query OK, 1 item affected (0.0063 sec)

MySQL Shell

MySQL Shell是MySQL服务器的统一脚本接口。它支持JavaScript和Python脚本。JavaScript是默认的处理模式。在大多数情况下,你需要一个账户来连接到本地的MySQL服务器实例。

启动MySQL Shell
安装并启动MySQL server后,将MySQL Shell连接到server实例。默认情况下,MySQL Shell使用X协议连接。

在运行server实例的系统上,打开一个终端窗口,并使用以下命令启动MySQL Shell:

mysqlsh name@localhost/world_x
Creating a Session to 'root@localhost/world_x'
Enter password: ****

您可能需要指定适当的路径。

另外:
.name表示MySQL帐户的用户名。
.MySQL Shell提示您输入密码。
.这个会话的默认模式是world_x数据库。

mysql-js>提示符表明此会话的活动语言是JavaScript。

[root@localhost ~]# mysqlsh root@localhost/world_x
Please provide the password for 'root@localhost': ******
Save password for 'root@localhost'? [Y]es/[N]o/Ne[v]er (default No): N
MySQL Shell 8.0.41

Copyright (c) 2016, 2025, 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@localhost/world_x'
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 61 (X protocol)
Server version: 5.7.26-log Source distribution
Default schema `world_x` accessible through db.
 MySQL  localhost:33060+  world_x  JS > 

当不带host参数运行mysqlsh时,MySQL Shell会尝试连接运行在localhost接口上的33060端口上的服务器实例。

MySQL Shell支持如下的输入行编辑:
.左箭头键和右箭头键在当前输入行内水平移动。
.向上箭头键和向下箭头键在先前输入的行集合中向上和向下移动。
.退格键删除光标之前的字符,输入新的字符将在光标位置输入。
.Enter输入当前输入行。

获取MySQL Shell的帮助
在命令解释器的提示符下输入mysqlsh –help以获取命令行选项列表。

[root@localhost ~]# mysqlsh --help
MySQL Shell 8.0.41

Copyright (c) 2016, 2025, 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.

Usage: mysqlsh [OPTIONS] [URI]
       mysqlsh [OPTIONS] [URI] -f  [

在MySQL Shell提示符下输入\help,查看可用命令及其描述。

 MySQL  localhost:33060+  world_x  JS > \help
The Shell Help is organized in categories and topics. To get help for a
specific category or topic use: \? 

The  argument should be the name of a category or a topic.

The pattern is a filter to identify topics for which help is required, it can
use the following wildcards:

- ? matches any single character.
- * matches any character sequence.

The following are the main help categories:

 - AdminAPI       The AdminAPI is an API that enables configuring and managing
                  InnoDB Clusters, ReplicaSets, ClusterSets, among other
                  things.
 - Shell Commands Provides details about the available built-in shell commands.
 - ShellAPI       Contains information about the shell and util global objects
                  as well as the mysql module that enables executing SQL on
                  MySQL Servers.
 - SQL Syntax     Entry point to retrieve syntax help on SQL statements.
 - X DevAPI       Details the mysqlx module as well as the capabilities of the
                  X DevAPI which enable working with MySQL as a Document Store

The available topics include:

- The dba global object and the classes available at the AdminAPI.
- The mysqlx module and the classes available at the X DevAPI.
- The mysql module and the global objects and classes available at the
  ShellAPI.
- The functions and properties of the classes exposed by the APIs.
- The available shell commands.
- Any word that is part of an SQL statement.
- Command Line - invoking built-in shell functions without entering interactive
  mode.

SHELL COMMANDS

The shell commands allow executing specific operations including updating the
shell configuration.

The following shell commands are available:

 - \                   Start multi-line input when in SQL mode.
 - \connect    (\c)    Connects the shell to a MySQL server and assigns the
                       global session.
 - \disconnect         Disconnects the global session.
 - \edit       (\e)    Launch a system editor to edit a command to be executed.
 - \exit               Exits the MySQL Shell, same as \quit.
 - \help       (\?,\h) Prints help information about a specific topic.
 - \history            View and edit command line history.
 - \js                 Switches to JavaScript processing mode.
 - \nopager            Disables the current pager.
 - \nowarnings (\w)    Don't show warnings after every statement.
 - \option             Allows working with the available shell options.
 - \pager      (\P)    Sets the current pager.
 - \py                 Switches to Python processing mode.
 - \quit       (\q)    Exits the MySQL Shell.
 - \reconnect          Reconnects the global session.
 - \rehash             Refresh the autocompletion cache.
 - \show               Executes the given report with provided options and
                       arguments.
 - \source     (\.)    Loads and executes a script from a file.
 - \sql                Executes SQL statement or switches to SQL processing
                       mode when no statement is given.
 - \status     (\s)    Print information about the current global session.
 - \system     (\!)    Execute a system shell command.
 - \use        (\u)    Sets the active schema.
 - \warnings   (\W)    Show warnings after every statement.
 - \watch              Executes the given report with provided options and
                       arguments in a loop.

GLOBAL OBJECTS

The following modules and objects are ready for use when the shell starts:

 - db      Used to work with database schema objects.
 - dba     Used for InnoDB Cluster, ReplicaSet, and ClusterSet administration.
 - mysql   Support for connecting to MySQL servers using the classic MySQL
           protocol.
 - mysqlx  Used to work with X Protocol sessions using the MySQL X DevAPI.
 - os      Gives access to functions which allow to interact with the operating
           system.
 - plugins Plugin to manage MySQL Shell plugins
 - session Represents the currently open MySQL session.
 - shell   Gives access to general purpose functions and properties.
 - sys     Gives access to system specific parameters.
 - util    Global object that groups miscellaneous tools like upgrade checker
           and JSON import.

For additional information on these global objects use: .help()

EXAMPLES
\? AdminAPI
      Displays information about the AdminAPI.

\? \connect
      Displays usage details for the \connect command.

\? checkInstanceConfiguration
      Displays usage details for the dba.checkInstanceConfiguration function.

\? sql syntax
      Displays the main SQL help categories.
 MySQL  localhost:33060+  world_x  JS > 

请输入\help和命令名,获取MySQL Shell命令的详细帮助。例如,要查看\connect命令的帮助信息,输入:

 MySQL  localhost:33060+  world_x  JS > \help \connect
NAME
      \connect - Connects the shell to a MySQL server and assigns the global
      session.

SYNTAX
      \connect [] 
      \c [] 

DESCRIPTION
      TYPE is an optional parameter to specify the session type. Accepts the
      following values:

      - --mc, --mysql: create a classic MySQL protocol session (default port
        3306)
      - --mx, --mysqlx: create an X protocol session (default port 33060)
      - --ssh : create an SSH tunnel to use as a gateway for db
        connection. This requires that db port is specified in advance.

      If TYPE is omitted, automatic protocol detection is done, unless the
      protocol is given in the URI.

      URI format is: [user[:password]@]hostname[:port] and SSHURI format is:
      [user@]hostname[:port]

EXAMPLE
      \connect --mx root@localhost
            Creates a global session using the X protocol to the indicated URI.
 MySQL  localhost:33060+  world_x  JS > 

退出MySQL Shell
输入如下命令退出MySQL Shell:

 MySQL  localhost:33060+  world_x  JS > \quit

MySQL 安装Shell

安装MySQL Shell
这里将介绍如何下载、安装和启动MySQL Shell。MySQL Shell是一个交互式的JavaScript、Python或SQL接口,支持MySQL服务器的开发和管理。 MySQL Shell是一个可以单独安装的组件。

在Microsoft Windows上安装MySQL Shell
在Microsoft Windows上使用MSI Installer安装MySQL Shell,请执行以下操作:
1.从http://dev.mysql.com/downloads/ shell/下载Windows(x86, 64位),MSI安装包。
2.当出现提示时,单击Run。
3.按照安装向导中的步骤操作。

如果安装MySQL时没有启用X插件,然后决定安装X插件,或者如果安装MySQL时没有使用MySQL安装程序,请参见安装X插件。

Linux下安装MySQL Shell
对于支持的Linux发行版,在Linux上安装MySQL Shell最简单的方法是使用MySQL APT存储库或MySQL Yum存储库。对于不使用MySQL存储库的系统 ,也可以直接下载并安装MySQL Shell。

使用MySQL APT存储库安装MySQL Shell
对于MySQL APT库支持的Linux发行版,请遵循以下路径之一:
.如果你的系统还没有MySQL APT存储库作为软件存储库,请执行以下操作:

.请按照“添加MySQL APT存储库”中的步骤进行操作,需要特别注意以下事项:
.在安装配置包的过程中,当在对话框中被要求配置存储库时,请确保选择MySQL 5.7(这是默认选项)作为你想要的发行版系列,并启用MySQL Preview Packages组件。

.确保您没有跳过更新MySQL APT存储库的包信息的步骤:

sudo apt-get update

.用这个命令安装MySQL Shell:

sudo apt-get install mysql-shell

.如果你的系统上已经有MySQL APT存储库作为软件存储库,请执行以下操作:
.更新MySQL APT仓库的包信息:

sudo apt-get update

.使用以下命令更新MySQL APT存储库配置包:

 sudo apt-get install mysql-apt-config

当在对话框中被要求配置存储库时,请确保选择MySQL 5.7(这是默认选项)作为你想要的发行版系列,并启用MySQL Preview Packages组件。

.用这个命令安装MySQL Shell:
用这个命令安装MySQL Shell:

使用MySQL Yum存储库安装MySQL Shell
对于MySQL Yum支持的Linux发行版,按照以下步骤安装MySQL Shell:
.执行下列操作之一:
.如果您已经将MySQL Yum存储库作为系统上的软件存储库,并且该存储库配置了新的发布包mysql57-community-release,则跳过下一步(“启 用MySQL工具预览子存储库……”)。

.如果你已经将MySQL Yum存储库作为软件存储库安装在你的系统上,但已经配置了旧的发布包MySQL -community-release,安装MySQL Shell最 简单的方法是先用新的mysql57- community-release包重新配置MySQL Yum存储库。为此,您需要先删除旧的发行版包,使用以下命令:

 sudo yum remove mysql-community-release

对于启用了dnf的系统,可以这样做:

 sudo dnf erase mysql-community-release

然后,按照添加MySQL Yum存储库的步骤安装新的发布包mysql57-community-release。

.如果系统中还没有MySQL Yum存储库作为软件存储库,请按照添加MySQL Yum存储库的步骤操作。

.启用MySQL Tools预览子存储库。你可以手动编辑/etc/yum.repos.d/mysql-community.repo文件。这是文件中子仓库默认条目的一个例子(文 件中的baseurl条目可能看起来不同,这取决于你的Linux发行版):

[mysql-tools-preview]
name=MySQL Tools Preview
baseurl=http://repo.mysql.com/yum/mysql-tools-preview/el/6/$basearch/
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql

将条目enabled=0更改为enabled=1以启用子存储库。

.用这个命令安装MySQL Shell:

sudo yum install mysql-shell

对于启用dnf的系统,可以这样做:

sudo dnf install mysql-shell

从MySQL Developer专区直接下载安装MySQL Shell
MySQL Shell的RPM、Debian和源码包也可以从download MySQL Shell下载。

MySQL 安装X插件

MySQL要安装内置的X Plugin,有以下三种方式:
.使用MySQL Windows安装程序
a.启动MySQL安装程序。MySQL安装程序仪表板打开。
b.单击MySQL Server的Reconfigure快速操作。使用“下一步”和“返回”配置以下内容:
.在“帐户和角色”中确认当前root帐户的密码。
.在“插件和扩展”中,勾选“启用X协议/MySQL作为文档存储”复选框。MySQL安装程序提供一个默认端口号,并打开防火墙端口供网络访问。
.在“应用服务器配置”中单击“执行”。
c.安装MySQL Shell。

.使用MySQL Shell
a.安装MySQL Shell

[root@localhost ~]# rpm -ivh mysql-shell-8.0.41-1.el7.x86_64.rpm

b.打开终端窗口(Windows上的命令提示符),导航到MySQL二进制文件位置(例如,Linux上的/usr/bin/)。

c.执行如下命令:

[root@localhost ~]# mysqlsh -u root -h 10.18.10.20 -P 3306 --classic --dba enableXProtocol
WARNING: The --classic option was deprecated, please use --mysql instead. (Option has been processed as --mysql).
Please provide the password for 'root@10.18.10.20:3306': ******
Save password for 'root@10.18.10.20 :3306'? [Y]es/[N]o/Ne[v]er (default No): N
enableXProtocol: Installing plugin mysqlx...
enableXProtocol: Verifying plugin is active...
enableXProtocol: successfully installed the X protocol plugin!

[root@localhost ~]# netstat -ltnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:24903           0.0.0.0:*               LISTEN      30883/mysqld
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      8407/mysqld
tcp        0      0 0.0.0.0:3307            0.0.0.0:*               LISTEN      8444/mysqld
tcp        0      0 0.0.0.0:3308            0.0.0.0:*               LISTEN      30883/mysqld
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1584/sshd
tcp        0      0 0.0.0.0:24901           0.0.0.0:*               LISTEN      8407/mysqld
tcp        0      0 0.0.0.0:24902           0.0.0.0:*               LISTEN      8444/mysqld
tcp6       0      0 :::22                   :::*                    LISTEN      1584/sshd
tcp6       0      0 :::33060                :::*                    LISTEN      8407/mysqld

33060端口就是X插件所占用的端口。
.使用MySQL客户端程序:
a.打开终端窗口(Windows上的命令提示符),导航到MySQL二进制文件位置(例如,Linux上的/usr/bin/)。

b.调用mysql命令行客户端:

[root@localhost ~]# mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 45
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

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.

c.执行以下语句:

mysql> INSTALL PLUGIN mysqlx SONAME 'mysqlx.so';
Query OK, 0 rows affected (0.14 sec)

mysql>

[mysql@localhost mysql]$ netstat -ltnp
(No info could be read for "-p": geteuid()=27 but you should be root.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      -
tcp6       0      0 :::3306                 :::*                    LISTEN      -
tcp6       0      0 :::22                   :::*                    LISTEN      -
tcp6       0      0 ::1:631                 :::*                    LISTEN      -
tcp6       0      0 :::33060                :::*                    LISTEN      -

33060端口就是X插件所占用的端口。
d.安装MySQL Shell。

[root@localhost ~]# rpm -ivh mysql-shell-8.0.41-1.el7.x86_64.rpm

3.验证X Plugin是否已经安装。
当X Plugin安装正确时,当您使用以下命令之一查询服务器上的活动插件时,它会显示在列表中:
.MySQL Shell命令:

[root@localhost ~]# mysqlsh -u root -h 10.18.10.20  -P 3306 --sqlc -e "show plugins"
Please provide the password for 'root@10.18.10.20 :3306': ******
Save password for 'root@10.18.10.20 :3306'? [Y]es/[N]o/Ne[v]er (default No): N
Name    Status  Type    Library License
binlog  ACTIVE  STORAGE ENGINE  NULL    GPL
mysql_native_password   ACTIVE  AUTHENTICATION  NULL    GPL
sha256_password ACTIVE  AUTHENTICATION  NULL    GPL
CSV     ACTIVE  STORAGE ENGINE  NULL    GPL
MEMORY  ACTIVE  STORAGE ENGINE  NULL    GPL
InnoDB  ACTIVE  STORAGE ENGINE  NULL    GPL
INNODB_TRX      ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_LOCKS    ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_LOCK_WAITS       ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_CMP      ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_CMP_RESET        ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_CMPMEM   ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_CMPMEM_RESET     ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_CMP_PER_INDEX    ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_CMP_PER_INDEX_RESET      ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_BUFFER_PAGE      ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_BUFFER_PAGE_LRU  ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_BUFFER_POOL_STATS        ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_TEMP_TABLE_INFO  ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_METRICS  ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_FT_DEFAULT_STOPWORD      ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_FT_DELETED       ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_FT_BEING_DELETED ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_FT_CONFIG        ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_FT_INDEX_CACHE   ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_FT_INDEX_TABLE   ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_SYS_TABLES       ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_SYS_TABLESTATS   ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_SYS_INDEXES      ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_SYS_COLUMNS      ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_SYS_FIELDS       ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_SYS_FOREIGN      ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_SYS_FOREIGN_COLS ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_SYS_TABLESPACES  ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_SYS_DATAFILES    ACTIVE  INFORMATION SCHEMA      NULL    GPL
INNODB_SYS_VIRTUAL      ACTIVE  INFORMATION SCHEMA      NULL    GPL
MyISAM  ACTIVE  STORAGE ENGINE  NULL    GPL
MRG_MYISAM      ACTIVE  STORAGE ENGINE  NULL    GPL
PERFORMANCE_SCHEMA      ACTIVE  STORAGE ENGINE  NULL    GPL
ARCHIVE ACTIVE  STORAGE ENGINE  NULL    GPL
BLACKHOLE       ACTIVE  STORAGE ENGINE  NULL    GPL
FEDERATED       DISABLED        STORAGE ENGINE  NULL    GPL
partition       ACTIVE  STORAGE ENGINE  NULL    GPL
ngram   ACTIVE  FTPARSER        NULL    GPL
group_replication       ACTIVE  GROUP REPLICATION       group_replication.so    GPL
mysqlx  ACTIVE  DAEMON  mysqlx.so       GPL

.MySQL Client程序命令:

[root@localhost ~]# mysql -h 10.18.10.20  -P 3306 -u root -p -e "show plugins"
Enter password:
+----------------------------+----------+--------------------+----------------------+---------+
| Name                       | Status   | Type               | Library              | License |
+----------------------------+----------+--------------------+----------------------+---------+
| binlog                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| mysql_native_password      | ACTIVE   | AUTHENTICATION     | NULL                 | GPL     |
| sha256_password            | ACTIVE   | AUTHENTICATION     | NULL                 | GPL     |
| CSV                        | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| MEMORY                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| InnoDB                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| INNODB_TRX                 | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_LOCKS               | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_LOCK_WAITS          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP                 | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP_RESET           | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMPMEM              | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMPMEM_RESET        | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP_PER_INDEX       | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP_PER_INDEX_RESET | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_BUFFER_PAGE         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_BUFFER_PAGE_LRU     | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_BUFFER_POOL_STATS   | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_TEMP_TABLE_INFO     | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_METRICS             | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_DEFAULT_STOPWORD | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_DELETED          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_BEING_DELETED    | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_CONFIG           | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_INDEX_CACHE      | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_INDEX_TABLE      | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_TABLES          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_TABLESTATS      | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_INDEXES         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_COLUMNS         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_FIELDS          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_FOREIGN         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_FOREIGN_COLS    | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_TABLESPACES     | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_DATAFILES       | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_VIRTUAL         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| MyISAM                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| MRG_MYISAM                 | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| PERFORMANCE_SCHEMA         | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| ARCHIVE                    | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| BLACKHOLE                  | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| FEDERATED                  | DISABLED | STORAGE ENGINE     | NULL                 | GPL     |
| partition                  | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| ngram                      | ACTIVE   | FTPARSER           | NULL                 | GPL     |
| group_replication          | ACTIVE   | GROUP REPLICATION  | group_replication.so | GPL     |
| mysqlx                     | ACTIVE   | DAEMON             | mysqlx.so            | GPL     |
+----------------------------+----------+--------------------+----------------------+---------+

mysqlxsys@localhost用户帐号
安装X插件会创建一个mysqlxsys@localhost用户帐户。如果由于某种原因,创建用户帐户失败,X插件安装也会失败。下面是关于 mysqlxsys@localhost用户帐户的用途以及在创建失败时该怎么办的解释。

X 插件的安装过程使用 MySQL root账户为 `mysqlxsys@localhost` 用户创建一个内部账户。`mysqlxsys@localhost` 账户由 X 插件用于外部 用户对 MySQL 账户系统的身份验证,以及在特权用户请求时终止会话。`mysqlxsys@localhost` 账户创建时处于锁定状态,因此外部用户无法 使用它登录。如果由于某种原因 MySQL root账户不可用,在启动 X 插件安装之前,您必须在 `mysql` 命令行客户端中执行以下语句手动创建 `mysqlxsys@localhost` 用户:

mysql> CREATE USER IF NOT EXISTS mysqlxsys@localhost IDENTIFIED WITH mysql_native_password AS '123456' ACCOUNT LOCK;
Query OK, 0 rows affected (0.01 sec)

mysql> GRANT SELECT ON mysql.user TO mysqlxsys@localhost;
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT SUPER ON *.* TO mysqlxsys@localhost;
Query OK, 0 rows affected (0.01 sec)

MySQL Shell全局变量

MySQL Shell全局变量
MySQL Shell保留一些变量作为全局变量,这些变量被分配给脚本中常用的对象。本节描述可用的全局变量,并提供使用它们的示例。全局变量是:
.session 表示全局会话(如果已建立)
.db 表示已定义的模式,例如由URI定义的模式。

MySQL Shell为与使用全局变量相关的常见情况提供交互式错误解决方案。例如:
.试图使用未定义的session全局变量
.试图使用session检索不存在的模式
.试图使用未定义的db全局变量

未定义的全局会话
全局session变量在全局会话建立时设置。建立全局会话后,在MySQL Shell中使用session语句显示会话类型及其URI:

mysql-js> session

mysql-js>

如果没有建立全局会话,MySQL Shell显示如下信息:

mysql-js> session

mysql-js>

如果在没有建立全局会话的情况下试图使用session变量,则会启动交互式错误解析,并提示您提供建立全局会话所需的信息。如果会话成功建立,它会被赋值给session变量。提示如下:
.初始提示解释说没有建立全局会话,并询问是否应该建立全局会话。
.如果选择设置全局会话,则请求会话类型
.请求存储的会话的URI或别名
.如果需要,则需要密码

例如:

mysql-js> session.uri
The global session is not set, do you want to establish a session? [y/N]: y
Please specify the session type:
1) X
2) Node
3) Classic
Type: 2
Please specify the MySQL server URI (or $slias): root@localhost
Enter password:*******
root@localhost:33060
mysql-js>

未定义db变量
在建立全局会话并配置默认模式时,将设置global db变量。例如,使用root@localhost/sakila这样的URI建立一个全局会话,连接到localhost上的MySQL服务器,端口为33060。作为root用户,将模式sakila分配给全局变量db。定义好模式后,在MySQL Shell提示符下执行db命令会打印出模式名,如下所示:

mysql-js> db

mysql-js>

如果未建立全局会话,则显示如下信息:

mysql-js> db

mysql-js>

如果在没有建立全局会话的情况下尝试使用db变量,则会显示以下错误:

mysql-js> db.getCollections()
LogicError: The db variable is not set, establish a global session first.
at (shell):1:2
in db.getCollections()

如果已经建立了全局会话,但您试图使用未定义的数据库,则开始交互式错误解决,并提示您通过提供模式名称来定义活动模式。如果成功,则将db变量设置为定义的模式。例如:

mysql-js> db.getCollections()
The db variable is not set, do you want to set the active schema? [y/N]:y
Please specify the schema:world_x
[

]
mysql-js> db

mysql-js>

检索一个不存在的模式
如果尝试使用会话检索不存在的模式,交互式错误解决方案提供了创建模式的选项。

mysql-js> var mySchema = session.getSchema('my_test')
The schema my_test does not exist, do you want to create it? [y/N]: y
mysql-js> mySchema

mysql-js>

在所有情况下,如果您不提供解决每种情况所需的信息,则在未定义的变量上执行请求的语句将显示正确的结果。

MySQL Shell连接

MySQL Shell连接
MySQL Shell可以配置为在启动应用程序时使用命令选项连接到MySQL服务器,或者在MySQL Shell内部使用\connect命令连接到MySQL服务器。您 想要连接的MySQL服务器的地址可以使用单独的参数来指定,例如用户,主机名和端口,或者使用统一资源标识符(URI),格式为 user@host:port/schema,例如mike@myserver:33060/testDB。以下部分描述这些连接方法。

无论选择哪种方法连接,了解MySQL Shell如何处理密码都是很重要的。默认情况下,假定连接需要密码。在登录提示时要求输入密码。要指定 无密码帐户,请使用——password选项而不指定密码,或者在URI中的用户后面使用:而不指定密码。

如果您没有为连接指定参数,则使用以下默认值:
.user默认为当前系统用户名
.host默认为localhost
.port在使用X Session时默认为X Plugin端口33060,在使用Classic Session时默认为端口3306

使用X协议的MySQL Shell连接总是使用TCP,不支持使用Unix套接字。MySQL当满足以下条件时,Shell连接使用MySQL协议默认使用Unix套接字:
.–port未指定
.–host未指定或者为localhost
.–socket为到套接字提供了路径
.–classic被指定
如果指定了–host,但它不是localhost,则建立TCP连接。在这种情况下,如果没有指定–port,则使用默认值3306。如果满足套接字连接的条 件,但没有指定–socket,则使用默认套接字

使用URI字符串进行连接
通过使用–uri命令选项以字符串格式传递连接数据,可以配置MySQL Shell连接到的MySQL服务器。

使用以下格式:

[dbuser[:[dbpassword]]@]host[:port][/schema]

这些选项的说明:
.dbuser:指定认证过程中使用的MySQL用户帐号
.dbpassword:指定要用于身份验证过程的用户密码,不建议将密码存储在URI中。
.host:指定会话对象所连接的主机。如果未指定,则默认使用localhost。
.port:指定目标MySQL服务器正在监听连接的端口。如果没有指定,33060默认用于启用X协议的会话,而3306是传统MySQL协议会话的默认值。
.schema:指定会话建立时要设置为默认的数据库

如果没有使用URI指定密码(建议这样做),则会提示输入密码。下面的示例展示了如何使用这些命令选项:
.连接到端口33065的 Node 会话

[root@localhost ~]# mysqlsh --uri root@10.13.13.25:33065 --node
WARNING: The --node option was deprecated, please use --mysqlx instead. (Option has been processed as --mysqlx).
Please provide the password for 'root@localhost:33065': ******
MySQL Shell 8.0.41

Copyright (c) 2016, 2025, 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 an X protocol session to 'root@localhost:33065'
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 31
Server version: 5.7.26-log Source distribution
No default schema selected; type \use  to set one.
 MySQL  10.13.13.25:33065  JS >

.连接一个经典会话。

[root@localhost ~]# mysqlsh --uri root@10.13.13.25 --classic
WARNING: The --classic option was deprecated, please use --mysql instead. (Option has been processed as --mysql).
Please provide the password for 'root@10.13.13.25': ******
Save password for 'root@10.13.13.25'? [Y]es/[N]o/Ne[v]er (default No): N
MySQL Shell 8.0.41

Copyright (c) 2016, 2025, 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@10.13.13.25'
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 32
Server version: 5.7.26-log Source distribution
No default schema selected; type \use  to set one.
 MySQL  10.13.13.25:3306  JS >

虽然不建议使用无密码帐户,但也可以在用户名后使用“:”指定不需要密码的用户,例如:

[root@localhost ~]#mysqlsh --uri user:@localhost

使用单个参数进行连接
除了使用URI指定连接参数之外,还可以为每个值使用单独的参数定义连接数据
使用以下参数:
.–dbuser (-u) value
.–dbpassword value
.–host (-h) value
.–port (-P) value
.–schema (-D) value
.–password (-p)
.–socket (-S)

前5个参数匹配URI格式中使用的令牌,参数–password表示用户连接时不需要密码,为保持一致性,部分参数支持以下别名:
.–user相当于–dbuser
.–password 相当于 –dbpassword
.–database 相当于 –schema

当以多种方式指定参数时,适用以下规则:
.如果多次指定参数,则使用最后一次出现的值
.如果同时指定了各个连接参数和–uri,那么–uri的值将被视为基础,而各个参数的值会覆盖基础URI中的特定组件。

尝试在端口33065上与指定用户建立XSession。

[root@localhost ~]# mysqlsh -u root -h 10.13.13.25 -P 33065
Please provide the password for 'root@10.13.13.25:33065': ******
MySQL Shell 8.0.41

Copyright (c) 2016, 2025, 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@10.13.13.25:33065'
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 34
Server version: 5.7.26-log Source distribution
No default schema selected; type \use  to set one.
 MySQL  10.13.13.25:33065  JS >

尝试与指定用户建立经典会话

[root@localhost ~]# mysqlsh -u root -h 10.13.13.25 --classic
WARNING: The --classic option was deprecated, please use --mysql instead. (Option has been processed as --mysql).
Please provide the password for 'root@10.13.13.25': ******
Save password for 'root@10.13.13.25'? [Y]es/[N]o/Ne[v]er (default No): N
MySQL Shell 8.0.41

Copyright (c) 2016, 2025, 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@10.13.13.25'
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 35
Server version: 5.7.26-log Source distribution
No default schema selected; type \use  to set one.
 MySQL  10.13.13.25:3306  JS >

尝试与指定用户建立节点会话

[root@localhost ~]# mysqlsh --node -u root -h 10.13.13.25
WARNING: The --node option was deprecated, please use --mysqlx instead. (Option has been processed as --mysqlx).
Please provide the password for 'root@10.13.13.25': ******
MySQL Shell 8.0.41

Copyright (c) 2016, 2025, 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 an X protocol session to 'root@10.13.13.25:33060'
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 36
Server version: 5.7.26-log Source distribution
No default schema selected; type \use  to set one.
 MySQL  10.13.13.25:33060  JS >

MySQL 5.7 组复制配置实践

MySQL组复制的配置实践
第一步是部署三个MySQL Server实例。Group Replication是MySQL Server 5.7.17及更新版本提供的内置MySQL插件。
下面的过程使用一台物理机器,因此每个MySQL服务器实例都需要一个特定的数据目录。在名为mysqldata的目录中创建数据目录,并对每个目录进行初始化。
创建三个数据目录

[mysql@localhost mysqldata]$ mkdir mysql1
[mysql@localhost mysqldata]$ mkdir mysql2
[mysql@localhost mysqldata]$ mkdir mysql3
[mysql@localhost mysqldata]$ ll
total 0
drwxr-xr-x. 2 mysql mysql 6 Jan 16 08:54 mysql1
drwxr-xr-x. 2 mysql mysql 6 Jan 16 08:55 mysql2
drwxr-xr-x. 2 mysql mysql 6 Jan 16 08:55 mysql3

创建三个实例的参数文件

[mysql@localhost mysql]# vi mysql1.cnf
[mysqld]
basedir=/mysqlsoft/mysql
datadir=/mysqldata/mysql1
bind-address=0.0.0.0
user=mysql
port=3306
log-error=/mysqldata/mysql1/mysql.err
pid-file=/mysqldata/mysql1/mysqld.pid
socket = /mysqldata/mysql1/mysql.sock
character-set-server=utf8mb4
default-storage-engine=INNODB

[mysql@localhost mysql]$ vi mysql2.cnf
[mysqld]
basedir=/mysqlsoft/mysql
datadir=/mysqldata/mysql2
bind-address=0.0.0.0
user=mysql
port=3307
log-error=/mysqldata/mysql2/mysql.err
pid-file=/mysqldata/mysql2/mysqld.pid
socket = /mysqldata/mysql2/mysql.sock
character-set-server=utf8mb4
default-storage-engine=INNODB


[mysql@localhost mysql]$ vi mysql3.cnf
[mysqld]
basedir=/mysqlsoft/mysql
datadir=/mysqldata/mysql3
bind-address=0.0.0.0
user=mysql
port=3308
log-error=/mysqldata/mysql3/mysql.err
pid-file=/mysqldata/mysql3/mysqld.pid
socket = /mysqldata/mysql3/mysql.sock
character-set-server=utf8mb4
default-storage-engine=INNODB

初始化三个实例

[root@localhost ~]# cd /mysqlsoft/mysql/bin
[root@localhost bin]# ./mysqld  --defaults-file=/mysqlsoft/mysql/mysql1.cnf --initialize -basedir=/mysqlsoft/mysql --

datadir=/mysqldata/mysql1 --user=mysql
[root@localhost bin]# ./mysqld  --defaults-file=/mysqlsoft/mysql/mysql2.cnf --initialize -basedir=/mysqlsoft/mysql --

datadir=/mysqldata/mysql2 --user=mysql
[root@localhost bin]# ./mysqld  --defaults-file=/mysqlsoft/mysql/mysql3.cnf --initialize -basedir=/mysqlsoft/mysql --

datadir=/mysqldata/mysql3 --user=mysql

[mysql@localhost mysql1]$ cat mysql.err
2025-01-16T02:45:38.125723Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --

explicit_defaults_for_timestamp server option (see documentation for more details).
2025-01-16T02:45:38.126190Z 0 [ERROR] Can't find error-message file 'asedir=/mysqlsoft/mysql/share/errmsg.sys'. Check error-

message file location and 'lc-messages-dir' configuration directive.
2025-01-16T02:45:38.535031Z 0 [Warning] InnoDB: New log files created, LSN=45790
2025-01-16T02:45:38.597593Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
2025-01-16T02:45:38.658289Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this 

server has been started. Generating a new UUID: f81625c0-d3b3-11ef-9c8d-005056a390e6.
2025-01-16T02:45:38.659975Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
2025-01-16T02:45:38.661884Z 1 [Note] A temporary password is generated for root@localhost: LplkX((&j1&u

[mysql@localhost mysql2]$ cat mysql.err
2025-01-16T02:45:51.143320Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --

explicit_defaults_for_timestamp server option (see documentation for more details).
2025-01-16T02:45:51.143570Z 0 [ERROR] Can't find error-message file 'asedir=/mysqlsoft/mysql/share/errmsg.sys'. Check error-

message file location and 'lc-messages-dir' configuration directive.
2025-01-16T02:45:51.439385Z 0 [Warning] InnoDB: New log files created, LSN=45790
2025-01-16T02:45:51.502171Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
2025-01-16T02:45:51.561336Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this 

server has been started. Generating a new UUID: ffc6ff15-d3b3-11ef-9e2d-005056a390e6.
2025-01-16T02:45:51.562821Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
2025-01-16T02:45:51.564054Z 1 [Note] A temporary password is generated for root@localhost: OM,#w?fll2iT


[mysql@localhost mysql3]$ cat mysql.err
2025-01-16T02:46:03.815721Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --

explicit_defaults_for_timestamp server option (see documentation for more details).
2025-01-16T02:46:03.815972Z 0 [ERROR] Can't find error-message file 'asedir=/mysqlsoft/mysql/share/errmsg.sys'. Check error-

message file location and 'lc-messages-dir' configuration directive.
2025-01-16T02:46:04.113214Z 0 [Warning] InnoDB: New log files created, LSN=45790
2025-01-16T02:46:04.171088Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
2025-01-16T02:46:04.230517Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this 

server has been started. Generating a new UUID: 07542900-d3b4-11ef-a088-005056a390e6.
2025-01-16T02:46:04.232171Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
2025-01-16T02:46:04.233327Z 1 [Note] A temporary password is generated for root@localhost: wlh%+FHw(7Sk

如果想服务能够部署自动支持安全连接,使用mysql_ssl_rsa_setup工具来创建缺省SSL与RSA文件

[root@localhost bin]# ./mysql_ssl_rsa_setup --datadir=/mysqldata/mysql1
Generating a 2048 bit RSA private key
...........+++
................................+++
writing new private key to 'ca-key.pem'
-----
Generating a 2048 bit RSA private key
.+++
.......................+++
writing new private key to 'server-key.pem'
-----
Generating a 2048 bit RSA private key
...............................+++
........................+++
writing new private key to 'client-key.pem'
-----
[root@localhost bin]# ./mysql_ssl_rsa_setup --datadir=/mysqldata/mysql2
Generating a 2048 bit RSA private key
........................+++
........................................................+++
writing new private key to 'ca-key.pem'
-----
Generating a 2048 bit RSA private key
................................+++
......................+++
writing new private key to 'server-key.pem'
-----
Generating a 2048 bit RSA private key
........................+++
......................................................................+++
writing new private key to 'client-key.pem'
-----
[root@localhost bin]# ./mysql_ssl_rsa_setup --datadir=/mysqldata/mysql3
Generating a 2048 bit RSA private key
........................................................................................................+++
...................+++
writing new private key to 'ca-key.pem'
-----
Generating a 2048 bit RSA private key
..................................+++
.......................................................................+++
writing new private key to 'server-key.pem'
-----
Generating a 2048 bit RSA private key
..............................................+++
........................+++
writing new private key to 'client-key.pem'
-----

配置启动脚本

[mysql@localhost mysql]$ cat my.cnf
[mysqld_multi]
mysqld=/mysqlsoft/mysql/bin/mysqld_safe
mysqladmin =/mysqlsoft/mysql/bin/mysqladmin
log =/mysqlsoft/mysql/mysqld_multi.log

[mysqld1]
basedir=/mysqlsoft/mysql
datadir=/mysqldata/mysql1
bind-address=0.0.0.0
user=mysql
port=3306
log-error=/mysqldata/mysql1/mysql.err
pid-file=/mysqldata/mysql1/mysqld.pid
socket = /mysqldata/mysql1/mysql.sock
character-set-server=utf8mb4
default-storage-engine=INNODB
explicit_defaults_for_timestamp = true


[mysqld2]
basedir=/mysqlsoft/mysql
datadir=/mysqldata/mysql2
bind-address=0.0.0.0
user=mysql
port=3307
log-error=/mysqldata/mysql2/mysql.err
pid-file=/mysqldata/mysql2/mysqld.pid
socket = /mysqldata/mysql2/mysql.sock
character-set-server=utf8mb4
default-storage-engine=INNODB
explicit_defaults_for_timestamp = true


[mysqld3]
basedir=/mysqlsoft/mysql
datadir=/mysqldata/mysql3
bind-address=0.0.0.0
user=mysql
port=3308
log-error=/mysqldata/mysql3/mysql.err
pid-file=/mysqldata/mysql3/mysqld.pid
socket = /mysqldata/mysql3/mysql.sock
character-set-server=utf8mb4
default-storage-engine=INNODB
explicit_defaults_for_timestamp = true

[mysql@localhost mysql]$ mysqld_multi start 1,2,3


[mysql@localhost mysql]$ tail -f mysqld_multi.log 
mysqld_multi log file version 2.16; run: Thu Jan 16 11:12:08 2025



Starting MySQL servers

2025-01-16T03:17:42.956897Z mysqld_safe Logging to '/mysqldata/mysql1/mysql.err'.
2025-01-16T03:17:42.968830Z mysqld_safe Logging to '/mysqldata/mysql3/mysql.err'.
2025-01-16T03:17:42.971621Z mysqld_safe Logging to '/mysqldata/mysql2/mysql.err'.
2025-01-16T03:17:42.978298Z mysqld_safe Logging to '/mysqldata/mysql1/mysql.err'.
2025-01-16T03:17:42.984997Z mysqld_safe Logging to '/mysqldata/mysql2/mysql.err'.
2025-01-16T03:17:42.999744Z mysqld_safe Logging to '/mysqldata/mysql3/mysql.err'.
2025-01-16T03:17:43.014252Z mysqld_safe A mysqld process already exists
2025-01-16T03:17:43.026350Z mysqld_safe Starting mysqld daemon with databases from /mysqldata/mysql3
2025-01-16T03:17:43.026973Z mysqld_safe Starting mysqld daemon with databases from /mysqldata/mysql2
2025-01-16T03:17:43.032460Z mysqld_safe A mysqld process already exists
2025-01-16T03:17:43.042893Z mysqld_safe Starting mysqld daemon with databases from /mysqldata/mysql2
2025-01-16T03:17:43.058374Z mysqld_safe Starting mysqld daemon with databases from /mysqldata/mysql3

组复制服务器设置
要安装和使用组复制插件,您必须正确配置MySQL服务器实例。建议将配置存储在实例的配置文件中。下面为mysql1服务器配置。

[mysql@localhost mysql]$ cat mysql1.cnf
[mysqld]
basedir=/mysqlsoft/mysql
datadir=/mysqldata/mysql1
bind-address=0.0.0.0
user=mysql
port=3306
log-error=/mysqldata/mysql1/mysql.err
pid-file=/mysqldata/mysql1/mysqld.pid
socket = /mysqldata/mysql1/mysql.sock
character-set-server=utf8mb4
default-storage-engine=INNODB

这些设置将MySQL服务器配置为使用前面创建的数据目录,以及服务器应该打开哪个端口并开始侦听传入的连接。

复制框架
以下设置根据“MySQL Group replication”的要求配置复制。

server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW

这些设置将服务器配置为使用唯一标识符1,以启用全局事务标识符,并将复制元数据存储在系统表而不是文件中。此外,它指示服务器打开二进制日志记录,使用基于行的格式并禁用二进制日志事件校验和。

组复制设置
此时,mysql1.cnf文件确保配置了服务器,并指示在给定配置下实例化复制基础结构。以下部分为服务器配置组复制设置。

transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="2366d798-4dc1-421a-a9de-3c825bfada7d"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address= "127.0.0.1:24901"
loose-group_replication_group_seeds= "127.0.0.1:24901,127.0.0.1:24902,127.0.0.1:24903"
loose-group_replication_bootstrap_group= off

上面用于group_replication变量的loose前缀指示,如果在服务器启动时没有加载Group Replication插件,则服务器继续启动。
.第1行指示服务器,对于每个事务,它必须收集写集,并使用XXHASH64散列算法将其编码为散列。

.第2行告诉插件它要加入或创建的组的名称为“2366d798-4dc1-421a-a9de-3c825bfada7d”。

.第3行指示插件在服务器启动时不要自动启动操作。

.第4行告诉插件使用IP地址127.0.0.1或localhost和端口24901来处理来自组中其他成员的传入连接。
服务器在这个端口上监听成员到成员的连接。此端口绝对不能用于用户应用程序,必须在运行组复制时为组的不同成员之间的通信保留该端口。

group_replication_local_address配置的本地地址必须对所有组成员都可访问。例如,如果每个服务器实例都在不同的机器上,则使用该机器的IP和端口,例如10.0.0.1:33061。group_replication_local_address的推荐端口是33061,但是在本教程中,我们使用在一台机器上运行的三个服务器实例,因此使用端口24901到24903。

.第5行告诉插件,如果需要加入组,应该联系这些主机和端口上的以下成员。这些是种子成员,当该成员想要连接到组时使用。在加入时,服务器首先与其中一个(种子)联系,然后要求组重新配置以允许加入服务器被组接受。请注意,此选项不需要列出组中的所有成员,而是在此服务器希望加入组时应该联系的服务器列表。

启动组的服务器不使用此选项,因为它是初始服务器,因此它负责引导组。第二个服务器加入要求组中唯一的成员加入,然后扩展组。第三个服务器加入可以请求这两个服务器中的任何一个加入,然后这个群组再次扩展。后续服务器在加入时重复此过程。

当同时加入多个服务器时,确保它们指向已经在组中的种子成员。不要使用正在加入组的成员作为种子,因为他们在联系时可能还不在组中。

最好的做法是先启动bootstrap成员,然后让它创建组。然后将其作为其他加入的成员的种子成员。这确保在加入其他成员时形成一个组。

不支持创建群组并同时加入多个成员。它可能会起作用,但很可能是操作竞争,然后加入组的行为以错误或超时告终。

.第6行指示插件是否启动组
此选项在任何时候都只能在一个服务器实例上使用,通常是在您第一次引导组时(或者在整个组被关闭并重新启动的情况下)。如果您多次引导组,例如当多个服务器实例设置了此选项时,那么它们可能会创建一个人工分裂的大脑场景,其中存在两个具有相同名称的不同组。在第一个服务器实例联机后禁用此选项。

组中所有服务器的配置非常相似。需要修改每个服务器的具体信息(例如server_id、datadir、group_replication_local_address)。

用户凭证
“组复制”通过异步复制协议实现分布式恢复,在组成员加入组之前先同步组成员。分布式恢复进程依赖于一个名为group_replication_recovery的复制区域通道,该区域通道用于在组成员之间传输事务。因此,需要设置具有相应权限的复制用户,以便Group replication建立成员间直接恢复复制通道。

[mysql@localhost mysql]$ mysqld --defaults-file=/mysqlsoft/mysql/mysql1.cnf &

创建一个具有REPLICATION-SLAVE权限的MySQL用户。不应该在二进制日志中捕获此过程,以避免将更改传播到其他服务器实例。在下面的示例中,显示了用户rpl_user和密码password。在配置服务器时,请使用合适的用户名和密码。连接到服务器mysql1,发出以下语句:

[root@localhost bin]# mysql -h 10.138.130.250 -P 3306 -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

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> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE USER rpl_user@'%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)

mysql> SET SQL_LOG_BIN=1;
Query OK, 0 rows affected (0.00 sec)

按照上述方式配置用户后,使用CHANGE MASTER TO语句配置服务器,以便在下一次需要从另一个成员恢复其状态时,为group_replication_recovery复制通道使用给定的凭据。执行以下命令,将rpl_user和password替换为创建用户时使用的值。

mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='123456' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.03 sec)

分布式恢复是加入组的服务器所采取的第一步。如果这些凭据设置不正确,服务器将无法运行恢复过程并获得与其他组成员的同步,因此最终无法加入组成员。类似地,如果成员不能通过服务器的主机名正确识别其他成员,则恢复过程可能会失败。建议运行MySQL的操作系统使用正确配置的唯一主机名,可以使用DNS或本地设置。这个主机名可以在performance_schema.replication_group_members表的Member_host列中进行验证。如果多个组成员外部化操作系统设置的默认主机名,则成员有可能无法解析到正确的成员地址,从而无法加入组。在这种情况下,使用report_host配置一个唯一的主机名,由每个服务器外部化。

启动组复制
配置并启动服务mysql1后,安装Group Replication插件。连接到服务器并发出以下命令:

mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
Query OK, 0 rows affected (0.06 sec)

重点:
mysql.session在加载组复制之前必须已经存在。mysql.ession在MySQL 5.7.19版本中被添加。如果您的数据字典是使用较早版本初始化的,则必须运行mysql_upgrade过程。如果不执行升级,则启动“组复制”失败,并提示错误信息

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..

要检查插件是否已成功安装,请执行SHOW PLUGINS;然后检查输出。它应该显示如下内容:

mysql> SHOW PLUGINS;
+----------------------------+----------+--------------------+----------------------+---------+
| Name                       | Status   | Type               | Library              | License |
+----------------------------+----------+--------------------+----------------------+---------+
| binlog                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| mysql_native_password      | ACTIVE   | AUTHENTICATION     | NULL                 | GPL     |
| sha256_password            | ACTIVE   | AUTHENTICATION     | NULL                 | GPL     |
| CSV                        | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| MEMORY                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| InnoDB                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| INNODB_TRX                 | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_LOCKS               | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_LOCK_WAITS          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP                 | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP_RESET           | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMPMEM              | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMPMEM_RESET        | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP_PER_INDEX       | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP_PER_INDEX_RESET | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_BUFFER_PAGE         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_BUFFER_PAGE_LRU     | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_BUFFER_POOL_STATS   | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_TEMP_TABLE_INFO     | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_METRICS             | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_DEFAULT_STOPWORD | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_DELETED          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_BEING_DELETED    | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_CONFIG           | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_INDEX_CACHE      | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_INDEX_TABLE      | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_TABLES          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_TABLESTATS      | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_INDEXES         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_COLUMNS         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_FIELDS          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_FOREIGN         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_FOREIGN_COLS    | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_TABLESPACES     | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_DATAFILES       | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_VIRTUAL         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| MyISAM                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| MRG_MYISAM                 | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| PERFORMANCE_SCHEMA         | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| ARCHIVE                    | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| BLACKHOLE                  | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| FEDERATED                  | DISABLED | STORAGE ENGINE     | NULL                 | GPL     |
| partition                  | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| ngram                      | ACTIVE   | FTPARSER           | NULL                 | GPL     |
| group_replication          | ACTIVE   | GROUP REPLICATION  | group_replication.so | GPL     |
+----------------------------+----------+--------------------+----------------------+---------+
45 rows in set (0.01 sec)

要启动组,请指示服务器mysql1引导组,然后启动组复制。这个引导应该只由单个服务器完成,即启动组的服务器,并且只能一次。这就是为什么引导配置选项的值没有保存在配置文件中。如果将其保存在配置文件中,则重启后服务器将自动引导具有相同名称的第二个组。这将导致两个具有相同名称的不同组。同样的道理也适用于将此选项设置为ON时停止和重新启动插件。

mysql> SET GLOBAL group_replication_bootstrap_group=ON;
Query OK, 0 rows affected (0.00 sec)

mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected (2.09 sec)

mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
Query OK, 0 rows affected (0.00 sec)

一旦START GROUP_REPLICATION语句返回,这个组就已经启动了。你可以检查组现在已经创建,并且里面有一个成员:

mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | f81625c0-d3b3-11ef-9c8d-005056a390e6 | mysqlcs     |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
1 row in set (0.01 sec)

该表中的信息确认组中有一个具有唯一标识符f81625c0-d3b3-11ef-9c8d-005056a390e6的成员,它是ONLINE的,并且在mysqlcs上监听端口3306上的客户端连接。
为了演示服务器确实在一个组中,并且它能够处理负载,创建一个表并向其中添加一些内容。

mysql> CREATE DATABASE test;
Query OK, 1 row affected (0.01 sec)

mysql> USE test;
Database changed
mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL);
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO t1 VALUES (1, 'Luis');
Query OK, 1 row affected (0.04 sec)

检查表t1和二进制日志的内容。

mysql> SELECT * FROM t1;
+----+------+
| c1 | c2   |
+----+------+
|  1 | Luis |
+----+------+
1 row in set (0.00 sec)


mysql> SHOW BINLOG EVENTS;
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+
| Log_name      | Pos | Event_type     | Server_id | End_log_pos | Info                                                               |
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+
| binlog.000001 |   4 | Format_desc    |         1 |         123 | Server ver: 5.7.26-log, Binlog ver: 4                              |
| binlog.000001 | 123 | Previous_gtids |         1 |         150 |                                                                    |
| binlog.000001 | 150 | Gtid           |         1 |         211 | SET @@SESSION.GTID_NEXT= 'f81625c0-d3b3-11ef-9c8d-005056a390e6:1'  |
| binlog.000001 | 211 | Query          |         1 |         301 | CREATE DATABASE test                                               |
| binlog.000001 | 301 | Gtid           |         1 |         362 | SET @@SESSION.GTID_NEXT= 'f81625c0-d3b3-11ef-9c8d-005056a390e6:2'  |
| binlog.000001 | 362 | Query          |         1 |         486 | use `test`; CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL) |
| binlog.000001 | 486 | Gtid           |         1 |         547 | SET @@SESSION.GTID_NEXT= 'f81625c0-d3b3-11ef-9c8d-005056a390e6:3'  |
| binlog.000001 | 547 | Query          |         1 |         615 | BEGIN                                                              |
| binlog.000001 | 615 | Table_map      |         1 |         658 | table_id: 108 (test.t1)                                            |
| binlog.000001 | 658 | Write_rows     |         1 |         700 | table_id: 108 flags: STMT_END_F                                    |
| binlog.000001 | 700 | Xid            |         1 |         727 | COMMIT /* xid=23 */                                                |
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+
11 rows in set (0.00 sec)

如上所述,创建了数据库和表对象,并将它们对应的DDL语句写入二进制日志。此外,还将数据插入表并写入二进制日志。下一节将说明二进制日志条目的重要性,当组增长时,当新成员试图赶上并联机时,将执行分布式恢复。
向组中添加实例
此时,组中有一个成员服务器mysql1,其中包含一些数据。现在是时候通过添加前面配置的另外两个服务器来扩展组了。
添加第二个实例
为了添加第二个实例,服务器mysql2,首先为它创建配置文件。该配置类似于服务器mysql1所使用的配置,除了数据目录的位置、mysql2将要侦听的端口或其server_id等内容。这些不同的行在下面的清单中突出显示。
[mysql@localhost mysql]$ vi mysql2.cnf
[mysqld]
basedir=/mysqlsoft/mysql
datadir=/mysqldata/mysql2
bind-address=0.0.0.0
user=mysql
port=3307
log-error=/mysqldata/mysql2/mysql.err
pid-file=/mysqldata/mysql2/mysqld.pid
socket = /mysqldata/mysql2/mysql.sock
character-set-server=utf8mb4
default-storage-engine=INNODB

server_id=2
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW

transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="2366d798-4dc1-421a-a9de-3c825bfada7d"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address= "127.0.0.1:24902"
loose-group_replication_group_seeds= "127.0.0.1:24901,127.0.0.1:24902,127.0.0.1:24903"
loose-group_replication_bootstrap_group= off

与服务器mysql1的过程类似,配置文件就绪后启动服务器

[mysql@localhost mysql]$ mysqld --defaults-file=/mysqlsoft/mysql/mysql2.cnf &

然后配置恢复凭据,如下所示。这些命令与将服务器mysql1设置为用户在组内共享时使用的命令相同。在mysql2上发表以下声明。

[root@localhost /]#  mysql -h 10.138.130.250 -P 3307 -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

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> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE USER rpl_user@'%';
Query OK, 0 rows affected (0.01 sec)

mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%' IDENTIFIED BY 'password';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> SET SQL_LOG_BIN=1;
Query OK, 0 rows affected (0.00 sec)

mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='123456' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.02 sec)

安装Group Replication插件并启动将服务器加入组的过程。下面的示例以与部署服务器mysql1时相同的方式安装插件。

mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
Query OK, 0 rows affected (0.01 sec)

mysql> SHOW PLUGINS;
+----------------------------+----------+--------------------+----------------------+---------+
| Name                       | Status   | Type               | Library              | License |
+----------------------------+----------+--------------------+----------------------+---------+
| binlog                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| mysql_native_password      | ACTIVE   | AUTHENTICATION     | NULL                 | GPL     |
| sha256_password            | ACTIVE   | AUTHENTICATION     | NULL                 | GPL     |
| CSV                        | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| MEMORY                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| InnoDB                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| INNODB_TRX                 | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_LOCKS               | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_LOCK_WAITS          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP                 | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP_RESET           | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMPMEM              | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMPMEM_RESET        | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP_PER_INDEX       | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP_PER_INDEX_RESET | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_BUFFER_PAGE         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_BUFFER_PAGE_LRU     | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_BUFFER_POOL_STATS   | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_TEMP_TABLE_INFO     | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_METRICS             | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_DEFAULT_STOPWORD | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_DELETED          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_BEING_DELETED    | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_CONFIG           | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_INDEX_CACHE      | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_INDEX_TABLE      | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_TABLES          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_TABLESTATS      | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_INDEXES         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_COLUMNS         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_FIELDS          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_FOREIGN         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_FOREIGN_COLS    | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_TABLESPACES     | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_DATAFILES       | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_VIRTUAL         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| MyISAM                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| MRG_MYISAM                 | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| PERFORMANCE_SCHEMA         | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| ARCHIVE                    | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| BLACKHOLE                  | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| FEDERATED                  | DISABLED | STORAGE ENGINE     | NULL                 | GPL     |
| partition                  | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| ngram                      | ACTIVE   | FTPARSER           | NULL                 | GPL     |
| group_replication          | ACTIVE   | GROUP REPLICATION  | group_replication.so | GPL     |
+----------------------------+----------+--------------------+----------------------+---------+
45 rows in set (0.01 sec)

将服务器mysql2加入组。

mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected (5.85 sec)

与之前在mysql1在执行的步骤不相同,差异在于没有执行SET GLOBAL group_replication_bootstrap_group=ON;在启动组复制之前,因为组已经创建并且由服务器mysql1启动。所以这时服务器mysql2只需要被加入到现有的组中。

当组复制成功启动并且服务器加入组时,它会检查super_read_only变量。通过在成员的配置文件中将super_read_only设置为ON,可以确保在启动Group Replication时由于任何原因而失败的服务器不接受事务。如果服务器应该作为读写实例加入组,例如作为单主组中的主实例或作为多主组的成员,当super_read_only变量设置为ON时,则在加入组时将其设置为OFF。

检查performance_schema.replication_group_members表再次显示,现在组中有两个ONLINE服务器。

mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | f81625c0-d3b3-11ef-9c8d-005056a390e6 | mysqlcs     |        3306 | ONLINE       |
| group_replication_applier | ffc6ff15-d3b3-11ef-9e2d-005056a390e6 | mysqlcs     |        3307 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
2 rows in set (0.00 sec)

由于服务器mysql2也被标记为ONLINE,它一定已经自动赶上了服务器mysql1。验证它确实已与服务器mysql1同步,如下所示。

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
5 rows in set (0.00 sec)

mysql> select * from test.t1;
+----+------+
| c1 | c2   |
+----+------+
|  1 | Luis |
+----+------+
1 row in set (0.00 sec)

mysql> SHOW BINLOG EVENTS;
+---------------+-----+----------------+-----------+-------------+---------------------------------------+
| Log_name      | Pos | Event_type     | Server_id | End_log_pos | Info                                  |
+---------------+-----+----------------+-----------+-------------+---------------------------------------+
| binlog.000001 |   4 | Format_desc    |         2 |         123 | Server ver: 5.7.26-log, Binlog ver: 4 |
| binlog.000001 | 123 | Previous_gtids |         2 |         150 |                                       |
+---------------+-----+----------------+-----------+-------------+---------------------------------------+
2 rows in set (0.00 sec)

如上所述,第二台服务器已添加到组中,并且它自动复制了服务器mysql1的更改。根据分布式恢复过程,这意味着在加入组之后,在被声明为在线之前,服务器mysql2已经自动连接到服务器mysql1,并从中获取丢失的数据。换句话说,它从它缺失的二进制日志mysql1中复制事务,直到它加入组的时间点。

添加其他实例
向组中添加更多实例的步骤基本上与添加第二台服务器时相同,只是配置需要像为服务器mysql2 操作那样进行更改。要总结所需的命令:
1.修改配置文件

[mysql@localhost mysql]$ vi mysql3.cnf
[mysqld]
basedir=/mysqlsoft/mysql
datadir=/mysqldata/mysql3
bind-address=0.0.0.0
user=mysql
port=3308
log-error=/mysqldata/mysql3/mysql.err
pid-file=/mysqldata/mysql3/mysqld.pid
socket = /mysqldata/mysql3/mysql.sock
character-set-server=utf8mb4
default-storage-engine=INNODB

server_id=3
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW

transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="2366d798-4dc1-421a-a9de-3c825bfada7d"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address= "127.0.0.1:24903"
loose-group_replication_group_seeds= "127.0.0.1:24901,127.0.0.1:24902,127.0.0.1:24903"
loose-group_replication_bootstrap_group= off

2.启动服务器

[mysql@localhost mysql]$ mysqld --defaults-file=/mysqlsoft/mysql/mysql3.cnf &

3.配置group_replication_recovery通道的恢复凭据。

[root@mysqlcs ~]# mysql -h 10.138.130.250 -P 3308 -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.26-log Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

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> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE USER rpl_user@'%';
ERROR 1396 (HY000): Operation CREATE USER failed for 'rpl_user'@'%'
mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%' IDENTIFIED BY '123456';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)

mysql> SET SQL_LOG_BIN=1;
Query OK, 0 rows affected (0.00 sec)

mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='123456' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.02 sec)

4.安装Group Replication插件并启动它。

mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
Query OK, 0 rows affected (0.02 sec)

mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected (3.29 sec)

此时,服务器mysql3已经启动并运行,加入了组,并赶上了组中的其他服务器。查询performance_schema。Replication_group_members表再次

证实了这一点。

mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 07542900-d3b4-11ef-a088-005056a390e6 | mysqlcs     |        3308 | ONLINE       |
| group_replication_applier | f81625c0-d3b3-11ef-9c8d-005056a390e6 | mysqlcs     |        3306 | ONLINE       |
| group_replication_applier | ffc6ff15-d3b3-11ef-9e2d-005056a390e6 | mysqlcs     |        3307 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
3 rows in set (0.00 sec)

在服务器mysql2或服务器mysql1上执行相同的查询会产生相同的结果。此外,您可以验证服务器mysql3也赶上了:

mysql> SHOW DATABASES LIKE 'test';
+-----------------+
| Database (test) |
+-----------------+
| test            |
+-----------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM test.t1;
+----+------+
| c1 | c2   |
+----+------+
|  1 | Luis |
+----+------+
1 row in set (0.00 sec)

mysql> SHOW BINLOG EVENTS;
+---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+
| Log_name      | Pos  | Event_type     | Server_id | End_log_pos | Info                                                               |
+---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+
| binlog.000001 |    4 | Format_desc    |         3 |         123 | Server ver: 5.7.26-log, Binlog ver: 4                              |
| binlog.000001 |  123 | Previous_gtids |         3 |         150 |                                                                    |
| binlog.000001 |  150 | Gtid           |         1 |         211 | SET @@SESSION.GTID_NEXT= 'f81625c0-d3b3-11ef-9c8d-005056a390e6:1'  |
| binlog.000001 |  211 | Query          |         1 |         301 | CREATE DATABASE test                                               |
| binlog.000001 |  301 | Gtid           |         1 |         362 | SET @@SESSION.GTID_NEXT= 'f81625c0-d3b3-11ef-9c8d-005056a390e6:2'  |
| binlog.000001 |  362 | Query          |         1 |         486 | use `test`; CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL) |
| binlog.000001 |  486 | Gtid           |         1 |         547 | SET @@SESSION.GTID_NEXT= 'f81625c0-d3b3-11ef-9c8d-005056a390e6:3'  |
| binlog.000001 |  547 | Query          |         1 |         606 | BEGIN                                                              |
| binlog.000001 |  606 | Table_map      |         1 |         649 | table_id: 108 (test.t1)                                            |
| binlog.000001 |  649 | Write_rows     |         1 |         691 | table_id: 108 flags: STMT_END_F                                    |
| binlog.000001 |  691 | Xid            |         1 |         718 | COMMIT /* xid=26 */                                                |
| binlog.000001 |  718 | Gtid           |         1 |         779 | SET @@SESSION.GTID_NEXT= '2366d798-4dc1-421a-a9de-3c825bfada7d:1'  |
| binlog.000001 |  779 | Query          |         1 |         838 | BEGIN                                                              |
| binlog.000001 |  838 | View_change    |         1 |         977 | view_id=17375148526840614:1                                        |
| binlog.000001 |  977 | Query          |         1 |        1042 | COMMIT                                                             |
| binlog.000001 | 1042 | Gtid           |         1 |        1103 | SET @@SESSION.GTID_NEXT= '2366d798-4dc1-421a-a9de-3c825bfada7d:2'  |
| binlog.000001 | 1103 | Query          |         1 |        1162 | BEGIN                                                              |
| binlog.000001 | 1162 | View_change    |         1 |        1341 | view_id=17375148526840614:2                                        |
| binlog.000001 | 1341 | Query          |         1 |        1406 | COMMIT                                                             |
| binlog.000001 | 1406 | Gtid           |         1 |        1467 | SET @@SESSION.GTID_NEXT= '2366d798-4dc1-421a-a9de-3c825bfada7d:3'  |
| binlog.000001 | 1467 | Query          |         1 |        1526 | BEGIN                                                              |
| binlog.000001 | 1526 | View_change    |         1 |        1705 | view_id=17375148526840614:3                                        |
| binlog.000001 | 1705 | Query          |         1 |        1770 | COMMIT                                                             |
+---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+
23 rows in set (0.00 sec)

MySQL组复制组名不是有效的UUID

在使用 启动MySQL Group Replication 时,遇到如下错误信息

mysql> START GROUP_REPLICATION;
ERROR 3092 (HY000): The server is not configured properly to be an active member of the group. Please see more details on error log.

err.log文件中:

2025-01-22T02:14:04.090619Z 4 [ERROR] Plugin group_replication reported: 'The group name 'repl_group1' is not a valid UUID'

“Plugin group_replication reported: ‘The group name ‘repl_group1’ is not a valid UUID'” 通常意味着你在配置组复制时使用了不正确的组名格式。在 MySQL 的 Group Replication 中,组名必须是一个有效的 UUID。
解决步骤
1.生成一个有效的 UUID:
可以使用在线工具或者命令行来生成一个 UUID。例如,在 Linux 系统中,你可以使用 uuidgen 命令:

[mysql@localhost mysql]$ uuidgen
2366d798-4dc1-421a-a9de-3c825bfada7d

这将输出一个形如 2366d798-4dc1-421a-a9de-3c825bfada7d 的 UUID。

2.修改配置文件:
在你的 MySQL 配置文件(通常是 my.cnf 或 my.ini)中,将 group_replication_group_name 的值设置为上一步生成的 UUID。例如:

[mysql@localhost mysql]$ vi mysql1.cnf
loose-group_replication_group_name="2366d798-4dc1-421a-a9de-3c825bfada7d"

3.重启 MySQL 服务:
修改配置后,需要重启 MySQL 服务以使更改生效。可以使用如下命令:

[mysql@localhost mysql]$  mysqld --defaults-file=/mysqlsoft/mysql/mysql1.cnf

4.验证配置:
在 MySQL 命令行中,你可以使用以下命令来检查组复制的配置:

mysql> SHOW GLOBAL VARIABLES LIKE 'group_replication_%';
+----------------------------------------------------+-------------------------------------------------+
| Variable_name                                      | Value                                           |
+----------------------------------------------------+-------------------------------------------------+
| group_replication_allow_local_disjoint_gtids_join  | OFF                                             |
| group_replication_allow_local_lower_version_join   | OFF                                             |
| group_replication_auto_increment_increment         | 7                                               |
| group_replication_bootstrap_group                  | OFF                                             |
| group_replication_components_stop_timeout          | 31536000                                        |
| group_replication_compression_threshold            | 1000000                                         |
| group_replication_enforce_update_everywhere_checks | OFF                                             |
| group_replication_exit_state_action                | READ_ONLY                                       |
| group_replication_flow_control_applier_threshold   | 25000                                           |
| group_replication_flow_control_certifier_threshold | 25000                                           |
| group_replication_flow_control_mode                | QUOTA                                           |
| group_replication_force_members                    |                                                 |
| group_replication_group_name                       | 2366d798-4dc1-421a-a9de-3c825bfada7d            |
| group_replication_group_seeds                      | 127.0.0.1:24901,127.0.0.1:24902,127.0.0.1:24903 |
| group_replication_gtid_assignment_block_size       | 1000000                                         |
| group_replication_ip_whitelist                     | AUTOMATIC                                       |
| group_replication_local_address                    | 127.0.0.1:24903                                 |
| group_replication_member_weight                    | 50                                              |
| group_replication_poll_spin_loops                  | 0                                               |
| group_replication_recovery_complete_at             | TRANSACTIONS_APPLIED                            |
| group_replication_recovery_reconnect_interval      | 60                                              |
| group_replication_recovery_retry_count             | 10                                              |
| group_replication_recovery_ssl_ca                  |                                                 |
| group_replication_recovery_ssl_capath              |                                                 |
| group_replication_recovery_ssl_cert                |                                                 |
| group_replication_recovery_ssl_cipher              |                                                 |
| group_replication_recovery_ssl_crl                 |                                                 |
| group_replication_recovery_ssl_crlpath             |                                                 |
| group_replication_recovery_ssl_key                 |                                                 |
| group_replication_recovery_ssl_verify_server_cert  | OFF                                             |
| group_replication_recovery_use_ssl                 | OFF                                             |
| group_replication_single_primary_mode              | ON                                              |
| group_replication_ssl_mode                         | DISABLED                                        |
| group_replication_start_on_boot                    | OFF                                             |
| group_replication_transaction_size_limit           | 0                                               |
| group_replication_unreachable_majority_timeout     | 0                                               |
+----------------------------------------------------+-------------------------------------------------+
36 rows in set (0.01 sec)

确保 group_replication_group_name 的值是你设置的 UUID。

5.初始化组复制:
如果这是第一次设置组复制,确保每个服务器都已经正确配置并且可以相互通信。然后,你可以初始化组复制:

mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='123456' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.02 sec)

mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected (3.29 sec)

确保 repl_user 和 123456是正确设置的复制用户和密码。
通过以上步骤,你应该能够解决因组名格式不正确导致的错误,并成功设置 MySQL 的 Group Replication。如果问题仍然存在,请检查网络设置和防火墙规则是否允许服务器之间的通信。

MySQL 5.7 延迟复制

延迟复制
MySQL 5.7支持延迟复制,这样从服务器就会故意滞后于主服务器至少一段指定的时间。缺省值为0秒。使用MASTER_DELAY选项更改MASTER TO将 延迟设置为N秒:
CHANGE MASTER TO MASTER_DELAY = N;

从主机接收到的事件至少要比它在主机上的执行晚N秒才执行。例外情况是,格式描述事件或日志文件旋转事件没有延迟,它们只影响SQL线程的 内部状态。

延迟复制可用于以下几个目的:
.防止用户在主机上出错。DBA可以将延迟的从服务器回滚到灾难发生之前的时间

.测试系统在出现延迟时的行为。例如,在应用程序中,延迟可能是由从属服务器上的沉重负载引起的。但是,很难生成这种负载级别。延迟复 制可以模拟延迟,而不必模拟负载。它还可以用于调试与滞后从机相关的条件。

.检查数据库很久以前的样子,而无需重新加载备份。例如,如果延迟是一周,DBA需要查看数据库在最后几天的开发之前是什么样子,那么可以 检查延迟的从属服务器。

START SLAVE和STOP SLAVE立即生效并忽略任何延迟。RESET SLAVE将延迟复位为0。

SHOW SLAVE STATUS有三个字段提供延迟信息:
.SQL_Delay: 一个非负整数,表示从服务器必须滞后于主服务器的秒数

.SQL_Remaining_Delay: 当Slave_SQL_Running_State为Waiting until MASTER_DELAY seconds after master executed event,该字段包含一 个整数,表示延迟剩余的秒数。在其他时候,该字段为NULL。

.Slave_SQL_Running_State:指示SQL线程状态的字符串(类似于Slave_IO_State)。该值与SHOW PROCESSLIST显示的SQL线程的State值相同。

mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.138.130.243
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000010
          Read_Master_Log_Pos: 2099
               Relay_Log_File: localhost-relay-bin.000003
                Relay_Log_Pos: 877
        Relay_Master_Log_File: binlog.000010
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 2099
              Relay_Log_Space: 1689
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 2
                  Master_UUID: 684e1f7d-6f47-11ef-a6d5-005056a3a162
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set: 684e1f7d-6f47-11ef-a6d5-005056a3a162:9-11,
bb8b95d1-6f47-11ef-9592-005056a390e6:9-10,
ca006ef3-6f46-11ef-8203-005056b9a980:1-5
                Auto_Position: 0
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.01 sec)

mysql> SHOW PROCESSLIST\G
*************************** 1. row ***************************
     Id: 38
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 2046
  State: Slave has read all relay log; waiting for more updates
   Info: NULL
*************************** 2. row ***************************
     Id: 39
   User: root
   Host: localhost
     db: jycs
Command: Query
   Time: 0
  State: starting
   Info: SHOW PROCESSLIST
*************************** 3. row ***************************
     Id: 40
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 3682
  State: Waiting for master to send event
   Info: NULL
3 rows in set (0.00 sec)

当从SQL线程在执行事件之前等待延迟结束时,SHOW PROCESSLIST将其State值显示为waiting until MASTER_DELAY seconds after master executed event。

在从服务器上设置延迟复制时间为60秒:

mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
               Slave_IO_State: Connecting to master
                  Master_Host: 10.138.130.243
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000010
          Read_Master_Log_Pos: 2659
               Relay_Log_File: localhost-relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: binlog.000010
             Slave_IO_Running: Connecting
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 2659
              Relay_Log_Space: 154
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 2
                  Master_UUID: 684e1f7d-6f47-11ef-a6d5-005056a3a162
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 60 --延迟复制时间为60秒
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set: 684e1f7d-6f47-11ef-a6d5-005056a3a162:9-11,
bb8b95d1-6f47-11ef-9592-005056a390e6:9-10,
ca006ef3-6f46-11ef-8203-005056b9a980:1-5
                Auto_Position: 0
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.00 sec)

主服务器上插入数据

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2024-12-20 17:22:37 |
+---------------------+
1 row in set (0.00 sec)

mysql> insert into t_cs values(6,'ij');
Query OK, 1 row affected (0.03 sec)

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2024-12-20 17:22:56 |
+---------------------+
1 row in set (0.00 sec)

从服务器上验证延迟复制

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2024-12-20 17:14:31 |
+---------------------+
1 row in set (0.00 sec)

mysql> select * from t_cs;
+------+------+
| id   | name |
+------+------+
|    1 | cs   |
|    2 | ab   |
|    3 | cd   |
|    4 | ef   |
|    5 | gh   |
+------+------+
5 rows in set (0.00 sec)

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2024-12-20 17:14:37 |
+---------------------+
1 row in set (0.00 sec)

mysql> select * from t_cs;
+------+------+
| id   | name |
+------+------+
|    1 | cs   |
|    2 | ab   |
|    3 | cd   |
|    4 | ef   |
|    5 | gh   |
+------+------+
5 rows in set (0.00 sec)

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2024-12-20 17:14:51 |
+---------------------+
1 row in set (0.00 sec)

在延迟1分钟后,主服务器上插入的新记录被复制到从服务器

mysql> select * from t_cs;
+------+------+
| id   | name |
+------+------+
|    1 | cs   |
|    2 | ab   |
|    3 | cd   |
|    4 | ef   |
|    5 | gh   |
|    6 | ij   |
+------+------+
6 rows in set (0.01 sec)