
{"id":3299,"date":"2019-09-03T07:11:32","date_gmt":"2019-09-03T06:11:32","guid":{"rendered":"http:\/\/dasini.net\/blog\/?p=3299"},"modified":"2019-09-10T08:46:39","modified_gmt":"2019-09-10T07:46:39","slug":"tutoriel-deployer-mysql-8-0-innodb-cluster-09-2019","status":"publish","type":"post","link":"https:\/\/dasini.net\/blog\/2019\/09\/03\/tutoriel-deployer-mysql-8-0-innodb-cluster-09-2019\/","title":{"rendered":"Tutoriel \u2013 D\u00e9ployer MySQL 8.0 InnoDB Cluster (09-2019)"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/Rocher_du_Diamant_Martinique_by_olivier_dasini_1822x600.jpg\" alt=\"Rocher du Diamant - Martinique by Olivier DASINI\"\/><\/figure><\/div>\n\n\n\n<p>Cela fait maintenant 1 an que j&rsquo;ai \u00e9cris la v1 de ce tuto sur MySQL InnoDB Cluster (<a rel=\"noreferrer noopener\" aria-label=\"c'est par ici (opens in a new tab)\" href=\"http:\/\/dasini.net\/blog\/2018\/08\/30\/tutoriel-deployer-mysql-8-0-innodb-cluster\/\" target=\"_blank\">ici<\/a>) et durant ce laps de temps, mes coll\u00e8gues d&rsquo;<a rel=\"noreferrer noopener\" href=\"https:\/\/www.mysql.com\/\" target=\"_blank\">Oracle MySQL<\/a> ont travaill\u00e9 tr\u00e8s dur pour enrichir la solution et  d\u00e9velopper pas mal de nouvelles fonctionnalit\u00e9s. <br>En fait que du bon \ud83d\ude42 &#8211; gr\u00e2ce \u00e0 vous et \u00e0 vos retours &#8211; <strong>merci infiniment<\/strong> !.<\/p>\n\n\n\n<p>Bref tu l&rsquo;as compris, c&rsquo;est le moment de mettre \u00e0 jour ce tutoriel.<br>En clair, cet article remplace et annule l&rsquo;ancien.<\/p>\n\n\n\n<p>Je t&rsquo;invite \u00e0 passer un moment avec moi pour d\u00e9couvrir les diff\u00e9rentes \u00e9tapes du d\u00e9ploiement d&rsquo;un <strong>MySQL InnoDB Cluster<\/strong>, l\u2019utilisation de <strong>MySQL Router<\/strong> et aussi les principales commandes pour g\u00e9rer ton cluster avec <strong>MySQL Shell<\/strong>.<br><\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n\n\n<p>Dans la liste des besoins essentiels de mes clients, en plus de la supervision et des process de sauvegarde et restauration, se trouve la <strong>Haute Disponibilit\u00e9 avec MySQL<\/strong>. <\/p>\n\n\n\n<p>On va donc voir, dans cet article, comment d\u00e9ployer et g\u00e9rer un cluster MySQL \u00ab\u00a0<em>from scratch\u00a0\u00bb<\/em>&nbsp;, sous la forme d&rsquo;un tutoriel, gr\u00e2ce \u00e0 la solution <strong>HA<\/strong> native tout en un : <u>MySQL InnoDB Cluster<\/u>.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><em><u>Note<\/u>:&nbsp;<\/em><br><em>L&rsquo;article traite de MySQL <strong>InnoDB<\/strong> Cluster, HA natif de MySQL Server (plugin <strong>Group Replication<\/strong>) avec pour moteur de stockage <a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/innodb-storage-engine.html\" target=\"_blank\">InnoDB<\/a>. <\/em><br><em>Solution \u00e0 ne pas confondre avec <a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/mysql-cluster.html\" target=\"_blank\">MySQL <strong>NDB<\/strong> Cluster<\/a>&nbsp;(moteur de stockage <strong>NDB<\/strong>).<\/em><\/p><\/blockquote>\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Le contexte<\/h2>\n\n\n\n<p>3 instances MySQL autonomes (je peux en avoir 9 max), <br><em>&lt;spoil alert&gt;<\/em> qui vont gr\u00e2ce au plugin <a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/group-replication.html\" target=\"_blank\">MySQL Group Replication<\/a> se transformer en une base de donn\u00e9es distribu\u00e9e.<em>&lt;\/spoil alert&gt;<\/em><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Instance MySQL #1 &#8211; <em>mysql_node1<\/em> &#8211; N\u0153ud 1 du cluster<\/li><li>Instance MySQL #2 &#8211; <em>mysql_node2<\/em> &#8211; N\u0153ud 2 du cluster<\/li><li>Instance MySQL #3 &#8211; <em>mysql_node3<\/em> &#8211; N\u0153ud 3 du cluster<\/li><\/ul>\n\n\n\n<p>1 instance applicative &#8211; <em>app1<\/em> &#8211; form\u00e9e de MySQL Router <strong>+<\/strong> mon application.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><em><u>Note<\/u>: <\/em><br><em>J&rsquo;utilise l&rsquo;image <a href=\"https:\/\/hub.docker.com\/r\/mysql\/mysql-server\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">Docker&nbsp;MySQL Server<\/a> support\u00e9e par l&rsquo;\u00e9quipe MySQL d&rsquo;Oracle.<\/em><\/p><\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>$ docker ps\nCONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS                   PORTS                 NAMES\ne65479bbc98c        mysql\/mysql-server:latest   \"\/entrypoint.sh mysq\u2026\"   9 minutes ago       Up 9 minutes (healthy)   3306\/tcp, 33060\/tcp   mysql_node3\nbc140052242c        mysql\/mysql-server:latest   \"\/entrypoint.sh mysq\u2026\"   9 minutes ago       Up 9 minutes (healthy)   3306\/tcp, 33060\/tcp   mysql_node2\n9ae71ad1cfce        mysql\/mysql-server:latest   \"\/entrypoint.sh mysq\u2026\"   9 minutes ago       Up 9 minutes (healthy)   3306\/tcp, 33060\/tcp   mysql_node1<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><em><u>Note<\/u>: <\/em><br><em>Je n&rsquo;aborde pas dans cet article la <strong>redondance<\/strong> de MySQL Router. Plusieurs sc\u00e9narios sont possibles, je te recommande de lire&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/lefred.be\/content\/mysql-innodb-cluster-is-the-router-a-single-point-of-failure\/\" target=\"_blank\">\u00e7a<\/a>, <a rel=\"noreferrer noopener\" href=\"https:\/\/lefred.be\/content\/mysql-router-ha-with-pacemaker\/\" target=\"_blank\">ceci<\/a> et <a rel=\"noreferrer noopener\" href=\"https:\/\/lefred.be\/content\/mysql-router-ha-with-keepalived\/\" target=\"_blank\">cela<\/a>.<\/em><\/p><\/blockquote>\n\n\n\n<p><strong>MySQL Shell<\/strong> n&rsquo;a pas besoin d&rsquo;\u00eatre install\u00e9 sur toutes les instances (contrairement \u00e0 MySQL 5.7, pour pouvoir rendre persistante la configuration).<br>ce client texte est <strong>beaucoup plus puissant<\/strong> que le client texte par d\u00e9faut. <br>Si tu ne le connais pas encore, <a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/downloads\/shell\/\" target=\"_blank\">essaie le<\/a> et tu verras tu ne pourras plus t&rsquo;en passer \ud83d\ude42<\/p>\n\n\n\n<p>En ce qui concerne les versions des logiciels, ce sont les plus r\u00e9centes \u00e0 ce jour (journ\u00e9e caniculaire du mois d&rsquo;ao\u00fbt <strong>2019<\/strong>):<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/downloads\/mysql\/5.7.html#downloads\" target=\"_blank\">MySQL Server <strong>8.0.17<\/strong> GA<\/a><\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/downloads\/router\/\" target=\"_blank\">MySQL Router <strong>8.0.17<\/strong> GA<\/a><\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/downloads\/shell\/\" target=\"_blank\">MySQL Shell     <strong>8.0.17<\/strong> GA<\/a> <\/li><\/ul>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><em><u>Note<\/u>: <\/em><br><em>Dans cet article j&rsquo;utilise la <strong>derni\u00e8re GA<\/strong> de MySQL Server 8.0. <\/em><br><em>En ce qui concerne MySQL <strong>Router<\/strong> et MySQL <strong>Shell<\/strong>, il est <u>imp\u00e9ratif<\/u> d&rsquo;utiliser&nbsp;la <strong>derni\u00e8re<\/strong> version courante (m\u00eame avec un server en 5.7).<\/em><\/p><\/blockquote>\n\n\n\n\n\n<h2 class=\"wp-block-heading\">V\u00e9rifier la configuration des instances<\/h2>\n\n\n\n<p>La premi\u00e8re \u00e9tape consiste \u00e0 s&rsquo;assurer que les instances MySQL sont correctement configur\u00e9es, en d&rsquo;autres termes \u00ab\u00a0InnoDB Cluster <a rel=\"noreferrer noopener\" aria-label=\"aware (opens in a new tab)\" href=\"https:\/\/www.youtube.com\/watch?v=8ECgLA2MjFo\" target=\"_blank\">aware<\/a>\u00a0\u00bb (ouais je sais je suis bilingue :D).<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><u><em>Note<\/em><\/u>:<br>J&rsquo;aime bien pr\u00e9-configurer les instances \u00e0 provisionner. A minima, l&rsquo;installation des plugins:<\/p><p>ex: plugin_load=group_replication.so &amp; plugin-load-add=mysql_clone.so<\/p><\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><em><u>Note<\/u>: <\/em><br><em>J&rsquo;utilise le compte utilisateur root pour configurer le cluster, cependant ce n&rsquo;est pas une bonne pratique. Il est possible (et souhaitable) de cr\u00e9er un compte utilisateur sp\u00e9cifique (ou plusieurs), avec les droits qui vont bien. <\/em><br><em>La m\u00e9thode recommand\u00e9e pour cr\u00e9er cet utilisateur et d&rsquo;utiliser l&rsquo;option <strong>clusterAdmin<\/strong> des m\u00e9thodes&nbsp;<strong>dba.<a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_dba.html#af4510380474d531a9fb775693e94eaac\" target=\"_blank\">configureInstance<\/a><\/strong>() et cluster.<a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_cluster.html#a92471821375405214215958ee924087f\" target=\"_blank\"><strong>addInstance<\/strong><\/a>(). <\/em><br><em>Plus d&rsquo;info <a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/mysql-innodb-cluster-production-deployment.html#mysql-innodb-cluster-user-privileges\" target=\"_blank\">ici (Paragraphe \u00ab\u00a0User Privileges\u00a0\u00bb)<\/a>.<\/em><\/p><\/blockquote>\n\n\n\n\n\n<p>La v\u00e9rification de la configuration se fait gr\u00e2ce \u00e0 MySQL Shell et la fonction <em><strong><a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_dba.html#aef7387e5a7be5b449af2559bb4e66099\" target=\"_blank\">checkInstanceConfiguration<\/a>()<\/strong><\/em>&nbsp;:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ mysqlsh\nMySQL Shell 8.0.17\n\nCopyright (c) 2016, 2019, Oracle and\/or its affiliates. All rights reserved.\nOracle is a registered trademark of Oracle Corporation and\/or its affiliates.\nOther names may be trademarks of their respective owners.\n\nType '\\help' or '\\?' for help; '\\quit' to exit.\nMySQL JS> dba.checkInstanceConfiguration('root@mysql_node1:3306')\nValidating MySQL instance at mysql_node1:3306 for use in an InnoDB cluster...\n\nThis instance reports its own address as mysql_node1:3306\n\nChecking whether existing tables comply with Group Replication requirements...\nNo incompatible tables detected\n\nChecking instance configuration...\n\nNOTE: Some configuration options need to be fixed:\n+--------------------------+---------------+----------------+--------------------------------------------------+\n| Variable                 | Current Value | Required Value | Note                                             |\n+--------------------------+---------------+----------------+--------------------------------------------------+\n| binlog_checksum          | CRC32         | NONE           | Update the server variable                       |\n| enforce_gtid_consistency | OFF           | ON             | Update read-only variable and restart the server |\n| gtid_mode                | OFF           | ON             | Update read-only variable and restart the server |\n| server_id                | 1             | &lt;unique ID>    | Update read-only variable and restart the server |\n+--------------------------+---------------+----------------+--------------------------------------------------+\n\nSome variables need to be changed, but cannot be done dynamically on the server.\nNOTE: Please use the dba.configureInstance() command to repair these issues.\n\n{\n    \"config_errors\": [\n        {\n            \"action\": \"server_update\", \n            \"current\": \"CRC32\", \n            \"option\": \"binlog_checksum\", \n            \"required\": \"NONE\"\n        }, \n        {\n            \"action\": \"server_update+restart\", \n            \"current\": \"OFF\", \n            \"option\": \"enforce_gtid_consistency\", \n            \"required\": \"ON\"\n        }, \n        {\n            \"action\": \"server_update+restart\", \n            \"current\": \"OFF\", \n            \"option\": \"gtid_mode\", \n            \"required\": \"ON\"\n        }, \n        {\n            \"action\": \"server_update+restart\", \n            \"current\": \"1\", \n            \"option\": \"server_id\", \n            \"required\": \"&lt;unique ID>\"\n        }\n    ], \n    \"status\": \"error\"\n}\n<\/code><\/pre>\n\n\n\n<p>La fonction <em><strong><a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_dba.html#aef7387e5a7be5b449af2559bb4e66099\" target=\"_blank\">checkInstanceConfiguration<\/a>()<\/strong><\/em> renvoie un document JSON (pratique pour l&rsquo;automatisation) avec la liste des t\u00e2ches \u00e0 effectuer pour \u00eatre conforme.<br><\/p>\n\n\n\n<p>Dans mon cas, avec l&rsquo;image <a rel=\"noreferrer noopener\" href=\"https:\/\/hub.docker.com\/r\/mysql\/mysql-server\/\" target=\"_blank\">Docker<\/a> Officielle de MySQL 8.0.17, par d\u00e9faut sous Ubuntu, niveau configuration j&rsquo;ai quasiment tout \u00e0 faire \ud83d\ude42<br><br>Configurons donc&#8230;<\/p>\n\n\n\n<p>J&rsquo;ai 2 solutions :<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>1\/ je pr\u00e9pare mes instances \u00ab\u00a0manuellement\u00a0\u00bb (cette t\u00e2che peut bien \u00e9videmment s&rsquo;automatiser) comme expliqu\u00e9 dans l&rsquo;article&nbsp;<a rel=\"noreferrer noopener\" href=\"http:\/\/dasini.net\/blog\/2016\/11\/08\/deployer-un-cluster-mysql-group-replication\/\" target=\"_blank\">comment configurer un groupe<\/a>.<\/li><li>2\/ je laisse <strong>MySQL Shell faire tout le boulot<\/strong> en utilisant la m\u00e9thode : <em><strong><a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_dba.html#af4510380474d531a9fb775693e94eaac\" target=\"_blank\">configureInstance<\/a>()<\/strong><\/em><\/li><\/ul>\n\n\n\n<p>je sens que ton c\u0153ur balance pour la 2&#8230; le mien aussi \ud83d\ude42<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MySQL JS> dba.configureInstance('root@mysql_node1:3306')\nConfiguring MySQL instance at mysql_node1:3306 for use in an InnoDB cluster...\n\nThis instance reports its own address as mysql_node1:3306\n\nNOTE: Some configuration options need to be fixed:\n+--------------------------+---------------+----------------+--------------------------------------------------+\n| Variable                 | Current Value | Required Value | Note                                             |\n+--------------------------+---------------+----------------+--------------------------------------------------+\n| binlog_checksum          | CRC32         | NONE           | Update the server variable                       |\n| enforce_gtid_consistency | OFF           | ON             | Update read-only variable and restart the server |\n| gtid_mode                | OFF           | ON             | Update read-only variable and restart the server |\n| server_id                | 1             | &lt;unique ID>    | Update read-only variable and restart the server |\n+--------------------------+---------------+----------------+--------------------------------------------------+\n\nSome variables need to be changed, but cannot be done dynamically on the server.\nDo you want to perform the required configuration changes? [y\/n]: y\nDo you want to restart the instance after configuring it? [y\/n]: n\nConfiguring instance...\nThe instance 'mysql_node1:3306' was configured for InnoDB cluster usage.\nNOTE: MySQL server needs to be restarted for configuration changes to take effect.<\/code><\/pre>\n\n\n\n<p>Petit apart\u00e9 sur la <u>persistance<\/u> des informations de configurations.<\/p>\n\n\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>Les informations de configurations sont automatiquement sauvegard\u00e9es avec la commande <a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/set-variable.html\" target=\"_blank\">SET PERSIST<\/a>. Commande super pratique (Cloud Friendly) apparue en 8.0, qui me permet de faire des changements de configurations \u00e0 chaud (online) <strong>et<\/strong> persistants, stock\u00e9s dans le fichier <strong><em>mysqld-auto.cnf<\/em><\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># cat \/var\/lib\/mysql\/mysqld-auto.cnf \n<\/code><\/pre>\n\n\n\n<p>On peut \u00e9galement voir ces informations en SQL, gr\u00e2ce \u00e0 la table <a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/persisted-variables-table.html\" target=\"_blank\"><strong>persisted_variables<\/strong><\/a> de <a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/performance-schema.html\" target=\"_blank\"><strong>performance_schema<\/strong><\/a> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT * FROM performance_schema.persisted_variables;<\/code><\/pre>\n\n\n\n<p>La persistance des changements ce fait automatiquement gr\u00e2ce au param\u00e8tre&nbsp;<a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/server-system-variables.html#sysvar_persisted_globals_load\" target=\"_blank\" rel=\"noreferrer noopener\">persisted_globals_load<\/a> activ\u00e9 par d\u00e9faut (ON). Elle est effective apr\u00e8s l&rsquo;ex\u00e9cution des commandes:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>dba.<a href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_dba.html#af4510380474d531a9fb775693e94eaac\" target=\"_blank\" rel=\"noreferrer noopener\">configureInstance<\/a>()<\/li><li>dba.<a href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_dba.html#a12f040129a2c4c301392dd69611da0c8\" target=\"_blank\" rel=\"noreferrer noopener\">createCluster<\/a>()<\/li><li>Cluster.<a href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_cluster.html#a92471821375405214215958ee924087f\" target=\"_blank\" rel=\"noreferrer noopener\">addInstance<\/a>()<\/li><li>Cluster.<a href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_cluster.html#a0c878a44100530d6a0e0cd2f893a71af\" target=\"_blank\" rel=\"noreferrer noopener\">removeInstance<\/a>()<\/li><li>Cluster.<a href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_cluster.html#af56d9116e7d6d0cd111aed0971163248\" target=\"_blank\" rel=\"noreferrer noopener\">rejoinInstance<\/a>()<\/li><\/ul>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><em><u>Note<\/u>: <\/em><br><em>je te recommande cet <a rel=\"noreferrer noopener\" href=\"http:\/\/mysql.wisborg.dk\/2018\/08\/14\/mysql-8-0-persisted-variables\/\" target=\"_blank\">excellent article sur les variables persistantes<\/a> de mon non moins excellent coll\u00e8gue <a rel=\"noreferrer noopener\" href=\"https:\/\/twitter.com\/JWKrogh\" target=\"_blank\">Jesper<\/a>.<\/em><\/p><\/blockquote>\n\n\n\n<p><a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/set-variable.html\" target=\"_blank\">SET PERSIST<\/a>&nbsp;est tr\u00e8s appr\u00e9ciable dans les environnements o\u00f9 acc\u00e9der au fichier de configuration est compliqu\u00e9 voir impossible (<em>Cloud Friendly<\/em>, je te dis!!!). <br>Cependant, dans un environnement plus ma\u00eetris\u00e9 (plus classique), il peut \u00eatre pr\u00e9f\u00e9rable, de centraliser toutes les informations de configurations dans le fichier de configuration original (my.cnf \/ my.ini).<br>Question de go\u00fbts et d&rsquo;habitudes&#8230;.<\/p>\n\n\n\n<p>C&rsquo;est bien \u00e9videmment possible gr\u00e2ce \u00e0 l&rsquo;option&nbsp;<em><strong>mycnfPath<\/strong><\/em> de la m\u00e9thode dba.<a href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_dba.html#af4510380474d531a9fb775693e94eaac\" target=\"_blank\" rel=\"noreferrer noopener\">configureInstance<\/a>().<\/p>\n\n\n\n<p>Exemple:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dba.configureInstance('root@mysql_node1:3306', {mycnfPath: \"\/etc\/my.cnf\"})<\/code><\/pre>\n\n\n\n<p>Tu as donc le <a href=\"https:\/\/www.youtube.com\/watch?v=M7W2I9FGF9U\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"choix (opens in a new tab)\">choix<\/a> !<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><em><u>Note<\/u>: <\/em><br><em>Assure toi d&rsquo;avoir les droits n\u00e9cessaires&nbsp;pour mettre \u00e0 jour le fichier de configuration de MySQL.<\/em><\/p><\/blockquote>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n\n\n<p>Fin de l&rsquo;apart\u00e9, revenons donc a la configuration de notre instance.<\/p>\n\n\n\n<p>Gr\u00e2ce \u00e0 ton \u0153il aiguis\u00e9, tu as remarqu\u00e9, que l&rsquo;outil me propose de red\u00e9marrer l&rsquo;instance MySQL, ce qui est bien pratique. <br>Cependant, dans le cas pr\u00e9sent, la plateforme que j&rsquo;utilise (<a rel=\"noreferrer noopener\" href=\"https:\/\/hub.docker.com\/r\/mysql\/mysql-server\/\" target=\"_blank\">image MySQL officielle Docker<\/a>) ne dispose pas d&rsquo;un processus de supervision de <strong><a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/mysqld.html\" target=\"_blank\"><em>mysqld<\/em><\/a><\/strong>&nbsp;(comme c&rsquo;est g\u00e9n\u00e9ralement le cas sur ta plateforme pr\u00e9f\u00e9r\u00e9e. Info <a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/restart.html\" target=\"_blank\">ici<\/a>). <br>En clair, je vais devoir red\u00e9marrer sans l&rsquo;outil (mais je devrai m&rsquo;en sortir&#8230; <a rel=\"noreferrer noopener\" href=\"https:\/\/www.youtube.com\/watch?v=9NnG54zTg8A\" target=\"_blank\">ou pas<\/a>&nbsp;\ud83d\ude42 ).<\/p>\n\n\n\n\n\n<p>L&rsquo;instance <em>mysql_node1<\/em> est configur\u00e9e et pr\u00eate pour \u00eatre un membre d&rsquo;un cluster MySQL InnoDB Cluster \\o\/<\/p>\n\n\n\n<p>Tu peux le v\u00e9rifier en red\u00e9marrant l&rsquo;instance MySQL et refaire un <em>checkInstanceConfiguration<\/em>&nbsp; :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MySQL JS> dba.checkInstanceConfiguration('root@mysql_node1:3306')\nValidating MySQL instance at mysql_node1:3306 for use in an InnoDB cluster...\n\nThis instance reports its own address as mysql_node1:3306\n\nChecking whether existing tables comply with Group Replication requirements...\nNo incompatible tables detected\n\nChecking instance configuration...\nInstance configuration is compatible with InnoDB cluster\n\nThe instance 'mysql_node1:3306' is valid for InnoDB cluster usage.\n\n{\n    \"status\": \"ok\"\n}<\/code><\/pre>\n\n\n\n<p>Statut: <strong>OK<\/strong>.<\/p>\n\n\n\n<p>La m\u00eame proc\u00e9dure doit \u00eatre appliqu\u00e9e sur <strong>les autres instances<\/strong> MySQL.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MySQL JS> dba.configureInstance('root@mysql_node2:3306')\n...\n\nMySQL JS> dba.configureInstance('root@mysql_node3:3306')\n...<\/code><\/pre>\n\n\n\n<p>Je me retrouve, apr\u00e8s configuration et red\u00e9marrage&nbsp; avec le r\u00e9sultat suivant:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ mysqlsh -- dba checkInstanceConfiguration --user=root  --host=mysql_node1\nValidating MySQL instance at mysql_node1:3306 for use in an InnoDB cluster...\n\nThis instance reports its own address as mysql_node1:3306\n\nChecking whether existing tables comply with Group Replication requirements...\nNo incompatible tables detected\n\nChecking instance configuration...\nInstance configuration is compatible with InnoDB cluster\n\nThe instance 'mysql_node1:3306' is valid for InnoDB cluster usage.\n\n{\n    \"status\": \"ok\"\n}\n\n\n$ mysqlsh -- dba checkInstanceConfiguration --user=root  --host=mysql_node2\nValidating MySQL instance at mysql_node2:3306 for use in an InnoDB cluster...\n\nThis instance reports its own address as mysql_node2:3306\n\nChecking whether existing tables comply with Group Replication requirements...\nNo incompatible tables detected\n\nChecking instance configuration...\nInstance configuration is compatible with InnoDB cluster\n\nThe instance 'mysql_node2:3306' is valid for InnoDB cluster usage.\n\n{\n    \"status\": \"ok\"\n}\n\n\n$ mysqlsh -- dba checkInstanceConfiguration --user=root  --host=mysql_node3\nValidating MySQL instance at mysql_node3:3306 for use in an InnoDB cluster...\n\nThis instance reports its own address as mysql_node3:3306\n\nChecking whether existing tables comply with Group Replication requirements...\nNo incompatible tables detected\n\nChecking instance configuration...\nInstance configuration is compatible with InnoDB cluster\n\nThe instance 'mysql_node3:3306' is valid for InnoDB cluster usage.\n\n{\n    \"status\": \"ok\"\n}<\/code><\/pre>\n\n\n\n<p><a rel=\"noreferrer noopener\" href=\"https:\/\/www.youtube.com\/watch?v=nZWXR23YPmw\" target=\"_blank\">Ca fait plaisir !<\/a><\/p>\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Cr\u00e9er le cluster<\/h2>\n\n\n\n<p>Une fois les 3 instances correctement configur\u00e9es, l&rsquo;\u00e9tape suivante consiste \u00e0 cr\u00e9er le cluster avec&nbsp;<strong><em>createCluster<\/em><\/strong>. <br>Cette fonction va \u00eatre jou\u00e9e sur le premier membre, l&rsquo;instance MySQL sur &nbsp;<em>mysql_node1<\/em>, &nbsp;elle va permettre de cr\u00e9er un cluster&#8230; d&rsquo;un n\u0153ud.&nbsp; <br>Bon faut bien commencer quelque part \ud83d\ude42 <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ mysqlsh root@mysql_node1\nMySQL Shell 8.0.17\n...\nServer version: 8.0.17 MySQL Community Server - GPL\nNo default schema selected; type \\use &lt;schema> to set one.\n\n\nMySQL mysql_node1 JS> var cluster = dba.createCluster('pocCluster')\nA new InnoDB cluster will be created on instance 'mysql_node1:3306'.\n\nValidating instance at mysql_node1:3306...\n\nThis instance reports its own address as mysql_node1:3306\n\nInstance configuration is suitable.\nCreating InnoDB cluster 'pocCluster' on 'mysql_node1:3306'...\n\nAdding Seed Instance...\nCluster successfully created. Use Cluster.addInstance() to add MySQL instances.\nAt least 3 instances are needed for the cluster to be able to withstand up to\none server failure.<\/code><\/pre>\n\n\n\n<p><em><strong>createCluster()<\/strong><\/em> prend comme param\u00e8tre le nom du cluster (pocCluster). <br>Tu peux aussi lui passer des param\u00e8tres facultatifs comme par exemple <strong style=\"\"><em>ipWhitelist<\/em><\/strong>, <strong style=\"\"><em>multiPrimary<\/em><\/strong>, <strong><em>adoptFromGR<\/em><\/strong>&#8230;<br>La liste exhaustive est dispo dans la <a rel=\"noreferrer noopener\" aria-label=\"doc (opens in a new tab)\" href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_dba.html#a12f040129a2c4c301392dd69611da0c8\" target=\"_blank\">doc<\/a>.<\/p>\n\n\n\n<p>On peut v\u00e9rifier l&rsquo;\u00e9tat du n\u0153ud dans le cluster avec&nbsp;<strong>status<em>()<\/em><\/strong> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MySQL mysql_node1 JS> cluster.status()\n{\n    \"clusterName\": \"pocCluster\", \n    \"defaultReplicaSet\": {\n        \"name\": \"default\", \n        \"primary\": \"mysql_node1:3306\", \n        \"ssl\": \"REQUIRED\", \n        \"status\": \"OK_NO_TOLERANCE\", \n        \"statusText\": \"Cluster is NOT tolerant to any failures.\", \n        \"topology\": {\n            \"mysql_node1:3306\": {\n                \"address\": \"mysql_node1:3306\", \n                \"mode\": \"R\/W\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"mysql_node1:3306\"\n}<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><em><u>Notes<\/u> :<\/em><br><em>Assure toi que ton DNS (ou \/etc\/hosts) est correctement configur\u00e9, sinon tu vas avoir des soucis de connections&#8230;<\/em><\/p><\/blockquote>\n\n\n\n<p>L&rsquo;ajouts des&nbsp;n\u0153uds suivant se fait avec <em><strong><a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_cluster.html#a92471821375405214215958ee924087f\" target=\"_blank\">addInstance<\/a>()<\/strong><\/em>.<\/p>\n\n\n\n<p><u>N\u0153ud 2<\/u> <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MySQL mysql_node1 JS> cluster.addInstance('root@mysql_node2')\n\nNOTE: The target instance 'mysql_node2:3306' has not been pre-provisioned (GTID set\nis empty). The Shell is unable to decide whether incremental distributed state\nrecovery can correctly provision it.\nThe safest and most convenient way to provision a new instance is through\nautomatic clone provisioning, which will completely overwrite the state of\n'mysql_node2:3306' with a physical snapshot from an existing cluster member. To\nuse this method by default, set the 'recoveryMethod' option to 'clone'.\n\nThe incremental distributed state recovery may be safely used if you are sure\nall updates ever executed in the cluster were done with GTIDs enabled, there\nare no purged transactions and the new instance contains the same GTID set as\nthe cluster or a subset of it. To use this method by default, set the\n'recoveryMethod' option to 'incremental'.\n\n\nPlease select a recovery method [C]lone\/[I]ncremental recovery\/[A]bort (default Clone): \nValidating instance at mysql_node2:3306...\n\nThis instance reports its own address as mysql_node2:3306\n\nInstance configuration is suitable.\nA new instance will be added to the InnoDB cluster. Depending on the amount of\ndata on the cluster this might take from a few seconds to several hours.\n\nAdding instance to the cluster...\n\nMonitoring recovery process of the new cluster member. Press ^C to stop monitoring and let it continue in background.\nClone based state recovery is now in progress.\n\nNOTE: A server restart is expected to happen as part of the clone process. If the\nserver does not support the RESTART command or does not come back after a\nwhile, you may need to manually start it back.\n\n* Waiting for clone to finish...\nNOTE: mysql_node2:3306 is being cloned from mysql_node1:3306\n** Stage DROP DATA: Completed\n** Clone Transfer  \n    FILE COPY  ############################################################  100%  Completed\n    PAGE COPY  ############################################################  100%  Completed\n    REDO COPY  ############################################################  100%  Completed\n** Stage RECOVERY: |\nNOTE: mysql_node2:3306 is shutting down...\n\n* Waiting for server restart... ready\n* mysql_node2:3306 has restarted, waiting for clone to finish...\n* Clone process has finished: 65.84 MB transferred in 3 sec (21.95 MB\/s)\n\nState recovery already finished for 'mysql_node2:3306'\n\nThe instance 'mysql_node2' was successfully added to the cluster.<\/code><\/pre>\n\n\n\n<p>Le n\u0153ud ajout\u00e9 doit \u00eatre \u00ab\u00a0synchro\u00a0\u00bb avec le cluster. <br>MySQL InnoDB Cluster peut le g\u00e9rer automatiquement pour toi.<\/p>\n\n\n\n<p>Il te propose 2 m\u00e9thodes, par d\u00e9faut, le <u>Clone<\/u> (une copy physique) ou alors l&rsquo;<u>Incr\u00e9mental<\/u> (copy logique).<br>Le clone est la m\u00e9thode la plus s\u00fbre d&rsquo;un point de vue coh\u00e9rence d&rsquo;ensemble du cluster, c&rsquo;est donc cette m\u00e9thode que je te recommande.<\/p>\n\n\n\n<p>Sauf si tu te portes garant de la coh\u00e9rence des donn\u00e9es du n\u0153ud \u00e0 ajouter (et accessoirement que ton volume de donn\u00e9es est important =&gt; temps de clonage important).<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n\n\n<p>Je me permet de porter \u00e0 ton attention sur un point <u>important<\/u>.<br>L&rsquo;une des \u00e9tapes du clonage, n\u00e9cessite un red\u00e9marrage du serveur MySQL.<br>Comme vu plus haut, si comme ici tes instances MySQL ne disposent pas d&rsquo;un processus de supervision de <strong><a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/mysqld.html\" target=\"_blank\"><em>mysqld<\/em><\/a><\/strong>, comme c&rsquo;est le cas avec Docker, bah MySQL ne va pas red\u00e9marrer automatiquement.<\/p>\n\n\n\n<p>Pas de panique, il faut red\u00e9marrer l&rsquo;instance a la mano au bon moment, c&rsquo;est \u00e0 dire, quand tu verras:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Note: * Waiting for server restart<\/code><\/pre>\n\n\n\n<p>Dans mon cas, dans une autre fen\u00eatre j&rsquo;ai ex\u00e9cut\u00e9:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>daz@daz-TECRA-Z40-B:~$ docker restart mysql_node2\n mysql_node2<\/code><\/pre>\n\n\n\n<p>Easy!<br>Ok, <a href=\"http:\/\/www.expressio.fr\/expressions\/ca-ne-casse-pas-trois-pattes-a-un-canard.php\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"\u00e7a ne casse pas 3 pattes \u00e0 un canard (s\u2019ouvre dans un nouvel onglet)\">\u00e7a ne casse pas 3 pattes \u00e0 un canard<\/a>, mais \u00e7a t&rsquo;\u00e9vitera de perdre du temps inutilement \ud83d\ude09<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n\n\n<p>Je peux voir le nouvel \u00e9tat de mon cluster avec status:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MySQL mysql_node1 JS> cluster.status()\n{\n    \"clusterName\": \"pocCluster\", \n    \"defaultReplicaSet\": {\n        \"name\": \"default\", \n        \"primary\": \"mysql_node1:3306\", \n        \"ssl\": \"REQUIRED\", \n        \"status\": \"OK_NO_TOLERANCE\", \n        \"statusText\": \"Cluster is NOT tolerant to any failures.\", \n        \"topology\": {\n            \"mysql_node1:3306\": {\n                \"address\": \"mysql_node1:3306\", \n                \"mode\": \"R\/W\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node2:3306\": {\n                \"address\": \"mysql_node2:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"mysql_node1:3306\"\n}<\/code><\/pre>\n\n\n\n<p>Ca prend forme&#8230;<br>Aller encore un n\u0153ud !<\/p>\n\n\n\n<p><u>N\u0153ud 3<\/u><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MySQL mysql_node1 JS> cluster.addInstance('root@mysql_node3')\n\nNOTE: The target instance 'mysql_node3:3306' has not been pre-provisioned (GTID set\nis empty). The Shell is unable to decide whether incremental distributed state\nrecovery can correctly provision it.\nThe safest and most convenient way to provision a new instance is through\nautomatic clone provisioning, which will completely overwrite the state of\n'mysql_node3:3306' with a physical snapshot from an existing cluster member. To\nuse this method by default, set the 'recoveryMethod' option to 'clone'.\n\nThe incremental distributed state recovery may be safely used if you are sure\nall updates ever executed in the cluster were done with GTIDs enabled, there\nare no purged transactions and the new instance contains the same GTID set as\nthe cluster or a subset of it. To use this method by default, set the\n'recoveryMethod' option to 'incremental'.\n\n\nPlease select a recovery method [C]lone\/[I]ncremental recovery\/[A]bort (default Clone): \nValidating instance at mysql_node3:3306...\n\nThis instance reports its own address as mysql_node3:3306\n\nInstance configuration is suitable.\nA new instance will be added to the InnoDB cluster. Depending on the amount of\ndata on the cluster this might take from a few seconds to several hours.\n\nAdding instance to the cluster...\n\nMonitoring recovery process of the new cluster member. Press ^C to stop monitoring and let it continue in background.\nClone based state recovery is now in progress.\n\nNOTE: A server restart is expected to happen as part of the clone process. If the\nserver does not support the RESTART command or does not come back after a\nwhile, you may need to manually start it back.\n\n* Waiting for clone to finish...\nNOTE: mysql_node3:3306 is being cloned from mysql_node1:3306\n** Stage DROP DATA: Completed\n** Clone Transfer  \n    FILE COPY  ############################################################  100%  Completed\n    PAGE COPY  ############################################################  100%  Completed\n    REDO COPY  ############################################################  100%  Completed\n\nNOTE: mysql_node3:3306 is shutting down...\n\n* Waiting for server restart... ready\n* mysql_node3:3306 has restarted, waiting for clone to finish...\n** Stage RESTART: Completed\n* Clone process has finished: 65.84 MB transferred in 2 sec (32.92 MB\/s)\n\nIncremental distributed state recovery is now in progress.\n\n* Waiting for distributed recovery to finish...\nNOTE: 'mysql_node3:3306' is being recovered from '&lt;NULL>:0'\n* Distributed recovery has finished\n\nThe instance 'mysql_node3' was successfully added to the cluster.<\/code><\/pre>\n\n\n\n<p>M\u00eame processus que pour le n\u0153ud 2.<\/p>\n\n\n\n<p>Le r\u00e9sultat final est:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MySQL mysql_node1 JS> cluster.status()\n{\n    \"clusterName\": \"pocCluster\", \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                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node2:3306\": {\n                \"address\": \"mysql_node2:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node3:3306\": {\n                \"address\": \"mysql_node3:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"mysql_node1:3306\"\n}<\/code><\/pre>\n\n\n\n<p><a href=\"https:\/\/media1.tenor.com\/images\/e6ca17bcb0b1c3b0de3def3dc80527b0\/tenor.gif?itemid=9880513\" target=\"_blank\" rel=\"noreferrer noopener\">Et voil\u00e0<\/a>!<\/p>\n\n\n\n<p>Un Cluster <u>MySQL Group Replication<\/u> de 3 n\u0153uds facilement et rapidement d\u00e9ploy\u00e9 gr\u00e2ce \u00e0 <u>MySQL Shell<\/u>, c&rsquo;est \u00e7a <strong>MySQL InnoDB Cluster<\/strong> (enfin presque, il manque encore un \u00e9l\u00e9ment).<\/p>\n\n\n\n<p>La configuration actuelle est la suivante:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>N\u0153ud 1 = mysql_node1 : Primaire (lecture\/\u00e9criture)<\/li><li>N\u0153ud 2 = mysql_node2 : Secondaire (lecture seule)<\/li><li>N\u0153ud 3 = mysql_node3 : Secondaire (lecture seule)<\/li><\/ul>\n\n\n\n<p><a href=\"https:\/\/www.youtube.com\/watch?v=BPSiB2vyHLU\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">Et qu&rsquo;est ce que l&rsquo;on fait maintenant<\/a> ???<\/p>\n\n\n\n<p>Le Router !<br><br>Le Router !<br><br>Le Router !<\/p>\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Configuration de MySQL Router<\/h2>\n\n\n\n<p>Il est recommand\u00e9 (mais <u>pas<\/u> obligatoire) d&rsquo;installer MySQL Router sur la machine h\u00f4te de l&rsquo;application, je vais donc suivre cette recommandation et l&rsquo;installer sur la machine <em>app1<\/em>.<\/p>\n\n\n\n<p>Si tu ne souhaites \/ peux \/ veux pas mettre MySQL Router sur l&rsquo;application, pas de souci.<br>Il te faudra au moins 2 instances de MySQL Router et de plus tu vas devoir  g\u00e9rer le HA du Router. <br>Plusieurs solutions sont envisageables comme par exemple :<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><em><a href=\"https:\/\/lefred.be\/content\/mysql-router-ha-with-pacemaker\/\" target=\"_blank\" rel=\"noreferrer noopener\">Pacemaker<\/a><\/em><\/li><li><em><a href=\"https:\/\/lefred.be\/content\/mysql-router-ha-with-keepalived\/\" target=\"_blank\" rel=\"noreferrer noopener\">Keepalived<\/a><\/em><\/li><\/ul>\n\n\n\n\n\n<h3 class=\"wp-block-heading\">Bootstrap MySQL Router<\/h3>\n\n\n\n<p>La premi\u00e8re \u00e9tape est le <a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/mysql-router\/8.0\/en\/mysql-router-deploying-bootstrapping.html\" target=\"_blank\">bootstrap<\/a>, c&rsquo;est \u00e0 dire cr\u00e9er LE lien entre MySQL Router et ton cluster. <br>Il faut fournir \u00e0 <a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/mysql-router\/8.0\/en\/\" target=\"_blank\">mysqlrouter<\/a> a minima l&rsquo;adresse d&rsquo;un membre du cluster :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>daz@app1:~$ mysqlrouter --bootstrap root@mysql_node1:3306 --conf-base-port 3306 --directory \/routerDir\/RouterPoC1\nPlease enter MySQL password for root: \n# Bootstrapping MySQL Router instance at '\/routerDir\/RouterPoC1'...\n\n- Checking for old Router accounts\n  - No prior Router accounts found\n- Creating mysql account mysql_router1_h8rjf49kin1d@'%' for cluster management\n- Storing account in keyring\n- Adjusting permissions of generated files\n- Creating configuration \/routerDir\/RouterPoC1\/mysqlrouter.conf\n\n# MySQL Router configured for the InnoDB cluster 'pocCluster'\n\nAfter this MySQL Router has been started with the generated configuration\n\n    $ mysqlrouter -c \/routerDir\/RouterPoC1\/mysqlrouter.conf\n\nthe cluster 'pocCluster' can be reached by connecting to:\n\n## MySQL Classic protocol\n\n- Read\/Write Connections: localhost:3306\n- Read\/Only Connections:  localhost:3307\n\n## MySQL X protocol\n\n- Read\/Write Connections: localhost:3308\n- Read\/Only Connections:  localhost:3309<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><em><u>Note<\/u>: <\/em><br>Il se peut que tu rencontres un probl\u00e8me de permission. Probablement d\u00fb \u00e0 la configuration de <a rel=\"noreferrer noopener\" href=\"https:\/\/fr.wikipedia.org\/wiki\/AppArmor\" target=\"_blank\">AppArmor<\/a>&#8230; <br>Google (ou \u00e9quivalent) est ton ami (ou pas) <br>Si tu es sous Ubuntu <a rel=\"noreferrer noopener\" href=\"https:\/\/doc.ubuntu-fr.org\/apparmor\" target=\"_blank\">clic ici<\/a>.<\/p><\/blockquote>\n\n\n\n<p>Quelques explications&#8230;<\/p>\n\n\n\n<p>J&rsquo;ai cr\u00e9\u00e9 une configuration diff\u00e9rente de celle par d\u00e9faut, en personnalisant avec quelques options:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/mysql-router\/8.0\/en\/mysqlrouter.html#option_mysqlrouter_conf-base-port\" target=\"_blank\">conf-base-port<\/a> : le port propos\u00e9 par d\u00e9faut est <strong>6446<\/strong> pour la lecture\/\u00e9criture. Dans mon cas, je veux utiliser le c\u00e9l\u00e8bre port <strong>3306<\/strong>.<\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/mysql-router\/8.0\/en\/mysqlrouter.html#option_mysqlrouter_directory\" target=\"_blank\">directory<\/a> : histoire de ranger tout le bazar de cette instance de Router dans le r\u00e9pertoire sp\u00e9cifi\u00e9. Bien utile si tu as plusieurs instances de Router sur la machine.<\/li><\/ul>\n\n\n\n<p>La liste compl\u00e8te des options est disponible <a href=\"https:\/\/dev.mysql.com\/doc\/mysql-router\/8.0\/en\/mysqlrouter.html#option_mysqlrouter_directory\" target=\"_blank\" rel=\"noreferrer noopener\">ici<\/a>.<\/p>\n\n\n\n<p>Pour r\u00e9sumer, 4 ports TCP ont \u00e9t\u00e9 configur\u00e9s, dont 2 pour les connexions MySQL traditionnelles:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>3306<\/strong> (au lieu de 6446 par d\u00e9faut) : lectures \/ \u00e9critures pour le n\u0153ud primaire (<a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/mysql-router\/8.0\/en\/mysql-router-conf-options.html#option_mysqlrouter_routing_strategy\" target=\"_blank\">strat\u00e9gie de routing<\/a>: <em>first available<\/em> par d\u00e9faut).<\/li><li><strong>3307<\/strong> (au lieu de 6447 par d\u00e9faut) : lectures seules pour les n\u0153uds secondaires (<a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/mysql-router\/8.0\/en\/mysql-router-conf-options.html#option_mysqlrouter_routing_strategy\" target=\"_blank\">strat\u00e9gie de routing<\/a>: <em>Round-Robin with fallback<\/em> par d\u00e9faut).<\/li><\/ul>\n\n\n\n<p>Et le pendant pour les connexions avec le protocole X (3308 &amp; 3309 (au lieu de respectivement 64460 &amp; 64470)), pour une utilisation <a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/document-store.html\" target=\"_blank\">NoSQL Document Store<\/a> de MySQL.<\/p>\n\n\n\n\n\n<p>Le fichier de configuration de MySQL Router contient quelques informations importantes, tel que le(s) port(s) \u00e0 utiliser par l&rsquo;application (comme vu pr\u00e9c\u00e9demment) :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>daz@app1:~$ cat \/routerDir\/RouterPoC1\/mysqlrouter.conf \n# File automatically generated during MySQL Router bootstrap\n[DEFAULT]\nlogging_folder=\/routerDir\/RouterPoC1\/log\nruntime_folder=\/routerDir\/RouterPoC1\/run\ndata_folder=\/routerDir\/RouterPoC1\/data\nkeyring_path=\/routerDir\/RouterPoC1\/data\/keyring\nmaster_key_path=\/routerDir\/RouterPoC1\/mysqlrouter.key\nconnect_timeout=15\nread_timeout=30\ndynamic_state=\/routerDir\/RouterPoC1\/data\/state.json\n\n[logger]\nlevel = INFO\n\n[metadata_cache:pocCluster]\nrouter_id=1\nuser=mysql_router1_h8rjf49kin1d\nmetadata_cluster=pocCluster\nttl=0.5\nuse_gr_notifications=0\n\n[routing:pocCluster_default_rw]\nbind_address=0.0.0.0\nbind_port=3306\ndestinations=metadata-cache:\/\/pocCluster\/default?role=PRIMARY\nrouting_strategy=first-available\nprotocol=classic\n\n[routing:pocCluster_default_ro]\nbind_address=0.0.0.0\nbind_port=3307\ndestinations=metadata-cache:\/\/pocCluster\/default?role=SECONDARY\nrouting_strategy=round-robin-with-fallback\nprotocol=classic\n\n[routing:pocCluster_default_x_rw]\nbind_address=0.0.0.0\nbind_port=3308\ndestinations=metadata-cache:\/\/pocCluster\/default?role=PRIMARY\nrouting_strategy=first-available\nprotocol=x\n\n[routing:pocCluster_default_x_ro]\nbind_address=0.0.0.0\nbind_port=3309\ndestinations=metadata-cache:\/\/pocCluster\/default?role=SECONDARY\nrouting_strategy=round-robin-with-fallback\nprotocol=x<\/code><\/pre>\n\n\n\n<p>Il est possible de modifier ce fichier, si besoin.<\/p>\n\n\n\n<p>Ensuite, il faut d\u00e9marrer MySQL Router avec le script <strong>start.sh<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>daz@app1:~$ \/routerDir\/RouterPoC1\/start.sh \nPID 20307 written to '\/routerDir\/RouterPoC1\/mysqlrouter.pid'\nlogging facility initialized, switching logging to loggers specified in configuration\n\n\ndaz@app1:~$ ps aux | grep mysqlroute[r]\ndaz      20307  0.8  0.0 697792  3612 pts\/3    Sl   Aug08  12:10 \/usr\/bin\/mysqlrouter -c \/routerDir\/RouterPoC1\/mysqlrouter.conf<\/code><\/pre>\n\n\n\n<p>L&rsquo;arr\u00eat du Router se fait avec le script <strong>stop.sh<\/strong> (mais tu l&rsquo;avais devin\u00e9).<\/p>\n\n\n\n<p>Voil\u00e0 pour le Router !<br>C&rsquo;est termin\u00e9 pour la phase de d\u00e9ploiement du cluster.<\/p>\n\n\n\n<p><strong>Simple<\/strong>, <strong>rapide<\/strong> et surtout <strong>facilement automatisable<\/strong>, tels sont les principales caract\u00e9ristiques du d\u00e9ploiement d&rsquo;un <strong>MySQL InnoDB Cluster<\/strong>. <br>Qualit\u00e9s qui constituent le c\u0153ur m\u00eame de l&rsquo;ADN de MySQL.<\/p>\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Se connecter au cluster<\/h2>\n\n\n\n<p>Ton MySQL InnoDB Cluster est maintenant <em>\u00ab\u00a0up and running\u00a0\u00bb<\/em>.&nbsp;<\/p>\n\n\n\n<p>Ton application va donc devoir se connecter au port 3306 (car on l&rsquo;a configur\u00e9 comme cela, sinon c&rsquo;est 6446 par d\u00e9faut) pour utiliser la base de donn\u00e9e. <br>D&rsquo;ailleurs, on peut dire que <u>du point de vue de l&rsquo;application, la base de donn\u00e9e c&rsquo;est MySQL Router<\/u>, sauf qu&rsquo;en r\u00e9alit\u00e9 ce n&rsquo;est pas 1 instance, mais bel et bien 3 instances MySQL qui sont en <em>backend<\/em>&nbsp;et ceci en toute transparence \\o\/.<\/p>\n\n\n\n<p>La partie utilisation du cluster&nbsp;est hors du scope de cet article, mais on peut facilement simuler le comportement de l&rsquo;application avec un client MySQL et MySQL router.<\/p>\n\n\n\n<p>A partir de <em>app1<\/em>, je peux par exemple me connecter avec MySQL Shell (mon application), en local, au port 3306, en mode SQL:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>daz@app1:~$ mysqlsh root@localhost:3306 --sql -e\"SELECT @@report_host AS 'Primary is';\"\nPrimary is\nmysql_node1<\/code><\/pre>\n\n\n\n<p>La connexion au port 3306, m&rsquo;envoie sur le membre primaire du cluster, ici le n\u0153ud : <em>mysql_node1<\/em>.<\/p>\n\n\n\n<p>Le param\u00e8tre <a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/replication-options-slave.html#option_mysqld_report-host\" target=\"_blank\"><strong>report_host<\/strong><\/a> (d\u00e9fini dans mon fichier de configuration) me renvoi la valeur du&nbsp; n\u0153ud 1, qui est pour l&rsquo;instant le primaire.<\/p>\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Gestion des n\u0153uds<\/h2>\n\n\n\n<p>Je te propose maintenant de passer en revues les commandes les plus utiles.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">R\u00e9cup\u00e9rer les m\u00e9ta-donn\u00e9es du cluster<\/h3>\n\n\n\n<p>La variable, commun\u00e9ment nomm\u00e9 <em><strong>cluster<\/strong><\/em>, &#8211; celle l\u00e0 m\u00eame utilis\u00e9e lors de la cr\u00e9ation du cluster:  <strong>var cluster = dba.createCluster(&lsquo;&#8230;&rsquo;)<\/strong> &#8211; qui permet d&rsquo;effectuer un grand nombre de manipulation sur ce dernier, a une dur\u00e9e de vie limit\u00e9e \u00e0 la session.<\/p>\n\n\n\n<p>Pour r\u00e9cup\u00e9rer ces informations relatives \u00e0 l\u2019\u00e9tat du cluster dans une nouvelle session il faut utiliser la m\u00e9thode dba.<a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_dba.html#a57075d1355767e1d3b433c7e21bb0cd5\" target=\"_blank\"><strong><em>getCluster<\/em><\/strong><\/a>&nbsp;:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ mysqlsh root@localhost:3306\nMySQL Shell 8.0.17\n...\nServer version: 8.0.17 MySQL Community Server - GPL\nNo default schema selected; type \\use &lt;schema> to set one.\n\n\nMySQL localhost JS > cluster.status()\nReferenceError: cluster is not defined\n\n\nMySQL localhost JS> var cluster = dba.getCluster('pocCluster')\n\n\nMySQL localhost JS > cluster.status()\n...<\/code><\/pre>\n\n\n\n<p>Une alternative pratique est d&rsquo;utiliser le param\u00e8tre <strong>&#8211;cluster<\/strong> lors de la connexion \u00e0 MySQL Shell:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ mysqlsh root@localhost:3306 --cluster\nMySQL Shell 8.0.17\n...\nYour MySQL connection id is 38657\nServer version: 8.0.17 MySQL Community Server - GPL\nNo default schema selected; type \\use &lt;schema> to set one.\nYou are connected to a member of cluster 'pocCluster'.\nVariable 'cluster' is set.\nUse cluster.status() in scripting mode to get status of this cluster or cluster.help() for more commands.\n\n\nMySQL localhost JS> cluster.status()\n{<\/code><\/pre>\n\n\n\n\n\n<h3 class=\"wp-block-heading\" id=\"mce_101\">Choisir un nouveau n\u0153ud primaire<\/h3>\n\n\n\n<p>Pour changer de primaire \u00e0 la vol\u00e9e, il faut utiliser la fonction <a rel=\"noreferrer noopener\" aria-label=\"setPrimaryInstance (opens in a new tab)\" href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_cluster.html#aea6b630d81222a82edf14ca10e4b1fa3\" target=\"_blank\">setPrimaryInstance<\/a>()<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>## Set New Primary\nMySQL mysql_node1 JS> cluster.setPrimaryInstance(\"mysql_node2:3306\")\nSetting instance 'mysql_node2:3306' as the primary instance of cluster 'pocCluster'...\n\nInstance 'mysql_node1:3306' was switched from PRIMARY to SECONDARY.\nInstance 'mysql_node2:3306' was switched from SECONDARY to PRIMARY.\nInstance 'mysql_node3:3306' remains SECONDARY.\n\nWARNING: The cluster internal session is not the primary member anymore. For cluster management operations please obtain a fresh cluster handle using &lt;Dba>.getCluster().\n\nThe instance 'mysql_node2:3306' was successfully elected as primary.\n\n... {Reconnection} ...\n\n\nMySQL mysql_node1 JS> cluster.status()\n{\n    \"clusterName\": \"pocCluster\", \n    \"defaultReplicaSet\": {\n        \"name\": \"default\", \n        \"primary\": \"mysql_node2: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\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node2:3306\": {\n                \"address\": \"mysql_node2:3306\", \n                \"mode\": \"R\/W\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node3:3306\": {\n                \"address\": \"mysql_node3:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"mysql_node1:3306\"\n}<\/code><\/pre>\n\n\n\n\n\n<h3 class=\"wp-block-heading\" id=\"mce_109\">D\u00e9crire le cluster<\/h3>\n\n\n\n<p><a rel=\"noreferrer noopener\" aria-label=\"describe (opens in a new tab)\" href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_cluster.html#a4b2783f5f1f780fc83f17f17d1935469\" target=\"_blank\">describe<\/a>() d\u00e9crit la structure du cluster:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MySQL mysql_node1 JS> cluster.describe()\n{\n    \"clusterName\": \"pocCluster\", \n    \"defaultReplicaSet\": {\n        \"name\": \"default\", \n        \"topology\": [\n            {\n                \"address\": \"mysql_node1:3306\", \n                \"label\": \"mysql_node1:3306\", \n                \"role\": \"HA\", \n                \"version\": \"8.0.17\"\n            }, \n            {\n                \"address\": \"mysql_node2:3306\", \n                \"label\": \"mysql_node2:3306\", \n                \"role\": \"HA\", \n                \"version\": \"8.0.17\"\n            }, \n            {\n                \"address\": \"mysql_node3:3306\", \n                \"label\": \"mysql_node3:3306\", \n                \"role\": \"HA\", \n                \"version\": \"8.0.17\"\n            }\n        ], \n        \"topologyMode\": \"Single-Primary\"\n    }\n}<\/code><\/pre>\n\n\n\n\n\n<h3 class=\"wp-block-heading\" id=\"mce_114\">Passer en mode multi-primary<\/h3>\n\n\n\n<p>Le passage du mode single-primary \u00e0 multi-primary se fait avec la fonction <a rel=\"noreferrer noopener\" aria-label=\"switchToMultiPrimaryMode (opens in a new tab)\" href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_cluster.html#ab36ba1da480e88b4e75647bf7a25cc9a\" target=\"_blank\">switchToMultiPrimaryMode<\/a>():<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>## Switch To Multi Primary Mode\nMySQL mysql_node1 JS> cluster.switchToMultiPrimaryMode()\nSwitching cluster 'pocCluster' to Multi-Primary mode...\n\nInstance 'mysql_node1:3306' was switched from SECONDARY to PRIMARY.\nInstance 'mysql_node2:3306' remains PRIMARY.\nInstance 'mysql_node3:3306' was switched from SECONDARY to PRIMARY.\n\nThe cluster successfully switched to Multi-Primary mode.\n\n\nMySQL mysql_node1 JS> cluster.status()\n{\n    \"clusterName\": \"pocCluster\", \n    \"defaultReplicaSet\": {\n        \"name\": \"default\", \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                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node2:3306\": {\n                \"address\": \"mysql_node2:3306\", \n                \"mode\": \"R\/W\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node3:3306\": {\n                \"address\": \"mysql_node3:3306\", \n                \"mode\": \"R\/W\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }\n        }, \n        \"topologyMode\": \"Multi-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"mysql_node1:3306\"\n}<\/code><\/pre>\n\n\n\n\n\n<h3 class=\"wp-block-heading\" id=\"mce_114\">Passer en mode single-primary<\/h3>\n\n\n\n<p>Le passage du mode multi-primary \u00e0 single-primary se fait avec la fonction <a rel=\"noreferrer noopener\" aria-label=\"switchToSinglePrimaryMode (opens in a new tab)\" href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_cluster.html#ab5bdda064da720506034f05c924058e0\" target=\"_blank\">switchToSinglePrimaryMode<\/a>():<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>## switch To Single PrimaryMode\nMySQL mysql_node1 JS> cluster.switchToSinglePrimaryMode(\"mysql_node1:3306\")\nSwitching cluster 'pocCluster' to Single-Primary mode...\n\nInstance 'mysql_node1:3306' remains PRIMARY.\nInstance 'mysql_node2:3306' was switched from PRIMARY to SECONDARY.\nInstance 'mysql_node3:3306' was switched from PRIMARY to SECONDARY.\n\nWARNING: Existing connections that expected a R\/W connection must be disconnected, i.e. instances that became SECONDARY.\n\nThe cluster successfully switched to Single-Primary mode.\n\n... {Reconnection} ...\n\n\nMySQL mysql_node1 JS> cluster.status()\n{\n    \"clusterName\": \"pocCluster\", \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                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node2:3306\": {\n                \"address\": \"mysql_node2:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node3:3306\": {\n                \"address\": \"mysql_node3:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"mysql_node1:3306\"\n}<\/code><\/pre>\n\n\n\n\n\n<h3 class=\"wp-block-heading\" id=\"mce_109\">Database Failover<\/h3>\n\n\n\n<p>Le basculement niveau base de donn\u00e9es (changement de primaire) est automatiquement g\u00e9r\u00e9 par les membres du cluster entre eux.<\/p>\n\n\n\n<p>Par exemple, si j&rsquo;ai un crash du n\u0153ud primaire : <em>mysql_node1<\/em>.<br>Les connexions a MySQL Router vont avoir la vue suivante:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ mysqlsh root@localhost:3306 --cluster\nMySQL Shell 8.0.17\n...\n\n\nMySQL localhost JS> cluster.status()\n{\n    \"clusterName\": \"pocCluster\", \n    \"defaultReplicaSet\": {\n        \"name\": \"default\", \n        \"primary\": \"mysql_node2:3306\", \n        \"ssl\": \"REQUIRED\", \n        \"status\": \"OK_NO_TOLERANCE\", \n        \"statusText\": \"Cluster is NOT tolerant to any failures. 1 member is not active\", \n        \"topology\": {\n            \"mysql_node1:3306\": {\n                \"address\": \"mysql_node1:3306\", \n                \"mode\": \"n\/a\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"shellConnectError\": \"MySQL Error 2003 (HY000): Can't connect to MySQL server on 'mysql_node1' (113)\", \n                \"status\": \"(MISSING)\"\n            }, \n            \"mysql_node2:3306\": {\n                \"address\": \"mysql_node2:3306\", \n                \"mode\": \"R\/W\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node3:3306\": {\n                \"address\": \"mysql_node3:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"mysql_node2:3306\"\n}<\/code><\/pre>\n\n\n\n<p>Un nouveau primaire est \u00e9lu par le groupe, ici <em>mysql_node2<\/em>.<br><em>mysql_node1<\/em> est lui port\u00e9 disparu (<a rel=\"noreferrer noopener\" href=\"https:\/\/www.youtube.com\/watch?v=7ceNf9qJjgc\" target=\"_blank\">MIA<\/a>).<\/p>\n\n\n\n<p>Les donn\u00e9es de configuration du cluster \u00e9tant sauvegard\u00e9es, une fois le n\u0153ud red\u00e9marr\u00e9 \/ r\u00e9par\u00e9 \/ restaur\u00e9, il fera automatiquement parti du cluster \u00e0 nouveau. et il aura un r\u00f4le de secondaire, c&rsquo;est \u00e0 dire en lecture seule (si je suis en single-primary).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MySQL localhost JS> cluster.status()\n{\n    \"clusterName\": \"pocCluster\", \n    \"defaultReplicaSet\": {\n        \"name\": \"default\", \n        \"primary\": \"mysql_node2: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\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node2:3306\": {\n                \"address\": \"mysql_node2:3306\", \n                \"mode\": \"R\/W\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node3:3306\": {\n                \"address\": \"mysql_node3:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"mysql_node2:3306\"\n}<\/code><\/pre>\n\n\n\n<p>En cas de configuration non persistante, un <em><strong><a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_cluster.html#af56d9116e7d6d0cd111aed0971163248\" target=\"_blank\">rejoinInstance<\/a><\/strong><\/em>() est n\u00e9cessaire pour remettre le n\u0153ud dans le cluster.<\/p>\n\n\n\n\n\n<h3 class=\"wp-block-heading\">Supprimer un membre du groupe<\/h3>\n\n\n\n<p>Pour supprimer un n\u0153ud du cluster, c&rsquo;est la fonction <a rel=\"noreferrer noopener\" aria-label=\"removeInstance (opens in a new tab)\" href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_cluster.html#a0c878a44100530d6a0e0cd2f893a71af\" target=\"_blank\">removeInstance<\/a>():<br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>## Remove a member from the group\nMySQL localhost JS> cluster.status()\n{\n    \"clusterName\": \"pocCluster\", \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                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node2:3306\": {\n                \"address\": \"mysql_node2:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node3:3306\": {\n                \"address\": \"mysql_node3:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"mysql_node1:3306\"\n}\n\n\nMySQL localhost JS> cluster.removeInstance(\"mysql_node3:3306\")\nThe instance will be removed from the InnoDB cluster. Depending on the instance\nbeing the Seed or not, the Metadata session might become invalid. If so, please\nstart a new session to the Metadata Storage R\/W instance.\n\nInstance 'mysql_node3:3306' is attempting to leave the cluster...\n\nThe instance 'mysql_node3:3306' was successfully removed from the cluster.\n\n\nMySQL localhost JS> cluster.status()\n{\n    \"clusterName\": \"pocCluster\", \n    \"defaultReplicaSet\": {\n        \"name\": \"default\", \n        \"primary\": \"mysql_node1:3306\", \n        \"ssl\": \"REQUIRED\", \n        \"status\": \"OK_NO_TOLERANCE\", \n        \"statusText\": \"Cluster is NOT tolerant to any failures.\", \n        \"topology\": {\n            \"mysql_node1:3306\": {\n                \"address\": \"mysql_node1:3306\", \n                \"mode\": \"R\/W\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node2:3306\": {\n                \"address\": \"mysql_node2:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"mysql_node1:3306\"\n}<\/code><\/pre>\n\n\n\n<p>Pour remettre le membre, il suffit d&rsquo;utiliser la fonction addInstance():<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MySQL localhost JS> cluster.addInstance(\"mysql_node3:3306\")\nThe safest and most convenient way to provision a new instance is through\nautomatic clone provisioning, which will completely overwrite the state of\n'mysql_node3:3306' with a physical snapshot from an existing cluster member. To\nuse this method by default, set the 'recoveryMethod' option to 'clone'.\n\nThe incremental distributed state recovery may be safely used if you are sure\nall updates ever executed in the cluster were done with GTIDs enabled, there\nare no purged transactions and the new instance contains the same GTID set as\nthe cluster or a subset of it. To use this method by default, set the\n'recoveryMethod' option to 'incremental'.\n\nIncremental distributed state recovery was selected because it seems to be safely usable.\nValidating instance at mysql_node3:3306...\n\nThis instance reports its own address as mysql_node3:3306\n\nInstance configuration is suitable.\nA new instance will be added to the InnoDB cluster. Depending on the amount of\ndata on the cluster this might take from a few seconds to several hours.\n\nAdding instance to the cluster...\n\nMonitoring recovery process of the new cluster member. Press ^C to stop monitoring and let it continue in background.\nState recovery already finished for 'mysql_node3:3306'\n\nThe instance 'mysql_node3:3306' was successfully added to the cluster.<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>MySQL localhost JS> cluster.status()\n{\n    \"clusterName\": \"pocCluster\", \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                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node2:3306\": {\n                \"address\": \"mysql_node2:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node3:3306\": {\n                \"address\": \"mysql_node3:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"mysql_node1:3306\"\n}<\/code><\/pre>\n\n\n\n\n\n<h3 class=\"wp-block-heading\">Repartir apr\u00e8s un arr\u00eat total du cluster<\/h3>\n\n\n\n<p>En cas d&rsquo;arr\u00eat total du cluster i.e. toutes les instances&nbsp;sont \u00e9teintes, il faut utiliser, une fois les instances MySQL de nouveau d\u00e9marr\u00e9es &nbsp;<em><a rel=\"noreferrer noopener\" aria-label=\"rebootClusterFromCompleteOutage (opens in a new tab)\" href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_dba.html#a64e1c660242082f000a6e0eb60140769\" target=\"_blank\"><strong>rebootClusterFromCompleteOutage<\/strong><\/a><\/em><strong><em>()<\/em><\/strong>.<\/p>\n\n\n\n<p>Le reboot doit se faire sur l\u2019instance la plus \u00e0 jour, dans le cas contraire, l&rsquo;erreur suivante (<em><strong>Dba.rebootClusterFromCompleteOutage: The active session instance isn&rsquo;t the most updated in comparison with the ONLINE instances of the Cluster&rsquo;s metadata.<\/strong><\/em>) est lanc\u00e9e :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ mysqlsh root@mysql_node1:3306\nMySQL Shell 8.0.17\n...\n\n\nMySQL mysql_node3 JS> var cluster = dba.rebootClusterFromCompleteOutage('pocCluster')\nReconfiguring the cluster 'pocCluster' from complete outage...\n\nThe instance 'mysql_node1:3306' was part of the cluster configuration.\nWould you like to rejoin it to the cluster? [y\/N]: y\n\nThe instance 'mysql_node2:3306' was part of the cluster configuration.\nWould you like to rejoin it to the cluster? [y\/N]: y\n\nDba.rebootClusterFromCompleteOutage: The active session instance isn't the most updated in comparison with the ONLINE instances of the Cluster's metadata. Please use the most up to date instance: 'mysql_node1:3306'. (RuntimeError)<\/code><\/pre>\n\n\n\n<p>L&rsquo;outil \u00e0 la gentillesse de m&rsquo;indiquer quel est le membre le plus \u00e0 jour, ici <em>mysql_node1:3306<\/em>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ mysqlsh root@mysql_node1:3306\nMySQL Shell 8.0.17\n...\n\n\nMySQL mysql_node1 JS>  var cluster = dba.rebootClusterFromCompleteOutage('pocCluster')\nReconfiguring the cluster 'pocCluster' from complete outage...\n\nThe instance 'mysql_node2:3306' was part of the cluster configuration.\nWould you like to rejoin it to the cluster? [y\/N]: y\n\nThe instance 'mysql_node3:3306' was part of the cluster configuration.\nWould you like to rejoin it to the cluster? [y\/N]: y\n\nThe safest and most convenient way to provision a new instance is through\nautomatic clone provisioning, which will completely overwrite the state of\n'mysql_node1:3306' with a physical snapshot from an existing cluster member. To\nuse this method by default, set the 'recoveryMethod' option to 'clone'.\n\nThe incremental distributed state recovery may be safely used if you are sure\nall updates ever executed in the cluster were done with GTIDs enabled, there\nare no purged transactions and the new instance contains the same GTID set as\nthe cluster or a subset of it. To use this method by default, set the\n'recoveryMethod' option to 'incremental'.\n\nIncremental distributed state recovery was selected because it seems to be safely usable.\n\nThe cluster was successfully rebooted.<\/code><\/pre>\n\n\n\n<p>Je peux maintenant me connecter \u00e0 nouveau \u00e0 mon cluster (en utilisant le Router):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ mysqlsh root@localhost:3306 --cluster\nMySQL Shell 8.0.17\n...\n\n\nMySQL localhost JS> cluster.status()\n{\n    \"clusterName\": \"pocCluster\", \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                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node2:3306\": {\n                \"address\": \"mysql_node2:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node3:3306\": {\n                \"address\": \"mysql_node3:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"mysql_node1:3306\"\n}<\/code><\/pre>\n\n\n\n<p>Le membre sur lequel la commande a \u00e9t\u00e9 ex\u00e9cut\u00e9e est le nouveau primaire.<\/p>\n\n\n\n\n\n<h3 class=\"wp-block-heading\">Perte du quorum<\/h3>\n\n\n\n<p>Si le cluster perd plus de la moiti\u00e9 de ses membres &#8211; i.e. majorit\u00e9 de n\u0153uds inaccessibles &#8211; (<strong>crash<\/strong> ou <strong><a rel=\"noreferrer noopener\" href=\"https:\/\/fr.wikipedia.org\/wiki\/Split-brain\" target=\"_blank\">split brain<\/a><\/strong> par exemple) il se retrouve dans un \u00e9tat assez d\u00e9sagr\u00e9able, <a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/5.7\/en\/group-replication-network-partitioning.html\" target=\"_blank\">network partitioning<\/a>, en clair il faut une intervention externe au cluster pour permettre aux membres restant de continuer \u00e0 faire leur boulot.<br><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><em><u>Note<\/u><\/em>: <br>Par perte j&rsquo;entend arr\u00eat non pr\u00e9vu (crash). En cas d&rsquo;arr\u00eat normal ou propre, m\u00eame si le cluster perd son quorum (dans ce cas pr\u00e9sent arr\u00eat normal de 2 n\u0153uds), le n\u0153ud survivant sait que les autres n\u0153uds ne sont plus l\u00e0 (en clair pas de risque de split brain) donc le cluster continue de fonctionner. Mais c&rsquo;est un cluster avec un seul n\u0153ud&#8230;&nbsp; <\/p><\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>$ mysqlsh root@mysql_node3:3306 --cluster\nMySQL Shell 8.0.17\n...\nWARNING: Cluster has no quorum and cannot process write transactions: 2 out of 3 members of the InnoDB cluster are unreachable from the member we\u2019re connected to, which is not sufficient for a quorum to be reached.\nWARNING: You are connected to an instance in state 'Read Only'\nWrite operations on the InnoDB cluster will not be allowed.\n\nYou are connected to a member of cluster 'pocCluster'.\nVariable 'cluster' is set.\nUse cluster.status() in scripting mode to get status of this cluster or cluster.help() for more commands.\n\n\nMySQL mysql_node3 JS> cluster.status()\n{\n    \"clusterName\": \"pocCluster\", \n    \"defaultReplicaSet\": {\n        \"name\": \"default\", \n        \"primary\": \"mysql_node1:3306\", \n        \"ssl\": \"REQUIRED\", \n        \"status\": \"NO_QUORUM\", \n        \"statusText\": \"Cluster has no quorum as visible from 'mysql_node3:3306' and cannot process write transactions. 2 members are not active\", \n        \"topology\": {\n            \"mysql_node1:3306\": {\n                \"address\": \"mysql_node1:3306\", \n                \"mode\": \"n\/a\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"shellConnectError\": \"MySQL Error 2003 (HY000): Can't connect to MySQL server on 'mysql_node1' (113)\", \n                \"status\": \"UNREACHABLE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node2:3306\": {\n                \"address\": \"mysql_node2:3306\", \n                \"mode\": \"n\/a\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"shellConnectError\": \"MySQL Error 2003 (HY000): Can't connect to MySQL server on 'mysql_node2' (113)\", \n                \"status\": \"UNREACHABLE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node3:3306\": {\n                \"address\": \"mysql_node3:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"mysql_node3:3306\"\n}<\/code><\/pre>\n\n\n\n<p><em>mysql_node1<\/em> &amp; <em>mysql_node2<\/em> sont inaccessibles (e.g. le datacenter qui les h\u00e9berge est tomb\u00e9).<br><\/p>\n\n\n\n<p>Le failover automatique ne peut pas s\u2019enclencher, le n\u0153ud survivant <em>mysql_node3<\/em> se met en mode \u00ab\u00a0protection\u00a0\u00bb contre les incoh\u00e9rences (inconsistency) en se pla\u00e7ant automatiquement en lecture seule.<br>Il n\u2019acceptera donc aucune \u00e9criture tant qu&rsquo;il n&rsquo;aura pas re\u00e7u l&rsquo;ordre de le faire.<\/p>\n\n\n\n<p>Cette intervention se nomme, d\u00e9blocage de partition, et elle s&rsquo;ex\u00e9cute \u00e0 l&rsquo;aide de la fonction <a rel=\"noreferrer noopener\" aria-label=\"forceQuorumUsingPartitionOf (opens in a new tab)\" href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_cluster.html#ad9575e2950ef084685f4c56dbc8e62cc\" target=\"_blank\">forceQuorumUsingPartitionOf<\/a>():<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MySQL mysql_node3 JS> cluster.forceQuorumUsingPartitionOf(\"root@mysql_node3:3306\")\nRestoring replicaset 'default' from loss of quorum, by using the partition composed of [mysql_node3:3306]\n\nRestoring the InnoDB cluster ...\n\nThe InnoDB cluster was successfully restored using the partition from the instance 'root@mysql_node3:3306'.\n\nWARNING: To avoid a split-brain scenario, ensure that all other members of the replicaset are removed or joined back to the group that was restored.\n\n\nMySQL mysql_node3 JS> cluster.status()\n{\n    \"clusterName\": \"pocCluster\", \n    \"defaultReplicaSet\": {\n        \"name\": \"default\", \n        \"primary\": \"mysql_node3:3306\", \n        \"ssl\": \"REQUIRED\", \n        \"status\": \"OK_NO_TOLERANCE\", \n        \"statusText\": \"Cluster is NOT tolerant to any failures. 2 members are not active\", \n        \"topology\": {\n            \"mysql_node1:3306\": {\n                \"address\": \"mysql_node1:3306\", \n                \"mode\": \"n\/a\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"shellConnectError\": \"MySQL Error 2003 (HY000): Can't connect to MySQL server on 'mysql_node1' (113)\", \n                \"status\": \"(MISSING)\"\n            }, \n            \"mysql_node2:3306\": {\n                \"address\": \"mysql_node2:3306\", \n                \"mode\": \"n\/a\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"shellConnectError\": \"MySQL Error 2003 (HY000): Can't connect to MySQL server on 'mysql_node2' (113)\", \n                \"status\": \"(MISSING)\"\n            }, \n            \"mysql_node3:3306\": {\n                \"address\": \"mysql_node3:3306\", \n                \"mode\": \"R\/W\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"mysql_node3:3306\"\n}<\/code><\/pre>\n\n\n\n<p>Evidemment, sauf si tu es joueur \ud83d\ude42 , il faut \u00e9viter de rester trop longtemps dans cet \u00e9tat.<\/p>\n\n\n\n<p>Une fois les instances remisent en condition, il faut les remettre dans le cluster. Le process d\u00e9pends du sc\u00e9nario de la panne.<\/p>\n\n\n\n<p>Dans le cas le plus favorable, une fois le soucis identifi\u00e9 et r\u00e9par\u00e9, il suffit de red\u00e9marrer l&rsquo;instance. Gr\u00e2ce au syst\u00e8me de restauration du cluster, elle se mettra \u00e0 jour automatiquement.<\/p>\n\n\n\n<p>Exemple avec <em>mysql_node2<\/em>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MySQL localhost JS> cluster.status()\n{\n    \"clusterName\": \"pocCluster\", \n    \"defaultReplicaSet\": {\n        \"name\": \"default\", \n        \"primary\": \"mysql_node3:3306\", \n        \"ssl\": \"REQUIRED\", \n        \"status\": \"OK_NO_TOLERANCE\", \n        \"statusText\": \"Cluster is NOT tolerant to any failures. 1 member is not active\", \n        \"topology\": {\n            \"mysql_node1:3306\": {\n                \"address\": \"mysql_node1:3306\", \n                \"mode\": \"n\/a\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"shellConnectError\": \"MySQL Error 2003 (HY000): Can't connect to MySQL server on 'mysql_node1' (113)\", \n                \"status\": \"(MISSING)\"\n            }, \n            \"mysql_node2:3306\": {\n                \"address\": \"mysql_node2:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node3:3306\": {\n                \"address\": \"mysql_node3:3306\", \n                \"mode\": \"R\/W\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"mysql_node3:3306\"\n}<\/code><\/pre>\n\n\n\n\n\n<p>Autre hypoth\u00e8se plus emb\u00eatante, une corruption des donn\u00e9es irr\u00e9versible\u2026<br> Dans ce cas une solution consiste \u00e0 re-provisionner le n\u0153ud.<\/p>\n\n\n\n<p>Il faut tout d&rsquo;abord, r\u00e9initialiser les m\u00e9ta donn\u00e9es du cluster avec un <a rel=\"noreferrer noopener\" aria-label=\"rescan (opens in a new tab)\" href=\"https:\/\/dev.mysql.com\/doc\/dev\/mysqlsh-api-javascript\/8.0\/classmysqlsh_1_1dba_1_1_cluster.html#a96c63d07c753c4482d60fc6eea9a895f\" target=\"_blank\">rescan<\/a>().<\/p>\n\n\n\n<p>Exemple avec <em>mysql_node1<\/em> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MySQL localhost JS> cluster.status()\n{\n    \"clusterName\": \"pocCluster\", \n    \"defaultReplicaSet\": {\n        \"name\": \"default\", \n        \"primary\": \"mysql_node3:3306\", \n        \"ssl\": \"REQUIRED\", \n        \"status\": \"OK_NO_TOLERANCE\", \n        \"statusText\": \"Cluster is NOT tolerant to any failures. 1 member is not active\", \n        \"topology\": {\n            \"mysql_node1:3306\": {\n                \"address\": \"mysql_node1:3306\", \n                \"mode\": \"n\/a\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"shellConnectError\": \"MySQL Error 2003 (HY000): Can't connect to MySQL server on 'mysql_node1' (113)\", \n                \"status\": \"(MISSING)\"\n            }, \n            \"mysql_node2:3306\": {\n                \"address\": \"mysql_node2:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node3:3306\": {\n                \"address\": \"mysql_node3:3306\", \n                \"mode\": \"R\/W\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"mysql_node3:3306\"\n}<\/code><\/pre>\n\n\n\n<p>Rescan() :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MySQL localhost JS> cluster.rescan()\nRescanning the cluster...\n\nResult of the rescanning operation for the 'default' ReplicaSet:\n{\n    \"name\": \"default\", \n    \"newTopologyMode\": null, \n    \"newlyDiscoveredInstances\": [], \n    \"unavailableInstances\": [\n        {\n            \"host\": \"mysql_node1:3306\", \n            \"label\": \"mysql_node1:3306\", \n            \"member_id\": \"f6cdb648-b9d7-11e9-bf6c-0242ac14000b\"\n        }\n    ]\n}\n\nThe instance 'mysql_node1:3306' is no longer part of the ReplicaSet.\nThe instance is either offline or left the HA group. You can try to add it to the cluster again with the cluster.rejoinInstance('mysql_node1:3306') command or you can remove it from the cluster configuration.\nWould you like to remove it from the cluster metadata? [Y\/n]: Y\nRemoving instance from the cluster metadata...\nThe instance 'mysql_node1:3306' was successfully removed from the cluster metadata.<\/code><\/pre>\n\n\n\n<p>Nouvel \u00e9tat du cluster, plus d&rsquo;info sur <em>mysql_node1<\/em> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MySQL localhost JS> cluster.status()\n{\n    \"clusterName\": \"pocCluster\", \n    \"defaultReplicaSet\": {\n        \"name\": \"default\", \n        \"primary\": \"mysql_node3:3306\", \n        \"ssl\": \"REQUIRED\", \n        \"status\": \"OK_NO_TOLERANCE\", \n        \"statusText\": \"Cluster is NOT tolerant to any failures.\", \n        \"topology\": {\n            \"mysql_node2:3306\": {\n                \"address\": \"mysql_node2:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node3:3306\": {\n                \"address\": \"mysql_node3:3306\", \n                \"mode\": \"R\/W\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"mysql_node3:3306\"\n}<\/code><\/pre>\n\n\n\n<p>Puis ajouter le (nouveau) membre, en utilisant la fonctionnalit\u00e9 clone :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MySQL localhost JS> cluster.addInstance(\"root@mysql_node1:3306\")\n\nWARNING: A GTID set check of the MySQL instance at 'mysql_node1:3306' determined that it\ncontains transactions that do not originate from the cluster, which must be\ndiscarded before it can join the cluster.\n\nmysql_node1:3306 has the following errant GTIDs that do not exist in the cluster:\nf6cdb648-b9d7-11e9-bf6c-0242ac14000b:1-3\n\nWARNING: Discarding these extra GTID events can either be done manually or by completely\noverwriting the state of mysql_node1:3306 with a physical snapshot from an\nexisting cluster member. To use this method by default, set the\n'recoveryMethod' option to 'clone'.\n\nHaving extra GTID events is not expected, and it is recommended to investigate\nthis further and ensure that the data can be removed prior to choosing the\nclone recovery method.\n\nPlease select a recovery method [C]lone\/[A]bort (default Abort): C\nValidating instance at mysql_node1:3306...\n\nThis instance reports its own address as mysql_node1:3306\n\nInstance configuration is suitable.\nA new instance will be added to the InnoDB cluster. Depending on the amount of\ndata on the cluster this might take from a few seconds to several hours.\n\nAdding instance to the cluster...\n\nWARNING: User 'mysql_innodb_cluster_2835519091'@'%' already existed at instance 'localhost:3306'. It will be deleted and created again with a new password.\nMonitoring recovery process of the new cluster member. Press ^C to stop monitoring and let it continue in background.\nClone based state recovery is now in progress.\n\nNOTE: A server restart is expected to happen as part of the clone process. If the\nserver does not support the RESTART command or does not come back after a\nwhile, you may need to manually start it back.\n\n* Waiting for clone to finish...\nNOTE: mysql_node1:3306 is being cloned from mysql_node2:3306\n** Stage DROP DATA: Completed\n** Clone Transfer  \n    FILE COPY  ############################################################  100%  Completed\n    PAGE COPY  ############################################################  100%  Completed\n    REDO COPY  ############################################################  100%  Completed\n** Stage RECOVERY: \\\nNOTE: mysql_node1:3306 is shutting down...\n\n* Waiting for server restart... ready\n* mysql_node1:3306 has restarted, waiting for clone to finish...\n* Clone process has finished: 66.89 MB transferred in about 1 second (~inf TB\/s)\n\nState recovery already finished for 'mysql_node1:3306'\n\nThe instance 'mysql_node1:3306' was successfully added to the cluster.<\/code><\/pre>\n\n\n\n<p>Encore une fois, n&rsquo;oublie pas qu&rsquo;avec Docker MySQL n&rsquo;est pas g\u00e9r\u00e9 par un processus de supervision &#8211; <em>mysqld is not managed by supervisor process<\/em>.<br>Tu dois donc red\u00e9marrer toi m\u00eame l&rsquo;instance.<\/p>\n\n\n\n<p>Et enfin la structure finale de notre cluster, est celle que je d\u00e9sire:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MySQL localhost JS> cluster.status()\n{\n    \"clusterName\": \"pocCluster\", \n    \"defaultReplicaSet\": {\n        \"name\": \"default\", \n        \"primary\": \"mysql_node3: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\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node2:3306\": {\n                \"address\": \"mysql_node2:3306\", \n                \"mode\": \"R\/O\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }, \n            \"mysql_node3:3306\": {\n                \"address\": \"mysql_node3:3306\", \n                \"mode\": \"R\/W\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.17\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"mysql_node3:3306\"\n}<\/code><\/pre>\n\n\n\n\n\n<p>Voil\u00e0 c&rsquo;est tout pour aujourd&rsquo;hui.<br>Reste en contact, car il y a encore plein de chose \u00e0 dire sur le sujet et \u00e9galement plein de bonnes choses qui arrivent \ud83d\ude42<\/p>\n\n\n\n\n\n<p><u>Dans la m\u00eame th\u00e9matique<\/u>:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/mysql-innodb-cluster-userguide.html\" target=\"_blank\">MySQL InnoDB Cluster<\/a> <\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/group-replication.html\" target=\"_blank\">MySQL Group Replication<\/a> <\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/mysql-shell\/8.0\/en\/\" target=\"_blank\">MySQL Shell<\/a> <\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/dev.mysql.com\/doc\/mysql-router\/8.0\/en\/\" target=\"_blank\">MySQL Router<\/a> <\/li><\/ul>\n\n\n\n<ul class=\"wp-block-list\"><li><a rel=\"noreferrer noopener\" href=\"http:\/\/dasini.net\/blog\/2019\/04\/11\/mysql-innodb-cluster-howto-1-monitor-your-cluster\/\" target=\"_blank\">MySQL InnoDB Cluster \u2013 HowTo #1 \u2013 Monitor your cluster<\/a><\/li><li><a rel=\"noreferrer noopener\" href=\"http:\/\/dasini.net\/blog\/2019\/05\/21\/mysql-innodb-cluster-howto-2-validate-an-instance\/\" target=\"_blank\">MySQL InnoDB Cluster \u2013 HowTo #2 \u2013 Validate an instance<\/a> <\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/lefred.be\/content\/mysql-innodb-cluster-is-the-router-a-single-point-of-failure\/\" target=\"_blank\">MySQL InnoDB Cluster: is the router a single point of failure ?<\/a><\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/lefred.be\/content\/mysql-router-ha-with-pacemaker\/\" target=\"_blank\">MySQL Router HA with Pacemaker<\/a><\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/lefred.be\/content\/mysql-router-ha-with-keepalived\/\" target=\"_blank\">MySQL Router HA with Keepalived<\/a><\/li><li><a href=\"http:\/\/dasini.net\/blog\/2019\/09\/10\/mysql-innodb-cluster-easy-recovering-and-provisioning\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (s\u2019ouvre dans un nouvel onglet)\">MySQL InnoDB Cluster \u2013 Easy Recovering and provisioning<\/a><\/li><li><a rel=\"noreferrer noopener\" aria-label=\" (s\u2019ouvre dans un nouvel onglet)\" href=\"http:\/\/dasini.net\/blog\/2019\/07\/11\/mysql-innodb-cluster-recovering-and-provisioning-with-mysql-enterprise-backup\/\" target=\"_blank\">MySQL InnoDB Cluster \u2013 Recovering and provisioning with MySQL Enterprise Backup<\/a><\/li><li><a rel=\"noreferrer noopener\" aria-label=\" (s\u2019ouvre dans un nouvel onglet)\" href=\"http:\/\/dasini.net\/blog\/2019\/07\/09\/mysql-innodb-cluster-recovering-and-provisioning-with-mysqldump\/\" target=\"_blank\">MySQL InnoDB Cluster \u2013 Recovering and provisioning with mysqldump<\/a><\/li><li><a rel=\"noreferrer noopener\" href=\"http:\/\/dasini.net\/blog\/2017\/01\/11\/configurer-proxysql-pour-mysql-group-replication\/\" target=\"_blank\">Configurer ProxySQL pour MySQL Group Replication<\/a><\/li><li><a rel=\"noreferrer noopener\" aria-label=\"Pr\u00e9sentation: MySQL InnoDB Cluster; A complete High Availability solution for MySQL (opens in a new tab)\" href=\"https:\/\/www.slideshare.net\/freshdaz\/mysql-day-paris-2018-mysql-innodb-cluster-a-complete-high-availability-solution-for-mysql\" target=\"_blank\">Pr\u00e9sentation: MySQL InnoDB Cluster; A complete High Availability solution for MySQL<\/a> <\/li><\/ul>\n\n\n\n\n\n<p><u>Video<\/u>:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/www.youtube.com\/watch?v=YZzGsDjlWvk\" target=\"_blank\" rel=\"noreferrer noopener\">D\u00e9ployer 1 cluster <strong>MySQL<\/strong> avec seulement 2 commandes<\/a><\/li><\/ul>\n\n\n\n\n\n<p><u>Articles connexes<\/u>:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a rel=\"noreferrer noopener\" href=\"http:\/\/mysql.wisborg.dk\/2018\/08\/14\/mysql-8-0-persisted-variables\/\" target=\"_blank\">MySQL 8.0: Persisted Variables<\/a><\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/mysqlserverteam.com\/getting-help-in-mysql-shell\/\" target=\"_blank\">Getting Help in MySQL Shell<\/a><\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/mysql.wisborg.dk\/2018\/08\/25\/mysql-shell-built-in-help\/\" target=\"_blank\">MySQL Shell: Built-In Help<\/a><\/li><\/ul>\n\n\n\n\n\n<p><strong>Misc<\/strong><br>Some optional but useful parameters from my node1&rsquo;s <strong>my.cnf<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[mysqld]\nreport_port \t   = 3306\nreport_host \t   = mysql_node1\n\nplugin_load        = group_replication.so\nplugin-load-add    = mysql_clone.so<\/code><\/pre>\n\n\n\n\n\n<div style=\"height:75px\" 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 MySQL!<\/strong><\/p>\n\n\n\n<div style=\"height:25px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\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","protected":false},"excerpt":{"rendered":"<p>Cela fait maintenant 1 an que j\u2019ai \u00e9cris la v1 de ce tuto sur MySQL InnoDB Cluster et durant ce laps de temps, mes coll\u00e8gues d\u2019Oracle MySQL ont travaill\u00e9 tr\u00e8s dur pour enrichir la solution et d\u00e9velopper pas mal de nouvelles fonctionnalit\u00e9s.<br \/>\nEn fait que du bon ? \u2013 gr\u00e2ce \u00e0 vous et \u00e0 vos retours \u2013 merci infiniment !.<\/p>\n<p>Bref tu l\u2019as compris, c\u2019est le moment de mettre \u00e0 jour ce tutoriel.<br \/>\nEn clair, cet article remplace et annule l\u2019ancien.<\/p>\n<p>Je t\u2019invite \u00e0 passer un moment avec moi pour d\u00e9couvrir les diff\u00e9rentes \u00e9tapes du d\u00e9ploiement d\u2019un MySQL InnoDB Cluster, l\u2019utilisation de MySQL Router et aussi les principales commandes pour g\u00e9rer ton cluster avec MySQL Shell.<\/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":[282,316,288,8,337],"tags":[75,286,79,298,302,318,341],"class_list":["post-3299","post","type-post","status-publish","format-standard","hentry","category-group-replication","category-haute-disponibilite","category-innodb-cluster","category-mysql","category-tuto","tag-cluster","tag-group-replication","tag-haute-disponibilite","tag-innodb-cluster","tag-router","tag-shell","tag-tuto"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9LfWW-Rd","jetpack-related-posts":[{"id":3291,"url":"https:\/\/dasini.net\/blog\/2019\/07\/16\/deployer-1-cluster-mysql-avec-2-commandes\/","url_meta":{"origin":3299,"position":0},"title":"D\u00e9ployer 1 cluster MySQL avec 2 commandes","author":"Olivier DASINI","date":"16 juillet 2019","format":false,"excerpt":"Dans cette courte vid\u00e9o, je vais te montrer comment cr\u00e9er un cluster MySQL de 3 n\u0153uds avec simplement 2 commandes. https:\/\/www.youtube.com\/watch?v=YZzGsDjlWvk","rel":"","context":"Dans &quot;Group Replication&quot;","block_context":{"text":"Group Replication","link":"https:\/\/dasini.net\/blog\/category\/group-replication\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/img.youtube.com\/vi\/YZzGsDjlWvk\/0.jpg?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":1736,"url":"https:\/\/dasini.net\/blog\/2016\/11\/24\/retour-sur-le-mysql-day-paris-2016\/","url_meta":{"origin":3299,"position":1},"title":"Retour sur le MySQL Day Paris 2016","author":"Olivier DASINI","date":"24 novembre 2016","format":false,"excerpt":"Venez d\u00e9couvrir le nouveau MySQL Cloud Service d'Oracle et toutes les nouveaut\u00e9s produits MySQL annonc\u00e9es \u00e0 Oracle Open World Vous utilisez ou envisagez d\u2019utiliser des services cloud pour votre projet ? Le nouveau MySQL Cloud Service d\u2019Oracle fournit un service cloud simple, automatis\u00e9, int\u00e9gr\u00e9, pr\u00eat \u00e0 l\u2019emploi, pour permettre aux\u2026","rel":"","context":"Dans &quot;Conf\u00e9rence&quot;","block_context":{"text":"Conf\u00e9rence","link":"https:\/\/dasini.net\/blog\/category\/conference\/"},"img":{"alt_text":"Oracle MySQL Day Paris","src":"https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/Oracle_MySQL_Day_Paris.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/Oracle_MySQL_Day_Paris.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/Oracle_MySQL_Day_Paris.png?resize=525%2C300 1.5x"},"classes":[]},{"id":4381,"url":"https:\/\/dasini.net\/blog\/2021\/02\/24\/webinar-la-haute-disponibilite-avec-mysql\/","url_meta":{"origin":3299,"position":2},"title":"Webinar \u2013  La haute disponibilit\u00e9 avec MySQL","author":"Olivier DASINI","date":"24 f\u00e9vrier 2021","format":false,"excerpt":"MySQL propose plusieurs solutions pour vous aider \u00e0 b\u00e2tir une architecture hautement disponible. On retrouve InnoDB Cluster avec Group Replication, la r\u00e9plication asynchrone en utilisant InnoDB ReplicaSet ou encore la r\u00e9plication semi-synchrone, et enfin NDB Cluster. Dans cette session, nous examinerons ces diff\u00e9rents sc\u00e9narios, les \u00e9cueils \u00e0 \u00e9viter et les\u2026","rel":"","context":"Dans &quot;MySQL&quot;","block_context":{"text":"MySQL","link":"https:\/\/dasini.net\/blog\/category\/mysql\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1936,"url":"https:\/\/dasini.net\/blog\/2017\/05\/26\/php-tour-2017-slides-mysql-innodb-cluster\/","url_meta":{"origin":3299,"position":3},"title":"PHP Tour 2017 &#8211; Slides  MySQL InnoDB Cluster","author":"Olivier DASINI","date":"26 mai 2017","format":false,"excerpt":"La derni\u00e8re \u00e9dition du PHP Tour s'est d\u00e9roul\u00e9e les 18 et 19 mai 2017 \u00e0 Nantes. Ce que j'en garde : un tr\u00e8s bon cru, de bien belles rencontres, de bonnes bi\u00e8res ainsi qu'une excellente organisation (merci l'AFUP). J'ai \u00e9galement eu l'opportunit\u00e9 de pr\u00e9senter MySQL InnoDB Cluster, la nouvelle solution\u2026","rel":"","context":"Dans &quot;Conf\u00e9rence&quot;","block_context":{"text":"Conf\u00e9rence","link":"https:\/\/dasini.net\/blog\/category\/conference\/"},"img":{"alt_text":"Olivier DASINI aka @freshdaz","src":"https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/Olivier_Dasini_conf_2017.jpg?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":1654,"url":"https:\/\/dasini.net\/blog\/2016\/10\/05\/mysql-a-oracle-openworld-2016\/","url_meta":{"origin":3299,"position":4},"title":"MySQL \u00e0 Oracle OpenWorld 2016","author":"Olivier DASINI","date":"5 octobre 2016","format":false,"excerpt":"R\u00e9sum\u00e9 des annonces MySQL \u00e0 Oracle OpenWorld: MySQL dans le cloud, MySQL Group Replication, MySQL InnoDB Cluster, MySQL 8,...","rel":"","context":"Dans &quot;Group Replication&quot;","block_context":{"text":"Group Replication","link":"https:\/\/dasini.net\/blog\/category\/group-replication\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/Oracle_MySQL_Cloud_Service.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":2587,"url":"https:\/\/dasini.net\/blog\/2018\/08\/30\/tutoriel-deployer-mysql-8-0-innodb-cluster\/","url_meta":{"origin":3299,"position":5},"title":"Tutoriel \u2013 D\u00e9ployer MySQL 8.0 InnoDB Cluster","author":"Olivier DASINI","date":"30 ao\u00fbt 2018","format":false,"excerpt":"Cela fait maintenant plus d'un trimestre que MySQL 8.0 est GA (8.0.11; 8.0.12), il est temps que je t'en parle :) Dans la liste des besoins essentiels de mes clients se trouve la\u00a0Haute Disponibilit\u00e9 avec MySQL. On va voir, dans cet article, comment d\u00e9ployer et g\u00e9rer un cluster MySQL \"from\u2026","rel":"","context":"Dans &quot;Group Replication&quot;","block_context":{"text":"Group Replication","link":"https:\/\/dasini.net\/blog\/category\/group-replication\/"},"img":{"alt_text":"MySQL InnoDB Cluster Architecture","src":"https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/MySQL_8.0_InnoDB_Cluster_Production_post.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/MySQL_8.0_InnoDB_Cluster_Production_post.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/MySQL_8.0_InnoDB_Cluster_Production_post.png?resize=525%2C300 1.5x"},"classes":[]}],"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts\/3299","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=3299"}],"version-history":[{"count":58,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts\/3299\/revisions"}],"predecessor-version":[{"id":3460,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts\/3299\/revisions\/3460"}],"wp:attachment":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/media?parent=3299"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/categories?post=3299"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/tags?post=3299"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}