In this blog, I am going to explain the different ways of electing the PRIMARY node in MySQL group replication. Before MySQL 8.0.2, primary election was based on the member’s UUID, with the lowest UUID elected as the new primary in the event of a failover.
From MySQL 8.0.2: We can select the node to be promoted as a PRIMARY using the server weight ( group_replication_member_weight ). This can be achieved during the failure of the current primary node.
From MySQL 8.0.12: We can promote any node as a PRIMARY using the function “group_replication_set_as_primary”. This can be set anytime without any failures of nodes.
Scenario:
I have installed the 3 node group replication cluster. I am using Percona Server for MySQL 8.0.22.
1 2 3 4 5 6 7 8 9 | mysql> select member_host,member_state,member_role,member_version from performance_schema.replication_group_members; +---------------+--------------+-------------+----------------+ | member_host | member_state | member_role | member_version | +---------------+--------------+-------------+----------------+ | 172.28.128.15 | ONLINE | SECONDARY | 8.0.22 | | 172.28.128.14 | ONLINE | PRIMARY | 8.0.22 | | 172.28.128.13 | ONLINE | SECONDARY | 8.0.22 | +---------------+--------------+-------------+----------------+ 3 rows in set (0.03 sec) |
I am planning to take the current PRIMARY node “172.28.128.14” to maintenance for OS patching. When I bring the current PRIMARY node down, I need to promote the server “172.28.128.15” as a PRIMARY member. Let see how this can be achieved in the following ways.
- Using server weight (group_replication_member_weight)
- Using function “group_replication_set_as_primary”
Using server weight (group_replication_member_weight):
This approach is not straightforward. The new node will be promoted as a primary member when the current primary member goes down. Currently, I have the same weight on all my nodes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | [root@innodb1 ~]# mysql -e "select @@hostname, @@group_replication_member_weight\G" *************************** 1. row *************************** @@hostname: 172.28.128.13 @@group_replication_member_weight: 50 [root@innodb2 ~]# mysql -e "select @@hostname, @@group_replication_member_weight\G" *************************** 1. row *************************** @@hostname: 172.28.128.14 @@group_replication_member_weight: 50 [root@innodb3 ~]# mysql -e "select @@hostname, @@group_replication_member_weight\G" *************************** 1. row *************************** @@hostname: 172.28.128.15 @@group_replication_member_weight: 50 |
I am going to increase the weight on the server “172.28.128.15” so that it will be elected as a PRIMARY member when taking down the “172.28.128.14”.
At “172.28.128.15”,
1 2 3 4 5 6 7 8 9 10 | mysql> set global group_replication_member_weight = 70; Query OK, 0 rows affected (0.00 sec) mysql> select @@group_replication_member_weight; +-----------------------------------+ | @@group_replication_member_weight | +-----------------------------------+ | 70 | +-----------------------------------+ 1 row in set (0.00 sec) |
Note: To set the weight, you don’t need to execute the STOP/START GROUP_REPLICATION.
The weight was increased to 70 on the server “172.28.128.15”. Now, I am going to bring down the current PRIMARY node “172.28.128.14”.
At “172.28.128.14”,
1 2 3 4 5 6 7 8 9 10 | mysql> stop group_replication; Query OK, 0 rows affected (4.29 sec) mysql> select member_host,member_state,member_role,member_version from performance_schema.replication_group_members; +---------------+--------------+-------------+----------------+ | member_host | member_state | member_role | member_version | +---------------+--------------+-------------+----------------+ | 172.28.128.14 | OFFLINE | | | +---------------+--------------+-------------+----------------+ 1 row in set (0.01 sec) |
The node was left from the cluster.
At “172.28.128.15”,
1 2 3 4 5 6 7 8 | mysql> select member_host,member_state,member_role,member_version from performance_schema.replication_group_members; +---------------+--------------+-------------+----------------+ | member_host | member_state | member_role | member_version | +---------------+--------------+-------------+----------------+ | 172.28.128.15 | ONLINE | PRIMARY | 8.0.22 | | 172.28.128.13 | ONLINE | SECONDARY | 8.0.22 | +---------------+--------------+-------------+----------------+ 2 rows in set (0.04 sec) |
You can see that “172.28.128.15” was selected as a new PRIMARY node.
Using function “group_replication_set_as_primary”:
This method is very straightforward and no need to fail the current PRIMARY node to switch the primary member.
1 2 3 4 5 6 7 8 | +---------------+--------------+-------------+----------------+ | member_host | member_state | member_role | member_version | +---------------+--------------+-------------+----------------+ | 172.28.128.15 | ONLINE | SECONDARY | 8.0.22 | | 172.28.128.14 | ONLINE | PRIMARY | 8.0.22 | | 172.28.128.13 | ONLINE | SECONDARY | 8.0.22 | +---------------+--------------+-------------+----------------+ 3 rows in set (0.00 sec) |
Now, we need to execute the function “group_replication_set_as_primary” with the member UUID.
At “172.28.128.15”,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | mysql> show global variables like 'server_uu%'; +---------------+--------------------------------------+ | Variable_name | Value | +---------------+--------------------------------------+ | server_uuid | c5aed435-d58d-11ea-bb26-5254004d77d3 | +---------------+--------------------------------------+ 1 row in set (0.00 sec) mysql> select group_replication_set_as_primary('c5aed435-d58d-11ea-bb26-5254004d77d3'); +--------------------------------------------------------------------------+ | group_replication_set_as_primary('c5aed435-d58d-11ea-bb26-5254004d77d3') | +--------------------------------------------------------------------------+ | Primary server switched to: c5aed435-d58d-11ea-bb26-5254004d77d3 | +--------------------------------------------------------------------------+ 1 row in set (1.03 sec) mysql> select member_host,member_state,member_role,member_version from performance_schema.replication_group_members; +---------------+--------------+-------------+----------------+ | member_host | member_state | member_role | member_version | +---------------+--------------+-------------+----------------+ | 172.28.128.15 | ONLINE | PRIMARY | 8.0.22 | | 172.28.128.14 | ONLINE | SECONDARY | 8.0.22 | | 172.28.128.13 | ONLINE | SECONDARY | 8.0.22 | +---------------+--------------+-------------+----------------+ 3 rows in set (0.00 sec) |
“172.28.128.15” was elected as a PRIMARY node.
Note: You can execute the function “group_replication_set_as_primary_node” on any server of the cluster.
This approach is very useful, and if you want to switch the PRIMARY member to a highly configured server or for any other reason, it will be greatly helpful.
Good Sakthivel
Its really useful article at this time. Thanks @Sri Sakthivel
after the node comes up which was down , do we need to perform any step to make it as primary ?
Article is good. My situation is different. In 3 node cluster(1 primaryI(rw), 2 secondary(ro)), my primary is down. Unable to start up due to incosistencies. Can I promote one of ro nodes – make it primary. Then startup cluster with 1 primary 1 secondary ?