{"id":15684568,"url":"https://github.com/garutilorenzo/ansible-role-linux-mysql","last_synced_at":"2025-05-07T16:12:41.249Z","repository":{"id":154321510,"uuid":"473972086","full_name":"garutilorenzo/ansible-role-linux-mysql","owner":"garutilorenzo","description":"Install and configure MySQL Server and MySQL InnoDB Cluster","archived":false,"fork":false,"pushed_at":"2022-08-31T08:30:21.000Z","size":57,"stargazers_count":12,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-07T16:12:26.603Z","etag":null,"topics":["ansible","ansible-playbook","ansible-role","chaos-monkey","innodb-cluster","mysql","mysql-database","mysql-server"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/garutilorenzo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-25T10:51:45.000Z","updated_at":"2025-01-13T13:29:44.000Z","dependencies_parsed_at":null,"dependency_job_id":"7668db64-df65-44de-979d-d1cea9276b60","html_url":"https://github.com/garutilorenzo/ansible-role-linux-mysql","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/garutilorenzo%2Fansible-role-linux-mysql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/garutilorenzo%2Fansible-role-linux-mysql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/garutilorenzo%2Fansible-role-linux-mysql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/garutilorenzo%2Fansible-role-linux-mysql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/garutilorenzo","download_url":"https://codeload.github.com/garutilorenzo/ansible-role-linux-mysql/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252912997,"owners_count":21824066,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible","ansible-playbook","ansible-role","chaos-monkey","innodb-cluster","mysql","mysql-database","mysql-server"],"created_at":"2024-10-03T17:19:20.407Z","updated_at":"2025-05-07T16:12:41.132Z","avatar_url":"https://github.com/garutilorenzo.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![GitHub issues](https://img.shields.io/github/issues/garutilorenzo/ansible-role-linux-mysql)](https://github.com/garutilorenzo/ansible-role-linux-mysql/issues)\n![GitHub](https://img.shields.io/github/license/garutilorenzo/ansible-role-linux-mysql)\n[![GitHub forks](https://img.shields.io/github/forks/garutilorenzo/ansible-role-linux-mysql)](https://github.com/garutilorenzo/ansible-role-linux-mysql/network)\n[![GitHub stars](https://img.shields.io/github/stars/garutilorenzo/ansible-role-linux-mysql)](https://github.com/garutilorenzo/ansible-role-linux-mysql/stargazers)\n\n# Install and configure MySQL Server and MySQL InnoDB Cluster\n\nThis role will install and configure MySQL server or MySQL in HA mode using [MySQL InnoDB Cluster](https://dev.mysql.com/doc/refman/8.0/en/mysql-innodb-cluster-introduction.html) or [GTID replication](https://dev.mysql.com/doc/mysql-replication-excerpt/5.6/en/replication-gtids.html)\n\n## Table of Contents\n\n* [Role Variables](#role-variables)\n* [Vagrant up, build the test infrastructure](#vagrant-up-build-the-test-infrastructure)\n* [Ansible setup and pre-flight check](#ansible-setup-and-pre-flight-check)\n* [Deploy MySQL InnoDB Cluster ](#deploy-mysql-innodb-cluster)\n* [Cluster high availability check](#cluster-high-availability-check)\n* [Restore from complete outage](#restore-from-complete-outage)\n* [Clean up](#clean-up)\n\n### Role Variables\n\nThis role accept this variables:\n\n| Var   | Required |  Default | Desc |\n| ------- | ------- | ----------- |  ----------- |\n| `mysql_subnet`       | `yes`       |  `192.168.25.0/24` | Subnet where MySQL will be listen. If the VM or bare metal server has more than one interface, Ansible will filter the interface and MySQL wil listen only on a specific interface. This variable is also used to calculate the MySQL server ID. |\n| `mysql_root_pw`       | `yes`       | ``       | MySQL root password.   |\n| `mysql_authentication`       | `no`       | `mysql_native_password`       | MySQL authentication method.   |\n| `disable_firewall`       | `no`       | `no`       | If set to yes Ansible will disable the firewall.   |\n| `disable_selinux`        | `no`       | `no`       | Disable SELinux. Default no, if you want to configure SELinux use another Role. You can disable SELinux setting this variable to yes  |\n| `resolv_mode`  | `no` | `dns`       | How MySQL resolve the names, default dns. If set to *host* the /etc/hosts file will be overwritten  |\n| `mysql_listen_all_interfaces`  | `no` | `no`       | Set this variable to yes to allow MySQL to listen on all interfaces 0.0.0.0/0. Otherwise the listen ip address will be retrieved using *mysql_subnet* variable  |\n| `mysql_user`      | `no` |    `mysql`       | MySQL system user  |\n| `mysql_group`     | `no` |    `mysql`       | Group of the MySQL search system user  |\n| `mysql_data_dir`  | `no` | `/var/lib/mysql`       | MySQL data dir  |\n| `mysql_log_dir`   | `no` |  `/var/log/mysql`       | MySQL log dir  |\n| `mysql_conf_dir`  | `no` | `/etc/mysql`       | MySQL conf dir  |\n| `mysql_pid_dir`   | `no` |  `/var/run/mysqld`       | MySQL pid dir  |\n| `mysql_operator_user`   | `no` | `operator`       | MySQL operator user, used to bootstrap MySQL InnoDB Cluster. |\n| `mysql_operator_password`   | `no` | `Op3r4torMyPw`       | Password of operator user  |\n| `mysql_replica_user`   | `no` | `replica`       | MySQL replica user. Used for all the replica operations  |\n| `mysql_replica_password`   | `no`  | `rEpL1c4p4Sw0,rd`       | Password of replica user  |\n| `mysql_replication_mode`   | `no`  | ``       |  [InnoDB Cluster](https://dev.mysql.com/doc/refman/8.0/en/mysql-innodb-cluster-introduction.html), [GTID](https://dev.mysql.com/doc/mysql-replication-excerpt/5.6/en/replication-gtids.html), Empty/None (default) |\n| `mysql_gr_name`   | `no`    | ``       | Required if *mysql_replication_mode* is set to *InnoDB Cluster*. UUID of the Group Replication |\n| `mysql_gr_vcu`    | `no`    | ``       | Required if *mysql_replication_mode* is set to *InnoDB Cluster*. Group Replication [view change uuid](https://dev.mysql.com/doc/refman/8.0/en/group-replication-options.html#sysvar_group_replication_view_change_uuid)  |\n| `mysql_innodb_cluster_name`   | `no`   | ``       | Required if *mysql_replication_mode* is set to *InnoDB Cluster*. The name of MySQL InnoDB Cluster |\n\n### Vagrant up, build the test infrastructure\n\nTo test this role we use [Vagrant](https://www.vagrantup.com/) and [Virtualbox](https://www.virtualbox.org/), but if you prefer you can also use your own VMs or your baremetal machines.\n\nThe first step is to download this repo and birng up all the VMs. But first in the Vagrantfile paste your public ssh key in the *CHANGE_ME* variable. You can also adjust the number of the vm deployed by changing the NNODES variable (in this exaple we will use 5 nodes). Now we are ready to provision the machines:\n\n```\ngit clone https://github.com/garutilorenzo/ansible-role-linux-mysql.git\n\ncd ansible-role-linux-mysql/\n\nvagrant up\nBringing machine 'my-ubuntu-0' up with 'virtualbox' provider...\nBringing machine 'my-ubuntu-1' up with 'virtualbox' provider...\nBringing machine 'my-ubuntu-2' up with 'virtualbox' provider...\nBringing machine 'my-ubuntu-3' up with 'virtualbox' provider...\nBringing machine 'my-ubuntu-4' up with 'virtualbox' provider...\n\n[...]\n[...]\n\n    my-ubuntu-4: Inserting generated public key within guest...\n==\u003e my-ubuntu-4: Machine booted and ready!\n==\u003e my-ubuntu-4: Checking for guest additions in VM...\n    my-ubuntu-4: The guest additions on this VM do not match the installed version of\n    my-ubuntu-4: VirtualBox! In most cases this is fine, but in rare cases it can\n    my-ubuntu-4: prevent things such as shared folders from working properly. If you see\n    my-ubuntu-4: shared folder errors, please make sure the guest additions within the\n    my-ubuntu-4: virtual machine match the version of VirtualBox you have installed on\n    my-ubuntu-4: your host and reload your VM.\n    my-ubuntu-4:\n    my-ubuntu-4: Guest Additions Version: 6.0.0 r127566\n    my-ubuntu-4: VirtualBox Version: 6.1\n==\u003e my-ubuntu-4: Setting hostname...\n==\u003e my-ubuntu-4: Configuring and enabling network interfaces...\n==\u003e my-ubuntu-4: Mounting shared folders...\n    my-ubuntu-4: /vagrant =\u003e C:/Users/Lorenzo Garuti/workspaces/simple-ubuntu\n==\u003e my-ubuntu-4: Running provisioner: shell...\n    my-ubuntu-4: Running: inline script\n==\u003e my-ubuntu-4: Running provisioner: shell...\n    my-ubuntu-4: Running: inline script\n    my-ubuntu-4: hello from node 5\n```\n\n### Ansible setup and pre-flight check\n\nNow if you don't have Ansible installed, install ansible and all the requirements:\n\n```\napt-get install python3 python3-pip uuidgen openssl\npip3 install pipenv\n\npipenv shell\npip install -r requirements.txt\n```\n\nNow with Ansible installed we can download the role directly from GitHub:\n\n```\nansible-galaxy install git+https://github.com/garutilorenzo/ansible-role-linux-mysql.git\n```\n\nWhit Ansible and the role installed we can setup our inventory file (hosts.ini):\n\n```\n[mysql]\nmy-ubuntu-0 ansible_host=192.168.25.110\nmy-ubuntu-1 ansible_host=192.168.25.111\nmy-ubuntu-2 ansible_host=192.168.25.112\nmy-ubuntu-3 ansible_host=192.168.25.113\nmy-ubuntu-4 ansible_host=192.168.25.114\n```\n\nand the vars.yml file:\n\n```yaml\n---\n\ndisable_firewall: yes\ndisable_selinux: yes\nmysql_resolv_mode: hosts\nmysql_subnet: 192.168.25.0/24\nmysql_listen_all_interfaces: yes\n\nmysql_root_pw: '\u003cCHANGE_ME\u003e' # \u003c- openssl rand -base64 32 | sed 's/=//'\nmysql_replication_mode: 'InnoDB Cluster'\nmysql_gr_name: '\u003cCHANGE_ME\u003e' # \u003c- uuidgen\nmysql_gr_vcu: '\u003cCHANGE_ME\u003e' #  \u003c- uuidgen\nmysql_innodb_cluster_name: 'cluster_lab' \n```\n\n**NOTE** mysql_gr_name and mysql_gr_vcu are different uuid, so run uuidgen twice.\nWith this vars we are going to deploy MySQL in HA Mode with MySQL InnoDB Cluster, the cluster will be created from an existing [Group Replication](https://dev.mysql.com/doc/refman/8.0/en/group-replication.html) configuration.\n\nThe final step before proceed with the installation is to create the site.yml file:\n\n```yaml\n---\n- hosts: mysql\n  become: yes\n  remote_user: vagrant\n  roles: \n    - role: ansible-role-linux-mysql\n  vars_files:\n    - vars.yml\n```\n\n### Deploy MySQL InnoDB Cluster \n\nWe are finally ready to deploy MySQL InnoDB Cluster using ansible:\n\n```\nexport ANSIBLE_HOST_KEY_CHECKING=False # Ansible skip ssh-key validation\n\nansible-playbook -i hosts.ini site.yml -e mysql_bootstrap_host=my-ubuntu-0\n\nTASK [ansible-role-linux-mysql : render mysql.conf.d/mysqld.cnf] *******************************************************************************************\nok: [my-ubuntu-0]\nok: [my-ubuntu-2]\nok: [my-ubuntu-1]\nok: [my-ubuntu-3]\nok: [my-ubuntu-4]\n\nTASK [ansible-role-linux-mysql : render mysql.conf.d/gtid.cnf] *********************************************************************************************\nok: [my-ubuntu-1]\nok: [my-ubuntu-0]\nok: [my-ubuntu-3]\nok: [my-ubuntu-2]\nok: [my-ubuntu-4]\n\nTASK [ansible-role-linux-mysql : ansible.builtin.fail] *****************************************************************************************************\nskipping: [my-ubuntu-0]\nskipping: [my-ubuntu-1]\nskipping: [my-ubuntu-2]\nskipping: [my-ubuntu-3]\nskipping: [my-ubuntu-4]\n\nTASK [ansible-role-linux-mysql : ansible.builtin.fail] *****************************************************************************************************\nskipping: [my-ubuntu-0]\nskipping: [my-ubuntu-1]\nskipping: [my-ubuntu-2]\nskipping: [my-ubuntu-3]\nskipping: [my-ubuntu-4]\n\nTASK [ansible-role-linux-mysql : render innodb_cluster.cnf] ************************************************************************************************\nok: [my-ubuntu-0]\nok: [my-ubuntu-1]\nok: [my-ubuntu-3]\nok: [my-ubuntu-2]\nok: [my-ubuntu-4]\n\nRUNNING HANDLER [ansible-role-linux-mysql : reload systemd] ************************************************************************************************\nok: [my-ubuntu-3]\nok: [my-ubuntu-0]\nok: [my-ubuntu-2]\nok: [my-ubuntu-4]\nok: [my-ubuntu-1]\n\nPLAY RECAP *************************************************************************************************************************************************\nmy-ubuntu-0               : ok=69   changed=27   unreachable=0    failed=0    skipped=12   rescued=0    ignored=0   \nmy-ubuntu-1               : ok=71   changed=28   unreachable=0    failed=0    skipped=10   rescued=0    ignored=0   \nmy-ubuntu-2               : ok=71   changed=28   unreachable=0    failed=0    skipped=10   rescued=0    ignored=0   \nmy-ubuntu-3               : ok=71   changed=28   unreachable=0    failed=0    skipped=10   rescued=0    ignored=0   \nmy-ubuntu-4               : ok=71   changed=28   unreachable=0    failed=0    skipped=10   rescued=0    ignored=0 \n```\n\nThe cluster is now installed, but we have to persist some configurations. Since the cluster is a new cluster, Ansible has started the Group Replication in [bootstrap](https://dev.mysql.com/doc/refman/8.0/en/group-replication-bootstrap.html) mode. This means that the first instance (in this case my-ubuntu-0) has te value *group_replication_bootstrap_group* set to *ON*, and *group_replication_group_seeds* set to an empty value. With this second run of Ansible, this variables will be set to the correct values:\n\n```\nansible-playbook -i hosts.ini site.yml\n\nTASK [ansible-role-linux-mysql : ansible.builtin.fail] *****************************************************************************************************\nskipping: [my-ubuntu-0]\nskipping: [my-ubuntu-1]\nskipping: [my-ubuntu-2]\nskipping: [my-ubuntu-3]\nskipping: [my-ubuntu-4]\n\nTASK [ansible-role-linux-mysql : ansible.builtin.fail] *****************************************************************************************************\nskipping: [my-ubuntu-0]\nskipping: [my-ubuntu-1]\nskipping: [my-ubuntu-2]\nskipping: [my-ubuntu-3]\nskipping: [my-ubuntu-4]\n\nTASK [ansible-role-linux-mysql : render innodb_cluster.cnf] ************************************************************************************************\nok: [my-ubuntu-2]\nok: [my-ubuntu-4]\nok: [my-ubuntu-1]\nok: [my-ubuntu-3]\nchanged: [my-ubuntu-0]\n\nPLAY RECAP *************************************************************************************************************************************************\nmy-ubuntu-0               : ok=30   changed=1    unreachable=0    failed=0    skipped=18   rescued=0    ignored=0   \nmy-ubuntu-1               : ok=30   changed=0    unreachable=0    failed=0    skipped=18   rescued=0    ignored=0   \nmy-ubuntu-2               : ok=30   changed=0    unreachable=0    failed=0    skipped=18   rescued=0    ignored=0   \nmy-ubuntu-3               : ok=30   changed=0    unreachable=0    failed=0    skipped=18   rescued=0    ignored=0   \nmy-ubuntu-4               : ok=30   changed=0    unreachable=0    failed=0    skipped=18   rescued=0    ignored=0   \n```\n\nIn this guide mysqlsh is used to make operations on MySQL InnoDB Cluster. [Here](https://dev.mysql.com/doc/mysql-shell/8.0/en/) you can find more information about mysqlsh.\n\nNow we can finally check our cluster:\n\n```\nroot@my-ubuntu-0:~# mysqlsh root@my-ubuntu-0\nPlease provide the password for 'root@my-ubuntu-0': ******************************************\nMySQL  localhost:33060+ ssl  JS \u003e clu = dba.getCluster()\nMySQL  localhost:33060+ ssl  JS \u003e clu.status()\n{\n    \"clusterName\": \"cluster_lab\", \n    \"defaultReplicaSet\": {\n        \"name\": \"default\", \n        \"primary\": \"my-ubuntu-0:3306\", \n        \"ssl\": \"DISABLED\", \n        \"status\": \"OK\", \n        \"statusText\": \"Cluster is ONLINE and can tolerate up to 2 failures.\", \n        \"topology\": {\n            \"my-ubuntu-0:3306\": {\n                \"address\": \"my-ubuntu-0:3306\", \n                \"memberRole\": \"PRIMARY\", \n                \"mode\": \"R/W\", \n                \"readReplicas\": {}, \n                \"replicationLag\": \"applier_queue_applied\", \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.30\"\n            }, \n            \"my-ubuntu-1:3306\": {\n                \"address\": \"my-ubuntu-1:3306\", \n                \"memberRole\": \"SECONDARY\", \n                \"mode\": \"R/O\", \n                \"readReplicas\": {}, \n                \"replicationLag\": \"applier_queue_applied\", \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.30\"\n            }, \n            \"my-ubuntu-2:3306\": {\n                \"address\": \"my-ubuntu-2:3306\", \n                \"memberRole\": \"SECONDARY\", \n                \"mode\": \"R/O\", \n                \"readReplicas\": {}, \n                \"replicationLag\": \"applier_queue_applied\", \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.30\"\n            }, \n            \"my-ubuntu-3:3306\": {\n                \"address\": \"my-ubuntu-3:3306\", \n                \"memberRole\": \"SECONDARY\", \n                \"mode\": \"R/O\", \n                \"readReplicas\": {}, \n                \"replicationLag\": \"applier_queue_applied\", \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.30\"\n            }, \n            \"my-ubuntu-4:3306\": {\n                \"address\": \"my-ubuntu-4:3306\", \n                \"memberRole\": \"SECONDARY\", \n                \"mode\": \"R/O\", \n                \"readReplicas\": {}, \n                \"replicationLag\": \"applier_queue_applied\", \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.30\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"my-ubuntu-0:3306\"\n}\n```\n\n### Cluster high availability check\n\nTo test the cluster we can use a sample Docker compose stack, the example uses:\n\n* Wordpress as frontend\n* [mysqlrouter](https://github.com/garutilorenzo/mysqlrouter) will connect WP to MySQL\n\nTo run this test you have to install [Docker](https://docs.docker.com/get-docker/) and [Docker compose](https://docs.docker.com/compose/install/).\n\n#### User and Database creation\n\nWe need to create one db and one user for wordpress, to do this we have to find the primary server (check the cluster status and find the node with -\u003e \"mode\": \"R/W\")\n\n```\nroot@my-ubuntu-0:~# mysqlsh root@localhost\nPlease provide the password for 'root@localhost': ******************************************\n\nMySQL  localhost:33060+ ssl  JS \u003e \\sql # \u003c- SWITCH TO SQL MODE\nSwitching to SQL mode... Commands end with ;\n\ncreate database wordpress;\ncreate user 'wordpress'@'%' identified by 'wordpress';\ngrant all on wordpress.* TO 'wordpress'@'%';\nflush privileges;\n```\n\n#### Sample Dokcer compose stack\n\nThe sample stack can be found in the [examples](examples/) folder, this is the compose file:\n\n```yaml\nversion: '3.4'\nservices:\n  wordpress:\n    image: wordpress:latest\n    ports:\n      - 80:80\n    restart: always\n    environment:\n      - WORDPRESS_DB_HOST=mysqlrouter:6446\n      - WORDPRESS_DB_USER=wordpress\n      - WORDPRESS_DB_PASSWORD=wordpress\n      - WORDPRESS_DB_NAME=wordpress\n\n  mysqlrouter:\n    image: garutilorenzo/mysqlrouter:8.0.30\n    volumes:\n      - type: volume\n        source: mysqlrouter\n        target: /app/mysqlrouter/\n        volume:\n          nocopy: true\n    environment:\n     - MYSQL_HOST=my-ubuntu-0\n     - MYSQL_PORT=3306\n     - MYSQL_USER=root\n     - MYSQL_PASSWORD=\u003cCHANGE_ME\u003e # \u003c- the same password in the vars.yml file\n     - MYSQL_ROUTER_ACCOUNT=mysql_router_user\n     - MYSQL_ROUTER_PASSWORD=\u003cCHANGE_ME\u003e # \u003c- openssl rand -base64 32 | sed 's/=//'\n    extra_hosts:\n      my-ubuntu-0: 192.168.25.110\n      my-ubuntu-1: 192.168.25.111\n      my-ubuntu-2: 192.168.25.112\n      my-ubuntu-3: 192.168.25.113\n      my-ubuntu-4: 192.168.25.114\n\nvolumes:\n mysqlrouter:\n```\n\nNow we can start our stack and inspect the logs:\n\n```\ndocker-compose -f mysql-router-compose.yml up -d\ndocker-compose -f mysql-router-compose.yml logs mysqlrouter\n\nexamples-mysqlrouter-1  | Succesfully contacted mysql server at my-ubuntu-0. Checking for cluster state.\nexamples-mysqlrouter-1  | Check if config exist\nexamples-mysqlrouter-1  | bootstrap mysqlrouter with account mysql_router_user\nexamples-mysqlrouter-1  | Succesfully contacted mysql server at my-ubuntu-0. Trying to bootstrap.\nexamples-mysqlrouter-1  | Please enter MySQL password for root: \nexamples-mysqlrouter-1  | # Bootstrapping MySQL Router instance at '/app/mysqlrouter'...\nexamples-mysqlrouter-1  | \nexamples-mysqlrouter-1  | Please enter MySQL password for mysql_router_user: \nexamples-mysqlrouter-1  | - Creating account(s) (only those that are needed, if any)\nexamples-mysqlrouter-1  | - Verifying account (using it to run SQL queries that would be run by Router)\nexamples-mysqlrouter-1  | - Storing account in keyring\nexamples-mysqlrouter-1  | - Adjusting permissions of generated files\nexamples-mysqlrouter-1  | - Creating configuration /app/mysqlrouter/mysqlrouter.conf\nexamples-mysqlrouter-1  | \nexamples-mysqlrouter-1  | # MySQL Router configured for the InnoDB Cluster 'cluster_lab'\nexamples-mysqlrouter-1  | \nexamples-mysqlrouter-1  | After this MySQL Router has been started with the generated configuration\nexamples-mysqlrouter-1  | \nexamples-mysqlrouter-1  |     $ mysqlrouter -c /app/mysqlrouter/mysqlrouter.conf\nexamples-mysqlrouter-1  | \nexamples-mysqlrouter-1  | InnoDB Cluster 'cluster_lab' can be reached by connecting to:\nexamples-mysqlrouter-1  | \nexamples-mysqlrouter-1  | ## MySQL Classic protocol\nexamples-mysqlrouter-1  | \nexamples-mysqlrouter-1  | - Read/Write Connections: localhost:6446\nexamples-mysqlrouter-1  | - Read/Only Connections:  localhost:6447\nexamples-mysqlrouter-1  | \nexamples-mysqlrouter-1  | ## MySQL X protocol\nexamples-mysqlrouter-1  | \nexamples-mysqlrouter-1  | - Read/Write Connections: localhost:6448\nexamples-mysqlrouter-1  | - Read/Only Connections:  localhost:6449\nexamples-mysqlrouter-1  | \nexamples-mysqlrouter-1  | Starting mysql-router.\nexamples-mysqlrouter-1  | 2022-08-30 12:03:57 io INFO [7f794f1e0bc0] starting 4 io-threads, using backend 'linux_epoll'\nexamples-mysqlrouter-1  | 2022-08-30 12:03:57 http_server INFO [7f794f1e0bc0] listening on 0.0.0.0:8443\nexamples-mysqlrouter-1  | 2022-08-30 12:03:57 metadata_cache_plugin INFO [7f794a606700] Starting Metadata Cache\nexamples-mysqlrouter-1  | 2022-08-30 12:03:57 metadata_cache INFO [7f794a606700] Connections using ssl_mode 'PREFERRED'\nexamples-mysqlrouter-1  | 2022-08-30 12:03:57 metadata_cache INFO [7f7948602700] Starting metadata cache refresh thread\nexamples-mysqlrouter-1  | 2022-08-30 12:03:57 routing INFO [7f790e7fc700] [routing:bootstrap_rw] started: routing strategy = first-available\nexamples-mysqlrouter-1  | 2022-08-30 12:03:57 routing INFO [7f790e7fc700] Start accepting connections for routing routing:bootstrap_rw listening on 6446\nexamples-mysqlrouter-1  | 2022-08-30 12:03:57 routing INFO [7f790dffb700] [routing:bootstrap_x_ro] started: routing strategy = round-robin-with-fallback\nexamples-mysqlrouter-1  | 2022-08-30 12:03:57 routing INFO [7f790dffb700] Start accepting connections for routing routing:bootstrap_x_ro listening on 6449\nexamples-mysqlrouter-1  | 2022-08-30 12:03:57 routing INFO [7f790effd700] [routing:bootstrap_ro] started: routing strategy = round-robin-with-fallback\nexamples-mysqlrouter-1  | 2022-08-30 12:03:57 routing INFO [7f790effd700] Start accepting connections for routing routing:bootstrap_ro listening on 6447\nexamples-mysqlrouter-1  | 2022-08-30 12:03:57 metadata_cache INFO [7f7948602700] Connected with metadata server running on my-ubuntu-2:3306\nexamples-mysqlrouter-1  | 2022-08-30 12:03:57 routing INFO [7f790d7fa700] [routing:bootstrap_x_rw] started: routing strategy = first-available\nexamples-mysqlrouter-1  | 2022-08-30 12:03:57 routing INFO [7f790d7fa700] Start accepting connections for routing routing:bootstrap_x_rw listening on 6448\nexamples-mysqlrouter-1  | 2022-08-30 12:03:57 metadata_cache INFO [7f7948602700] Potential changes detected in cluster 'cluster_lab' after metadata refresh\nexamples-mysqlrouter-1  | 2022-08-30 12:03:57 metadata_cache INFO [7f7948602700] Metadata for cluster 'cluster_lab' has 5 member(s), single-primary: (view_id=0)\nexamples-mysqlrouter-1  | 2022-08-30 12:03:57 metadata_cache INFO [7f7948602700]     my-ubuntu-2:3306 / 33060 - mode=RO \nexamples-mysqlrouter-1  | 2022-08-30 12:03:57 metadata_cache INFO [7f7948602700]     my-ubuntu-1:3306 / 33060 - mode=RO \nexamples-mysqlrouter-1  | 2022-08-30 12:03:57 metadata_cache INFO [7f7948602700]     my-ubuntu-0:3306 / 33060 - mode=RW \nexamples-mysqlrouter-1  | 2022-08-30 12:03:57 metadata_cache INFO [7f7948602700]     my-ubuntu-3:3306 / 33060 - mode=RO \nexamples-mysqlrouter-1  | 2022-08-30 12:03:57 metadata_cache INFO [7f7948602700]     my-ubuntu-4:3306 / 33060 - mode=RO \n```\n\n#### Test the frontend\n\nNow if you try to access [localhost](http://localhost) you can see the Wordpress installation page:\n\n![wp-install](https://garutilorenzo.github.io/images/k3s-wp.png)\n\nInstall and configure WP, and now we are ready for some [Chaos Monkey](https://netflix.github.io/chaosmonkey/)\n\n#### Simulate disaster\n\nTo test WP reachability we can start this simple test:\n\n\n```\nwhile true; do curl -s -o /dev/null -w \"%{http_code}\" http://localhost; echo; sleep 1; done\n200\n200\n\n```\n\nnow shutdown the RW node (in this case my-ubuntu-0):\n\n```\nroot@my-ubuntu-0:~# sudo halt -p\nConnection to 192.168.25.110 closed by remote host.\nConnection to 192.168.25.110 closed.\n```\n\nand check the output of the test script:\n\n```\nwhile true; do curl -s -o /dev/null -w \"%{http_code}\" http://localhost; echo; sleep 1; done\n200\n500 # \u003c- my-ubuntu-0 shutdown and MySQL primary switch\n200\n200\n\n```\n\nNow we check the cluster status from the second node, and we see that the cluster is still *ONLINE* and can tolerate one more failure:\n\n```\nroot@my-ubuntu-1:~# mysqlsh root@localhost\nPlease provide the password for 'root@localhost': ******************************************\n\nMySQL  localhost:33060+ ssl  JS \u003e clu = dba.getCluster()\nMySQL  localhost:33060+ ssl  JS \u003e clu.status()\n{\n    \"clusterName\": \"cluster_lab\", \n    \"defaultReplicaSet\": {\n        \"name\": \"default\", \n        \"primary\": \"my-ubuntu-2:3306\", \n        \"ssl\": \"DISABLED\", \n        \"status\": \"OK_PARTIAL\", \n        \"statusText\": \"Cluster is ONLINE and can tolerate up to ONE failure. 1 member is not active.\", \n        \"topology\": {\n            \"my-ubuntu-0:3306\": {\n                \"address\": \"my-ubuntu-0:3306\", \n                \"memberRole\": \"SECONDARY\", \n                \"mode\": \"n/a\", \n                \"readReplicas\": {}, \n                \"role\": \"HA\", \n                \"shellConnectError\": \"MySQL Error 2003: Could not open connection to 'my-ubuntu-0:3306': Can't connect to MySQL server on 'my-ubuntu-0:3306' (110)\", \n                \"status\": \"(MISSING)\"\n            }, \n            \"my-ubuntu-1:3306\": {\n                \"address\": \"my-ubuntu-1:3306\", \n                \"memberRole\": \"SECONDARY\", \n                \"mode\": \"R/O\", \n                \"readReplicas\": {}, \n                \"replicationLag\": \"applier_queue_applied\", \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.30\"\n            }, \n            \"my-ubuntu-2:3306\": {\n                \"address\": \"my-ubuntu-2:3306\", \n                \"memberRole\": \"PRIMARY\", \n                \"mode\": \"R/W\", \n                \"readReplicas\": {}, \n                \"replicationLag\": \"applier_queue_applied\", \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.30\"\n            }, \n            \"my-ubuntu-3:3306\": {\n                \"address\": \"my-ubuntu-3:3306\", \n                \"memberRole\": \"SECONDARY\", \n                \"mode\": \"R/O\", \n                \"readReplicas\": {}, \n                \"replicationLag\": \"applier_queue_applied\", \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.30\"\n            }, \n            \"my-ubuntu-4:3306\": {\n                \"address\": \"my-ubuntu-4:3306\", \n                \"memberRole\": \"SECONDARY\", \n                \"mode\": \"R/O\", \n                \"readReplicas\": {}, \n                \"replicationLag\": \"applier_queue_applied\", \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.30\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"my-ubuntu-2:3306\"\n}\n MySQL  localhost:33060+ ssl  JS \u003e\n```\n\nIf you check WP at [localhost](http://localhost) is still available, the master now is the *my-ubuntu-2* node.\nNow if we bring up again the *my-ubuntu-0* node, the node wil rejoin the cluster and will get the updates from the other nodes:\n\n```\nroot@my-ubuntu-1:~# mysqlsh root@localhost\nPlease provide the password for 'root@localhost': ******************************************\n\nMySQL  localhost:33060+ ssl  JS \u003e clu = dba.getCluster()\nMySQL  localhost:33060+ ssl  JS \u003e clu.status()\n{\n    \"clusterName\": \"cluster_lab\", \n    \"defaultReplicaSet\": {\n        \"name\": \"default\", \n        \"primary\": \"my-ubuntu-2:3306\", \n        \"ssl\": \"DISABLED\", \n        \"status\": \"OK\", \n        \"statusText\": \"Cluster is ONLINE and can tolerate up to 2 failures.\", \n        \"topology\": {\n            \"my-ubuntu-0:3306\": {\n                \"address\": \"my-ubuntu-0:3306\", \n                \"memberRole\": \"SECONDARY\", \n                \"mode\": \"R/O\", \n                \"readReplicas\": {}, \n                \"replicationLag\": \"applier_queue_applied\", \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.30\"\n            }, \n            \"my-ubuntu-1:3306\": {\n                \"address\": \"my-ubuntu-1:3306\", \n                \"memberRole\": \"SECONDARY\", \n                \"mode\": \"R/O\", \n                \"readReplicas\": {}, \n                \"replicationLag\": \"applier_queue_applied\", \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.30\"\n            }, \n            \"my-ubuntu-2:3306\": {\n                \"address\": \"my-ubuntu-2:3306\", \n                \"memberRole\": \"PRIMARY\", \n                \"mode\": \"R/W\", \n                \"readReplicas\": {}, \n                \"replicationLag\": \"applier_queue_applied\", \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.30\"\n            }, \n            \"my-ubuntu-3:3306\": {\n                \"address\": \"my-ubuntu-3:3306\", \n                \"memberRole\": \"SECONDARY\", \n                \"mode\": \"R/O\", \n                \"readReplicas\": {}, \n                \"replicationLag\": \"applier_queue_applied\", \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.30\"\n            }, \n            \"my-ubuntu-4:3306\": {\n                \"address\": \"my-ubuntu-4:3306\", \n                \"memberRole\": \"SECONDARY\", \n                \"mode\": \"R/O\", \n                \"readReplicas\": {}, \n                \"replicationLag\": \"applier_queue_applied\", \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.30\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"my-ubuntu-2:3306\"\n}\n```\n\n### Restore from complete outage\n\nIf for any reason all the servers went down, the cluster has to be restored from a [complete outage](https://dev.mysql.com/doc/mysql-shell/8.0/en/troubleshooting-innodb-cluster.html).\n\nTo do this we have to connect to one instance, edit /etc/mysql/mysql.conf.d/innodb_cluster.cnf and set *group_replication_bootstrap_group* to *ON* and comment *group_replication_group_seeds*. We have now to restart MySQL:\n\n```\nvagrant@my-ubuntu-0:~$\nvi /etc/mysql/mysql.conf.d/innodb_cluster.cnf\n\ngroup_replication_bootstrap_group=on\n#group_replication_group_seeds=my-ubuntu-0:33061,my-ubuntu-1:33061,my-ubuntu-2:33061,my-ubuntu-3:33061,my-ubuntu-4:33061\n\nsystemctl restart mysqld\n```\n\nFor all the other (four) members we have to start the group replication:\n\n```\nvagrant@my-ubuntu-4:~$ mysqlsh root@localhost\nPlease provide the password for 'root@localhost': ******************************************\n\nMySQL  localhost:33060+ ssl  JS \u003e \\sql # \u003c- SWITCH TO SQL MODE\nSwitching to SQL mode... Commands end with ;\nMySQL  localhost:33060+ ssl  SQL \u003e start group_replication;\nQuery OK, 0 rows affected (1.7095 sec)\n```\n\nIf the traffic on the cluster was low or absent the cluster will be ONLINE:\n\n```\nMySQL  localhost:33060+ ssl  SQL \u003e \\js\nSwitching to JavaScript mode...\nMySQL  localhost:33060+ ssl  JS \u003e clu = dba.getCluster()\nMySQL  localhost:33060+ ssl  JS \u003e clu.status()\n{\n    \"clusterName\": \"cluster_lab\", \n    \"defaultReplicaSet\": {\n        \"name\": \"default\", \n        \"primary\": \"my-ubuntu-0:3306\", \n        \"ssl\": \"DISABLED\", \n        \"status\": \"OK\", \n        \"statusText\": \"Cluster is ONLINE and can tolerate up to 2 failures.\", \n        \"topology\": {\n            \"my-ubuntu-0:3306\": {\n                \"address\": \"my-ubuntu-0:3306\", \n                \"memberRole\": \"PRIMARY\", \n                \"mode\": \"R/W\", \n                \"readReplicas\": {}, \n                \"replicationLag\": \"applier_queue_applied\", \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.30\"\n            }, \n            \"my-ubuntu-1:3306\": {\n                \"address\": \"my-ubuntu-1:3306\", \n                \"memberRole\": \"SECONDARY\", \n                \"mode\": \"R/O\", \n                \"readReplicas\": {}, \n                \"replicationLag\": \"applier_queue_applied\", \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.30\"\n            }, \n            \"my-ubuntu-2:3306\": {\n                \"address\": \"my-ubuntu-2:3306\", \n                \"memberRole\": \"SECONDARY\", \n                \"mode\": \"R/O\", \n                \"readReplicas\": {}, \n                \"replicationLag\": \"applier_queue_applied\", \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.30\"\n            }, \n            \"my-ubuntu-3:3306\": {\n                \"address\": \"my-ubuntu-3:3306\", \n                \"memberRole\": \"SECONDARY\", \n                \"mode\": \"R/O\", \n                \"readReplicas\": {}, \n                \"replicationLag\": \"applier_queue_applied\", \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.30\"\n            }, \n            \"my-ubuntu-4:3306\": {\n                \"address\": \"my-ubuntu-4:3306\", \n                \"memberRole\": \"SECONDARY\", \n                \"mode\": \"R/O\", \n                \"readReplicas\": {}, \n                \"replicationLag\": \"applier_queue_applied\", \n                \"role\": \"HA\", \n                \"status\": \"ONLINE\", \n                \"version\": \"8.0.30\"\n            }\n        }, \n        \"topologyMode\": \"Single-Primary\"\n    }, \n    \"groupInformationSourceMember\": \"my-ubuntu-0:3306\"\n}\n```\n\nIf the cluster has a high volume traffic at the moment of the [complete outage](https://dev.mysql.com/doc/mysql-shell/8.0/en/troubleshooting-innodb-cluster.html). you have to probably run form mysqlsh:\n\n```\nMySQL  localhost:33060+ ssl  JS \u003e var clu = dba.rebootClusterFromCompleteOutage();\n```\n\n### Clean up\n\nWhen you have done you can finally destroy the cluster with:\n\n```\nvagrant destroy\n\n    my-ubuntu-4: Are you sure you want to destroy the 'my-ubuntu-4' VM? [y/N] y\n==\u003e my-ubuntu-4: Forcing shutdown of VM...\n==\u003e my-ubuntu-4: Destroying VM and associated drives...\n    my-ubuntu-3: Are you sure you want to destroy the 'my-ubuntu-3' VM? [y/N] y\n==\u003e my-ubuntu-3: Forcing shutdown of VM...\n==\u003e my-ubuntu-3: Destroying VM and associated drives...\n    my-ubuntu-2: Are you sure you want to destroy the 'my-ubuntu-2' VM? [y/N] y\n==\u003e my-ubuntu-2: Forcing shutdown of VM...\n==\u003e my-ubuntu-2: Destroying VM and associated drives...\n    my-ubuntu-1: Are you sure you want to destroy the 'my-ubuntu-1' VM? [y/N] y\n==\u003e my-ubuntu-1: Forcing shutdown of VM...\n==\u003e my-ubuntu-1: Destroying VM and associated drives...\n    my-ubuntu-0: Are you sure you want to destroy the 'my-ubuntu-0' VM? [y/N] y\n==\u003e my-ubuntu-0: Forcing shutdown of VM...\n==\u003e my-ubuntu-0: Destroying VM and associated drives...\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgarutilorenzo%2Fansible-role-linux-mysql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgarutilorenzo%2Fansible-role-linux-mysql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgarutilorenzo%2Fansible-role-linux-mysql/lists"}