
{"id":3852,"date":"2020-11-05T11:32:23","date_gmt":"2020-11-05T10:32:23","guid":{"rendered":"http:\/\/dasini.net\/blog\/?p=3852"},"modified":"2020-11-24T10:47:48","modified_gmt":"2020-11-24T09:47:48","slug":"automatic-connection-failover-for-asynchronous-replication","status":"publish","type":"post","link":"https:\/\/dasini.net\/blog\/2020\/11\/05\/automatic-connection-failover-for-asynchronous-replication\/","title":{"rendered":"Automatic connection failover for Asynchronous Replication"},"content":{"rendered":"\n<figure class=\"wp-block-image is-style-default\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/Plage_by_Olivier_DASINI_1066x800.JPG\" alt=\"Plage par Olivier DASINI\"\/><\/figure>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p><strong>TL;DR<\/strong><\/p>\n\n\n\n<p class=\"has-luminous-vivid-orange-color has-text-color\">Since <strong>MySQL 8.0.22<\/strong> there is a mechanism in asynchronous replication that makes the <strong>receiver automatically try to re-establish an asynchronous replication connection to another sender<\/strong>, in case the current connection gets interrupted due to the failure of the current sender.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n\n\n<p><a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/replication-asynchronous-connection-failover.html\" target=\"_blank\" rel=\"noreferrer noopener\">Asynchronous automatic connection failover<\/a> automates the process of re-establishment of an asynchronous replication connection to another sender of sender list.<br>That means if a the source of a replica crashed, this replica will be able to automatically connect to another source.<br>One of the biggest interest is to improve Disaster Recovery (DR) architecture.<\/p>\n\n\n\n<p>With this feature, a typical architecture is to have a 3 nodes asynchronous replication cluster.<br>2 primary nodes in active\/passive mode (<em>if you need active\/active architecture use <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/mysql-innodb-cluster.html\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"MySQL InnoDB Cluster\"><strong>MySQL InnoDB Cluster<\/strong><\/a><\/em>) and the third one is connected to  one of the primary, either for DR or for some specialized task like analytics for example.<br>So in case of unavailability of its primary &#8211; <em><strong>if the replication I\/O thread stops due to the source stopping or due to a network failure<\/strong><\/em> &#8211; this replica will  automatically connect to the other primary.<\/p>\n\n\n\n\n\n<p>Another architecture is to use this <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/replication-asynchronous-connection-failover.html\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Switching Sources with Asynchronous Connection Failover\">asynchronous automatic connection failover<\/a> feature with MySQL InnoDB Cluster.<\/p>\n\n\n\n<p>Hey guess what? this is the topic of this tutorial and by the way, we will use some of the fanciest MySQL 8.0 features \ud83d\ude42<\/p>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Context<\/h2>\n\n\n\n<p>4 MySQL <strong>8.0.22<\/strong> instances :<\/p>\n\n\n\n<p><br> &#8211;  mysql_node<strong>1<\/strong> : 172.20.0<strong>.11<\/strong><br> &#8211;  mysql_node<strong>2<\/strong> : 172.20.0<strong>.12<\/strong><br> &#8211;  mysql_node<strong>3<\/strong> : 172.20.0<strong>.13<\/strong><br>These 3 are members of a <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/group-replication.html\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"MySQL Group Replication\">MySQL Group Replication<\/a> cluster. <br>I created a <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/mysql-innodb-cluster.html\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"MySQL InnoDB Cluster\">MySQL InnoDB Cluster<\/a> (resources <a href=\"http:\/\/dasini.net\/blog\/2019\/09\/03\/tutoriel-deployer-mysql-8-0-innodb-cluster-09-2019\/\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Tutoriel \u2013 D\u00e9ployer MySQL 8.0 InnoDB Cluster (09-2019)\">here<\/a> and <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/mysql-innodb-cluster.html\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Deploying a Production InnoDB Cluster\">here<\/a>). <br>I will not use <a href=\"https:\/\/dev.mysql.com\/doc\/mysql-router\/8.0\/en\/\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"MySQL Router\">MySQL Router<\/a> in this tutorial.<\/p>\n\n\n\n<p><br> &#8211;  mysql_node<strong>4<\/strong> : 172.20.0<strong>.14<\/strong><br>It&rsquo;s my replica. <br>It will be asynchronously connected to the Group Replication.<\/p>\n\n\n\n<p>Because a picture is worth a thousand words, below is the architecture I want to achieve :<\/p>\n\n\n\n<figure class=\"wp-block-image is-style-default\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/Auto_connection_failover_Async_Replication_start_again_replica.png\" alt=\"Asynchronous Replica of a MySQL Group Replication by Olivier DASINI\"\/><\/figure>\n\n\n\n<p>Graphs in this article are from <a href=\"https:\/\/www.mysql.com\/products\/enterprise\/monitor.html\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"MySQL Enterprise Monitor\">MySQL Enterprise Monitor<\/a>.<\/p>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Current status<\/h2>\n\n\n\n<p>I&rsquo;m using <strong><a href=\"https:\/\/dev.mysql.com\/downloads\/mysql\/\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"MySQL Community Downloads\">MySQL 8.0.22<\/a><\/strong> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ mysqlsh root@mysql_node1:3306 --cluster\n\nmysql_node1:3306 ssl JS> \\sql SELECT VERSION();\n+-----------+\n| VERSION() |\n+-----------+\n| 8.0.22    |\n+-----------+<\/code><\/pre>\n\n\n\n\n\n<p>I have a 3 nodes Group Replication cluster up and running :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_node1:3306 ssl JS> \ncluster.status()\n{\n    \"clusterName\": \"ic1\", \n    \"defaultReplicaSet\": {\n        \"name\": \"default\", \n        \"primary\": \"mysql_node1:3306\", \n        \"ssl\": \"REQUIRED\", \n        \"status\": \"OK\", \n        \"statusText\": \"Cluster is ONLINE and can tolerate up to ONE failure.\", \n        \"topology\": {\n            \"mysql_node1:3306\": {\n                \"address\": \"mysql_node1:3306\", \n                \"mode\": \"R\/W\", \n                \"readReplicas\": {}, \n                \"replicationLag\": null, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.22\"\n            }, \n            \"mysql_node2:3306\": {\n                \"address\": \"mysql_node2:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"replicationLag\": null, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.22\"\n            }, \n            \"mysql_node3:3306\": {\n                \"address\": \"mysql_node3:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"replicationLag\": null, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.22\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"mysql_node1:3306\"\n}<\/code><\/pre>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Setup the replication user<\/h2>\n\n\n\n<p>Like you know, there are some preparation steps to be able to use <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/replication.html\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"MySQL Replication\">MySQL Asynchronous Replication<\/a>. If you&rsquo;re not familiar with replication using <strong>GTID<\/strong>, please read <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/replication-gtids.html\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Setting Up Replication Using GTIDs\">this<\/a>.<\/p>\n\n\n\n<p>On the Group Replication primary &#8211; <em>currently mysql_node1<\/em> &#8211; I setting up the asynchronous replication user:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_node1:3306 ssl SQL> \nCREATE USER 'repl'@'172.20.0.%' IDENTIFIED BY 'S3cr\u20actRepl' REQUIRE SSL;\n\n\nGRANT REPLICATION SLAVE ON *.* TO 'repl'@'172.20.0.%';<\/code><\/pre>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Setup the clone user<\/h2>\n\n\n\n<p>The <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/clone-plugin.html\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Clone Plugin\">clone plugin<\/a> is one of my favorite feature!<\/p>\n\n\n\n<p>It permits cloning data locally or from a remote MySQL server instance. <br>Cloned data is a physical snapshot of data stored in&nbsp;<code>InnoDB<\/code>&nbsp;that includes schemas, tables, tablespaces, and data dictionary metadata. <br>The cloned data comprises a fully functional data directory, which permits using the clone plugin for MySQL server provisioning.<\/p>\n\n\n\n<p>It&rsquo;s a very convenient way to copy data from the source (the Group Replication) to the replica (mysql_node4).<\/p>\n\n\n\n<p>Thanks to InnoDB Cluster the Clone plugin is already installed on the 3 members. <br>So on the primary member &#8211; <em>currently mysql_node1<\/em> &#8211; I&rsquo;ll create a dedicated clone user with the donor privileges for using and monitoring the clone plugin:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_node1:3306 ssl SQL> \nCREATE USER clone_user IDENTIFIED BY \"S3cr\u20actClone\";\n\n\nGRANT BACKUP_ADMIN, EXECUTE ON *.* TO clone_user;\n\n\nGRANT SELECT ON performance_schema.* TO clone_user;<\/code><\/pre>\n\n\n\n<p>Note that I could have used the cluster administrator dedicated user instead of create a specialized clone user.<\/p>\n\n\n\n\n\n<p>On <em>mysql_node4<\/em>, the future replica, I&rsquo;ll create the same user but with the recipient privileges. <br>But before I&rsquo;ll install the clone plugin and set the clone donor list:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_node4:3306 ssl SQL> \nINSTALL PLUGIN clone SONAME 'mysql_clone.so';\n\n\nSET PERSIST clone_valid_donor_list = 'mysql_node1:3306,mysql_node2:3306,mysql_node3:3306';\n\n\nCREATE USER clone_user IDENTIFIED BY \"S3cr\u20actClone\";\n\n\nGRANT CLONE_ADMIN, EXECUTE ON *.* to clone_user;\n\n\nGRANT SELECT ON performance_schema.* TO clone_user; <\/code><\/pre>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Clone a MySQL instance<\/h2>\n\n\n\n<p>Now we have everything all set to create the replica from a member of the group.<\/p>\n\n\n\n<p>On the future replica &#8211; <em>mysql_node4<\/em> &#8211; we can now run the clone instance command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_node4:3306 ssl SQL> \nCLONE INSTANCE FROM 'clone_user'@'mysql_node1':3306 IDENTIFIED BY 'S3cr\u20actClone';<\/code><\/pre>\n\n\n\n\n\n<p>If you want to monitor the cloning progress run the following query:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_node4:3306 ssl SQL> \nSELECT \n   STATE, \n   CAST(BEGIN_TIME AS DATETIME) AS \"START TIME\", \n   CASE WHEN END_TIME IS NULL THEN  LPAD(sys.format_time(POWER(10,12) * (UNIX_TIMESTAMP(now()) - UNIX_TIMESTAMP(BEGIN_TIME))), 10, ' ') \nELSE \nLPAD(sys.format_time(POWER(10,12) * (UNIX_TIMESTAMP(END_TIME) - UNIX_TIMESTAMP(BEGIN_TIME))), 10, ' ') END AS DURATION \nFROM performance_schema.clone_status;<\/code><\/pre>\n\n\n\n\n\n<p>When the cloning is over, the MySQL instance must be restarted (that will normally happen automatically). <br>After the restart, you can verify that the clone completed successfully with the queries below:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_node4:3306 ssl SQL> \nSELECT \n   STATE, \n   ERROR_NO, \n   BINLOG_FILE, \n   BINLOG_POSITION, \n   GTID_EXECUTED, \n   CAST(BEGIN_TIME AS DATETIME) as \"START TIME\", \n   CAST(END_TIME AS DATETIME) as \"FINISH TIME\", \n   sys.format_time(POWER(10,12) * (UNIX_TIMESTAMP(END_TIME) - UNIX_TIMESTAMP(BEGIN_TIME))) AS DURATION \nFROM performance_schema.clone_status \\G<\/code><\/pre>\n\n\n\n<p>and:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_node4:3306 ssl SQL> \nSELECT \n   STAGE, \n   STATE, \n   CAST(BEGIN_TIME AS DATETIME) as \"START TIME\", \n   CAST(END_TIME AS DATETIME) as \"FINISH TIME\", \n   LPAD(sys.format_time(POWER(10,12) * (UNIX_TIMESTAMP(END_TIME) - UNIX_TIMESTAMP(BEGIN_TIME))), 10, ' ') AS DURATION \nFROM performance_schema.clone_progress;<\/code><\/pre>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Add the replica<\/h2>\n\n\n\n<p>First I will setup the configuration information for a replication source server to the source list for a replication channel.<br>To do that we use the function: <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/replication-functions-source-list.html#udf_asynchronous-connection-failover-add-source\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"asynchronous_connection_failover_add_source()\">asynchronous_connection_failover_add_source<\/a><br>Information needed are the replication channel name, the source server address, port and network namespace, and also the weight.<\/p>\n\n\n\n<p>More information are available <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/replication-functions-source-list.html\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Functions which Configure the Source List\">here<\/a>.<\/p>\n\n\n\n<p>For this tutorial I chose the following values:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Channel name: <em>autof<\/em><\/li><li>Source server addresses: <em>mysql_node1<\/em>, <em>mysql_node2<\/em>, <em>mysql_node3<\/em><\/li><li>Source server port: <em>3306<\/em><\/li><li>Source server network namespace: \u00a0\u00bb (empty)<\/li><li>Weight: respectively: <em>50<\/em>, <em>90<\/em>, <em>90<\/em> <\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_node4:3306 ssl SQL> \nSELECT asynchronous_connection_failover_add_source('autof', 'mysql_node1', 3306, '', 50);\n\n\nSELECT asynchronous_connection_failover_add_source('autof', 'mysql_node2', 3306, '', 90);\n\n\nSELECT asynchronous_connection_failover_add_source('autof', 'mysql_node3', 3306, '', 90);<\/code><\/pre>\n\n\n\n\n\n<p>The&nbsp;replica&rsquo;s source lists for each replication channel for the asynchronous connection failover mechanism can be viewed in the Performance Schema table <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/performance-schema-replication-asynchronous-connection-failover-table.html\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"The replication_asynchronous_connection_failover Table\">replication_asynchronous_connection_failover<\/a>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_node4:3306 ssl SQL> \nSELECT * FROM performance_schema.replication_asynchronous_connection_failover;\n+--------------+-------------+------+-------------------+--------+\n| Channel_name | Host        | Port | Network_namespace | Weight |\n+--------------+-------------+------+-------------------+--------+\n| autof        | mysql_node1 | 3306 |                   |     50 |\n| autof        | mysql_node2 | 3306 |                   |     90 |\n| autof        | mysql_node3 | 3306 |                   |     90 |\n+--------------+-------------+------+-------------------+--------+\n<\/code><\/pre>\n\n\n\n\n\n<p>To set the parameters that the replica server uses for connect to the source, we use the well known <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/change-master-to.html\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"CHANGE MASTER TO\">CHANGE MASTER TO<\/a> statement. <br>You already know most of its clauses, so let&rsquo;s only focus on some of them:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>SOURCE_CONNECTION_AUTO_FAILOVER<\/strong> : activates the asynchronous connection failover mechanism.<\/li><li><strong>MASTER_RETRY_COUNT<\/strong> &amp; <strong>MASTER_CONNECT_RETRY<\/strong> : define the failover time. The default setting is&#8230; 60 days, probably not what you want :). So, you (most likely) should reduced the settings. e.g. 1 minute is respectively 20 and 3. (20 x 3 = 60)<\/li><li><strong>FOR<\/strong> <strong>CHANNEL<\/strong> : enables you to name which replication channel the statement applies to. The CHANGE MASTER TO statement applies to this specific replication channel.<\/li><\/ul>\n\n\n\n\n\n<p>Now let&rsquo;s configure the replication:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_node4:3306 ssl SQL> \nCHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='S3cr\u20actRepl', MASTER_HOST='mysql_node2', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_SSL=1, SOURCE_CONNECTION_AUTO_FAILOVER=1, MASTER_RETRY_COUNT=3, MASTER_CONNECT_RETRY=5 FOR CHANNEL 'autof';<\/code><\/pre>\n\n\n\n<p>Please note that my failover time in this tutorial is 15 seconds (3 x 5). Obviously the relevant setting depends on your needs. A longer duration will probably makes more sense in real life.<\/p>\n\n\n\n\n\n<p>Then start the replication, on channel <em>autof<\/em> using <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/start-replica.html\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"START REPLICA | SLAVE Statement\">START REPLICA<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_node4:3306 ssl SQL> \nSTART REPLICA FOR CHANNEL \"autof\";<\/code><\/pre>\n\n\n\n\n\n<p>&nbsp;Status information of the replication can be seen with <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/show-replica-status.html\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"SHOW REPLICA | SLAVE STATUS Statement\">SHOW REPLICA<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_node4:3306 ssl SQL> \nSHOW REPLICA STATUS\\G\n*************************** 1. row ***************************\n             Replica_IO_State: Waiting for master to send event\n                  Source_Host: mysql_node2\n                  Source_User: repl\n                  Source_Port: 3306\n                Connect_Retry: 5\n                           ...\n           Replica_IO_Running: Yes\n          Replica_SQL_Running: Yes\n                           ...\n           Source_Retry_Count: 3\n                           ...\n                Auto_Position: 1\n                           ...\n                 Channel_Name: autof\n                           ...<\/code><\/pre>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Automatic connection failover<\/h2>\n\n\n\n<p>We have now configured our replication, with an InnoDB Cluster\/Group Replication as a source and a standalone MySQL server as a replica.<br>Let&rsquo;s see how the automatic connection failover works.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Restart the replica<\/h3>\n\n\n\n<p>I want to see the behavior after a restart of the replication.<\/p>\n\n\n\n<p>State before the stop:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_node4:3306 ssl SQL> \nSELECT \n   CHANNEL_NAME, \n   SERVICE_STATE, \n   HOST, \n   CONNECTION_RETRY_INTERVAL, \n   CONNECTION_RETRY_COUNT \nFROM replication_connection_configuration \n   INNER JOIN replication_applier_status \n      USING (CHANNEL_NAME) \nWHERE CHANNEL_NAME = 'autof'\\G\n*************************** 1. row ***************************\n             CHANNEL_NAME: autof\n            SERVICE_STATE: ON\n                     HOST: mysql_node2\nCONNECTION_RETRY_INTERVAL: 5\n   CONNECTION_RETRY_COUNT: 3<\/code><\/pre>\n\n\n\n\n\n<p>Stop the replication:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_node4:3306 ssl SQL> \nSTOP REPLICA;\n\n\nSELECT \n   CHANNEL_NAME, \n   SERVICE_STATE, \n   HOST, \n   CONNECTION_RETRY_INTERVAL, \n   CONNECTION_RETRY_COUNT \nFROM replication_connection_configuration \n   INNER JOIN replication_applier_status \n      USING (CHANNEL_NAME) \nWHERE CHANNEL_NAME = 'autof'\\G\n*************************** 1. row ***************************\n             CHANNEL_NAME: autof\n            SERVICE_STATE: OFF\n                     HOST: mysql_node2\nCONNECTION_RETRY_INTERVAL: 5\n   CONNECTION_RETRY_COUNT: 3<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image is-style-default\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/Auto_connection_failover_Async_Replication_stop_replica.png\" alt=\"MySQL Enterprise Monitor\"\/><\/figure>\n\n\n\n\n\n<p>After a while, start the replication:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_node4:3306 ssl SQL> \nSTART REPLICA;\n\nSELECT \n   CHANNEL_NAME, \n   SERVICE_STATE, \n   HOST, \n   CONNECTION_RETRY_INTERVAL, \n   CONNECTION_RETRY_COUNT \nFROM replication_connection_configuration \n   INNER JOIN replication_applier_status \n      USING (CHANNEL_NAME) \nWHERE CHANNEL_NAME = 'autof'\\G\n*************************** 1. row ***************************\n             CHANNEL_NAME: autof\n            SERVICE_STATE: ON\n                     HOST: mysql_node2\nCONNECTION_RETRY_INTERVAL: 5\n   CONNECTION_RETRY_COUNT: 3<\/code><\/pre>\n\n\n\n\n\n<p>Replica picks up where it left off&#8230; as you would have expected.<\/p>\n\n\n\n\n\n\n\n<h3 class=\"wp-block-heading\">Short unavailability of the source<\/h3>\n\n\n\n<p>I want to see the behavior after a short unavailability of the source. I mean a duration lower than the failover threshold &#8211; <em>connection_retry_interval<\/em> x <em>connection_retry_count<\/em> &#8211; 15 seconds (5&#215;3) in this example. <\/p>\n\n\n\n<p>State before the stop of the source, <em>mysql_node2<\/em>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_node4:3306 ssl SQL> \nSELECT \n   CHANNEL_NAME, \n   SERVICE_STATE, \n   HOST, \n   CONNECTION_RETRY_INTERVAL, \n   CONNECTION_RETRY_COUNT \nFROM replication_connection_configuration \n   INNER JOIN replication_applier_status \n      USING (CHANNEL_NAME) \nWHERE CHANNEL_NAME = 'autof'\\G\n*************************** 1. row ***************************\n             CHANNEL_NAME: autof\n            SERVICE_STATE: ON\n                     HOST: mysql_node2\nCONNECTION_RETRY_INTERVAL: 5\n   CONNECTION_RETRY_COUNT: 3<\/code><\/pre>\n\n\n\n<p><em>&#8230; Stop mysql_node2 for 10 seconds &#8230;<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image is-style-default\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/Auto_connection_failover_Async_Replication_short_unavailability.png\" alt=\"MySQL Enterprise Monitor\"\/><\/figure>\n\n\n\n<p>State after the start of the source <em>mysql_node2<\/em>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_node4:3306 ssl SQL> \nSELECT \n   CHANNEL_NAME, \n   SERVICE_STATE, \n   HOST, \n   CONNECTION_RETRY_INTERVAL, \n   CONNECTION_RETRY_COUNT \nFROM replication_connection_configuration \n   INNER JOIN replication_applier_status \n      USING (CHANNEL_NAME) \nWHERE CHANNEL_NAME = 'autof'\\G\n*************************** 1. row ***************************\n             CHANNEL_NAME: autof\n            SERVICE_STATE: ON\n                     HOST: mysql_node2\nCONNECTION_RETRY_INTERVAL: 5\n   CONNECTION_RETRY_COUNT: 3<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image is-style-default\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/Auto_connection_failover_Async_Replication_start_again_replica.png\" alt=\"MySQL Enterprise Monitor\"\/><\/figure>\n\n\n\n<p>Well&#8230; nothing changed!<br>The unavailability of the source was not long enough to trigger the failover. <br>That is awesome to prevent non necessary failover.<\/p>\n\n\n\n\n\n\n\n<h3 class=\"wp-block-heading\">Long unavailability of the source<\/h3>\n\n\n\n<p>I want to see the behavior after a longer unavailability of the source. I mean a duration greater than the failover threshold &#8211; <em>connection_retry_interval<\/em> x <em>connection_retry_count<\/em> &#8211; 15 seconds (5&#215;3) in this example. <\/p>\n\n\n\n<p>State before the stop of the source, <em>mysql_node2<\/em>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_node4:3306 ssl SQL> \nSELECT \n   CHANNEL_NAME, \n   SERVICE_STATE, \n   HOST, \n   CONNECTION_RETRY_INTERVAL, \n   CONNECTION_RETRY_COUNT \nFROM replication_connection_configuration \n   INNER JOIN replication_applier_status \n      USING (CHANNEL_NAME) \nWHERE CHANNEL_NAME = 'autof'\\G\n*************************** 1. row ***************************\n             CHANNEL_NAME: autof\n            SERVICE_STATE: ON\n                     HOST: mysql_node2\nCONNECTION_RETRY_INTERVAL: 5\n   CONNECTION_RETRY_COUNT: 3<\/code><\/pre>\n\n\n\n<p><em>&#8230; Stop mysql_node2 for 20 seconds &#8230;<\/em><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mysql_node4:3306 ssl SQL> \nSELECT \n   CHANNEL_NAME, \n   SERVICE_STATE, \n   HOST, \n   CONNECTION_RETRY_INTERVAL, \n   CONNECTION_RETRY_COUNT \nFROM replication_connection_configuration \n   INNER JOIN replication_applier_status \n      USING (CHANNEL_NAME) \nWHERE CHANNEL_NAME = 'autof'\\G\n*************************** 1. row ***************************\n             CHANNEL_NAME: autof\n            SERVICE_STATE: ON\n                     HOST: mysql_node3\nCONNECTION_RETRY_INTERVAL: 5\n   CONNECTION_RETRY_COUNT: 3<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image is-style-default\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/Auto_connection_failover_Async_Replication_long_unavailability.png\" alt=\"MySQL Enterprise Monitor\"\/><\/figure>\n\n\n\n<p>As expected, the asynchronous automatic connection failover took place. \\o\/<br>The new source is now <em>mysql_node3<\/em>,  because it has a bigger weight than <em>mysql_node1<\/em> (90 vs 50) and because it was available \ud83d\ude42<\/p>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Limitations<\/h2>\n\n\n\n<p>Please be aware that in 8.0.22 this feature lacks of some of the needed functionality to replace MySQL Router as means to replicate from an InnoDB Cluster\/Group Replication cluster.<\/p>\n\n\n\n<p>Things such as:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>does not automatically learn about new members or members that are removed<\/li><li>does not follow the primary role, it stays connected to whatever host it was connected to<\/li><li>does not follow the majority network partition<\/li><li>does not care if a host is not part of the group any longer, as long as it can connect, it will<\/li><\/ul>\n\n\n\n<p>These limitations will be lifted in future versions.<\/p>\n\n\n\n\n\n\n\n\n\n<p>This is a very nice feature starting with <strong>MySQL 8.0.22<\/strong>, useful for both MySQL Replication and MySQL Group Replication architectures.<\/p>\n\n\n\n<p>And you know what? There is more to come \ud83d\ude09<\/p>\n\n\n\n<p>Stay tuned!<\/p>\n\n\n\n\n\n\n\n<h2 class=\"wp-block-heading\">References<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/replication-asynchronous-connection-failover.html\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Switching Sources with Asynchronous Connection Failover\">Switching Sources with Asynchronous Connection Failover<\/a><\/li><li><a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/replication-functions-source-list.html\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Functions which Configure the Source List\">Functions which Configure the Source List<\/a><\/li><li><a href=\"https:\/\/dev.mysql.com\/worklog\/task\/?id=12649\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"WL#12649: Automatic connection failover for Async Replication Channels \u2013 Step I: Automatic Connection Failover\">WL#12649: Automatic connection failover for Async Replication Channels &#8211; Step I: Automatic Connection Failover<\/a><\/li><li><a href=\"https:\/\/mysqlserverteam.com\/clone-create-mysql-instance-replica\/\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Clone: Create MySQL instance replica\">Clone: Create MySQL instance replica<\/a><\/li><li><a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/clone-plugin.html\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"The Clone Plugin\">The Clone Plugin<\/a><\/li><li><a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/replication.html\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"MySQL Replication\">MySQL Replication<\/a><\/li><li><a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/group-replication.html\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"MySQL Group Replication\">MySQL Group Replication<\/a><\/li><li><a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/mysql-innodb-cluster.html\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"MySQL InnoDB Cluster\">MySQL InnoDB Cluster<\/a><\/li><li><a href=\"http:\/\/dasini.net\/blog\/2019\/09\/03\/tutoriel-deployer-mysql-8-0-innodb-cluster-09-2019\/\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Tutoriel \u2013 D\u00e9ployer MySQL 8.0 InnoDB Cluster\">Tutoriel \u2013 D\u00e9ployer MySQL 8.0 InnoDB Cluster<\/a><\/li><li><a href=\"https:\/\/www.mysql.com\/products\/enterprise\/\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"MySQL Enterprise Edition\">MySQL Enterprise Edition<\/a><\/li><\/ul>\n\n\n\n\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><a href=\"https:\/\/www.linkedin.com\/groups\/12524512\/\" target=\"_blank\" rel=\"noopener\" title=\"Olivier DASINI on Linkedin\">Follow me on Linkedin<\/a><\/p>\n\n\n\n<p>Watch my videos on my <a href=\"https:\/\/www.youtube.com\/channel\/UC12TulyJsJZHoCmby3Nm3WQ\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Olivier's MySQL Channel\">YouTube channel<\/a> and <a href=\"https:\/\/www.youtube.com\/channel\/UC12TulyJsJZHoCmby3Nm3WQ\/?sub_confirmation=1\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Subscribe\">subscribe<\/a>.<\/p>\n\n\n\n<p>My <a href=\"https:\/\/www.slideshare.net\/freshdaz\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Olivier DASINI on Slideshare\">Slideshare account<\/a>.<\/p>\n\n\n\n<p>My <a href=\"https:\/\/speakerdeck.com\/freshdaz\/\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Olivier DASINI on Speaker Deck\">Speaker Deck account<\/a>.<\/p>\n\n\n\n<div style=\"height:25px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-vivid-red-color has-text-color\"><strong>Thanks for using HeatWave &amp; MySQL!<\/strong><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Since MySQL 8.0.22 there is a mechanism in asynchronous replication that makes the receiver automatically try to re-establish an asynchronous replication connection to another sender, in case the current connection gets interrupted due to the failure of the current sender.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"footnotes":""},"categories":[351,355,203,339],"tags":[1642,1641,343],"class_list":["post-3852","post","type-post","status-publish","format-standard","hentry","category-group-replication-en","category-high-availability","category-mysql-en","category-tuto-en","tag-disaster-recovery","tag-failover","tag-group-replication-en"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9LfWW-108","jetpack-related-posts":[{"id":3086,"url":"https:\/\/dasini.net\/blog\/2019\/05\/21\/mysql-innodb-cluster-howto-2-validate-an-instance\/","url_meta":{"origin":3852,"position":0},"title":"MySQL InnoDB Cluster &#8211; HowTo #2 &#8211; Validate an instance","author":"Olivier DASINI","date":"21 mai 2019","format":false,"excerpt":"Q: Validate an instance for MySQL InnoDB Cluster usage? A: Use check_instance_configuration()","rel":"","context":"Dans &quot;Group Replication&quot;","block_context":{"text":"Group Replication","link":"https:\/\/dasini.net\/blog\/category\/group-replication-en\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":6650,"url":"https:\/\/dasini.net\/blog\/2024\/07\/16\/get-your-heatwave-mysql-data-on-premises-with-replication\/","url_meta":{"origin":3852,"position":1},"title":"Get Your HeatWave MySQL Data On-Premises with Replication","author":"Olivier DASINI","date":"16 juillet 2024","format":false,"excerpt":"This article guides you through setting up replication between a HeatWave MySQL instance (source) and an on-premise standalone MySQL instance (replica). It highlights key steps like creating a replication user, securing the connection, and using MySQL Shell utilities for data transfer.","rel":"","context":"Dans &quot;HeatWave&quot;","block_context":{"text":"HeatWave","link":"https:\/\/dasini.net\/blog\/category\/heatwave-en\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/2024\/07\/Get-Your-HeatWave-MySQL-Data-On-Premises-with-Replication-1.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/2024\/07\/Get-Your-HeatWave-MySQL-Data-On-Premises-with-Replication-1.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/2024\/07\/Get-Your-HeatWave-MySQL-Data-On-Premises-with-Replication-1.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/2024\/07\/Get-Your-HeatWave-MySQL-Data-On-Premises-with-Replication-1.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/2024\/07\/Get-Your-HeatWave-MySQL-Data-On-Premises-with-Replication-1.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/2024\/07\/Get-Your-HeatWave-MySQL-Data-On-Premises-with-Replication-1.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":3957,"url":"https:\/\/dasini.net\/blog\/2020\/11\/10\/mysql-8-0-22-new-features-summary\/","url_meta":{"origin":3852,"position":2},"title":"MySQL 8.0.22 New Features Summary","author":"Olivier DASINI","date":"10 novembre 2020","format":false,"excerpt":"Presentation of some of the new features of MySQL 8.0.22 released on October 19th, 2020.","rel":"","context":"Dans &quot;MySQL&quot;","block_context":{"text":"MySQL","link":"https:\/\/dasini.net\/blog\/category\/mysql-en\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/img.youtube.com\/vi\/CFFcaqhN-W8\/0.jpg?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":2090,"url":"https:\/\/dasini.net\/blog\/2018\/01\/09\/setting-up-proxysql-1-4-with-mysql-5-7-group-replication\/","url_meta":{"origin":3852,"position":3},"title":"Setting up ProxySQL 1.4 with MySQL 5.7 Group Replication","author":"Olivier DASINI","date":"9 janvier 2018","format":false,"excerpt":"There are 3\u00a0pillars for a database architecture: Monitoring, Backup \/ Restore process, High Availability This blog post is about database High Availability; more precisely about one of the best combo of the moment : MySQL 5.7 Group Replication\u00a0: the only native HA solution for MySQL, it's a\u00a0Single\/Multi-master update everywhere replication\u2026","rel":"","context":"Dans &quot;Group Replication&quot;","block_context":{"text":"Group Replication","link":"https:\/\/dasini.net\/blog\/category\/group-replication-en\/"},"img":{"alt_text":"MySQL","src":"https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/mysql_300x161.jpg?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":4188,"url":"https:\/\/dasini.net\/blog\/2021\/01\/26\/replicate-from-mysql-5-7-to-mysql-database-service\/","url_meta":{"origin":3852,"position":4},"title":"Replicate from MySQL 5.7 to MySQL Database Service","author":"Olivier DASINI","date":"26 janvier 2021","format":false,"excerpt":"MySQL Replication is a very common topology, widely used in various architecture. People use it, among others, for High Availability, Read Scalability or Geographic Redundancy. Another use case is to use MySQL Replication to seamlessly integrate a newer version of the server in your architecture. Let\u2019s say you are running\u2026","rel":"","context":"Dans &quot;MySQL&quot;","block_context":{"text":"MySQL","link":"https:\/\/dasini.net\/blog\/category\/mysql-en\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":4151,"url":"https:\/\/dasini.net\/blog\/2020\/12\/17\/mysql-shell-the-new-era\/","url_meta":{"origin":3852,"position":5},"title":"MySQL SHELL &#8211; The new era","author":"Anastasia Papachristopoulou","date":"17 d\u00e9cembre 2020","format":false,"excerpt":"In one of our previous articles - Setting up Replication with various methods for MySQL 8 - we reviewed how to create a replica with multiple tools. Now, it is time to perform the same action but with MySQL Shell.","rel":"","context":"Dans &quot;Backup \/ Restore&quot;","block_context":{"text":"Backup \/ Restore","link":"https:\/\/dasini.net\/blog\/category\/backup-restore\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts\/3852","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/comments?post=3852"}],"version-history":[{"count":91,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts\/3852\/revisions"}],"predecessor-version":[{"id":4031,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts\/3852\/revisions\/4031"}],"wp:attachment":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/media?parent=3852"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/categories?post=3852"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/tags?post=3852"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}