{"id":20551692,"url":"https://github.com/do-community/do-blueprint-mysqlgrouprepl","last_synced_at":"2025-12-07T02:02:35.641Z","repository":{"id":90797622,"uuid":"125430725","full_name":"do-community/do-blueprint-mysqlgrouprepl","owner":"do-community","description":"Blueprint for setting up MySQL group replication with ProxySQL to route queries","archived":false,"fork":false,"pushed_at":"2018-08-20T17:29:03.000Z","size":17,"stargazers_count":5,"open_issues_count":1,"forks_count":1,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-01-16T17:01:00.391Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/do-community.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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":"2018-03-15T21:57:44.000Z","updated_at":"2019-05-03T12:45:16.000Z","dependencies_parsed_at":null,"dependency_job_id":"6b3771be-928a-44d2-94d1-a7aa3a7d0565","html_url":"https://github.com/do-community/do-blueprint-mysqlgrouprepl","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/do-community%2Fdo-blueprint-mysqlgrouprepl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/do-community%2Fdo-blueprint-mysqlgrouprepl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/do-community%2Fdo-blueprint-mysqlgrouprepl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/do-community%2Fdo-blueprint-mysqlgrouprepl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/do-community","download_url":"https://codeload.github.com/do-community/do-blueprint-mysqlgrouprepl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242157191,"owners_count":20081037,"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":[],"created_at":"2024-11-16T02:33:05.565Z","updated_at":"2025-12-07T02:02:35.568Z","avatar_url":"https://github.com/do-community.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"## MySQL Group Replication with ProxySQL\n\nWelcome to the MySQL Group Replication Blueprint repository.  This repository can be used to quickly set up a replicated database group using [MySQL group replication](https://dev.mysql.com/doc/refman/5.7/en/group-replication.html) to scale read requests and help ensure availability.  Access to the group is provided by [ProxySQL](http://www.proxysql.com/), a powerful, flexible routing component that can intelligently route queries and respond to changes on the backend.\n\nThis process should take between five to ten minutes.\n\nBy default, after cloning the project and executing the Terraform and Ansible steps described below, you will have a three member group replication database layer to handle your project's data.  The Blueprint will also create a server with ProxySQL installed and configured to connect with the group.  Due to security considerations, this component is best installed on the same server as your application server.\n\n## Architecture of MySQL Group Replication Blueprint\n\n![Architecture diagram of MySQL group replication blueprint]()\n\n* **3** 1GB Droplets for MySQL group replication members\n\t* Specs: 1 VCPU, 1GB memory, and 25GB SSD\n\t* Datacenter: NYC3\n\t* OS: Ubuntu 16.04\n\t* Software: MySQL server (upstream package)\n\n* **1** 1GB Droplet for the ProxySQL routing component\n\t* Specs: 1 VCPU, 1GB memory, and 25GB SSD\n\t* Datacenter: NYC3\n\t* OS: Ubuntu 16.04\n\t* Software: ProxySQL\n\nUsing the given Droplet sizes, **this infrastructure will cost $20 a month** to run.\n\nIn addition to the above software packages, a demonstration database called `playground` will be configured on the backend loaded with a small amount of dummy data.  An associated user called `playgrounduser` will be configured within MySQL and within the ProxySQL routing component.\n\n## Quickstart\n\nHere are the steps to get up and running.\n\n### Requirements\n\nThe software required to run DigitalOcean Blueprints are provided within a Docker image.  You will need to install Docker locally to run these playbooks.  You can find up-to-date instructions on how to download and install Docker on your computer [on the Docker website](https://www.docker.com/community-edition#/download).\n\nIf you'd prefer not to install Docker locally, you can create a dedicated control Droplet using the [DigitalOcean Docker One-click application](https://www.digitalocean.com/products/one-click-apps/docker/) instead.  You will also need [git](https://git-scm.com/downloads) available if it's not already installed.\n\n### Clone the Repo\n\nTo get started, clone this repository to your Docker server into a writeable directory:\n\n```\ncd ~\ngit clone https://github.com/do-community/do-blueprint-mysqlgrouprepl\n```\n\n### Add a Bash Alias for the Infrastructure Tools Docker Container\n\nOpen your shell configuration file using your preferred text editor:\n\n```\nnano ~/.bashrc\n```\n\nInside, at the bottom, add a function and definition for `complete` to simplify usage of the Docker image:\n\n```\n. . .\nfunction bp() {\n    docker run -it --rm \\\n    -v \"${PWD}\":\"/blueprint\" \\\n    -v \"${HOME}/.terraform.d\":\"/root/.terraform.d\" \\\n    -v \"${HOME}/.bp-ssh\":\"/root/.bp-ssh\" \\\n    -v \"${HOME}/.config\":\"/root/.config\" \\\n    -e ANSIBLE_TF_DIR='./terraform' \\\n    -e HOST_HOSTNAME=\"${HOSTNAME}\" \\\n    -e HOST_UID=\"$(id -u)\" \\\n    -e HOST_GID=\"$(id -g)\" \\\n    docommunity/bp \"$@\"\n}\n\ncomplete -W \"terraform doctl ./terraform.py ansible ansible-connection ansible-doc ansible-inventory ansible-pull ansible-config ansible-console ansible-galaxy ansible-playbook ansible-vault\" \"bp\"\n```\n\nSave and close the file when you are finished.  Source the file to read in the new function to your current session:\n\n```\nsource ~/.bashrc\n```\n\n### Run the `setup.yml` Local Playbook\n\nNext, enter the repository directory and run the `setup.yml` playbook.  This will configure the local repository and credentials.\n\n*Note*: The initial run of this playbook may show some warnings since the Ansible dynamic inventory script cannot yet find a valid state file from Terraform.  This is expected and the warnings will not be present once a Terraform state file is created.\n\n```\nbp ansible-playbook setup.yml\n```\n\nEnter your DigitalOcean read/write API key if prompted (you can generate a read/write API key by visiting the [API section of the DigitalOcean Control Panel](https://cloud.digitalocean.com/settings/api/tokens) and clicking \"Generate New Token\").  Confirm the operation to create a dedicated SSH key pair by typing \"yes\" at when prompted.  As part of this configuration, a dedicated SSH key pair will be generated for managing Blueprints infrastructure and added to your DigitalOcean account.\n\nThe playbook will:\n\n* Check the `doctl` configuration to try to find an existing DigitalOcean API key\n* Prompt you to enter an API key if it could not find one in the `doctl` configuration\n* Check if a dedicated `~/.ssh/blueprint-id_rsa` SSH key pair is already available locally.\n* Generate the `~/.ssh/blueprint-id_rsa` key pair if required and add it to your DigitalOcean account.\n* Install the Terraform Ansible provider and the associated Ansible dynamic inventory script that allows Ansible to read from the Terraform state file\n* Generate a `terraform/terraform.tfvars` file with your DigitalOcean API key and SSH key defined\n* Initialize the `terraform` directory so that it's ready to use.\n* Install the Ansible roles needed to run the main playbook.\n\nOnce the `setup.yml` playbook has finished, follow the instructions in the final output to complete the configuration.  You can optionally add the key to your local SSH agent:\n\n```\neval `ssh-agent`\nssh-add ~/.bp-ssh/blueprint-id_rsa\n```\n\nOtherwise, when SSHing into your Blueprint infrastructure, you will need to pass in the appropriate SSH key using the `-i` flag:\n\n```\nssh -i ~/.bp-ssh/blueprint-id_rsa \u003cusername\u003e@\u003cserver_ip\u003e\n```\n\n### Create the Infrastructure\n\nMove into the `terraform` directory.  Adjust the `terraform.tfvars` and `main.tf` file if necessary (to adjust the number or size of your servers for instance).  When you are ready, create your infrastructure with `terraform apply`:\n\n```\ncd terraform\nbp terraform apply\n```\n\nType `yes` to confirm the operation.\n\n### Apply the Configuration\n\nMove back to the main repository directory.  Use the `ansible -m ping` command to check whether the hosts are accessible yet:\n\n```\nbp ansible -m ping all\n```\n\nThis command will return failures if the servers are not yet accepting SSH connections or if the userdata script that installs Python has not yet completed.  Run the command again until these failures disappear from all hosts.\n\nOnce the hosts are pinged successfully, apply the configuration with the `ansible-playbook` command. The infrastructure will be configured primarily using the values of the variables set in the `group_vars` directory and in the role defaults:\n\n```\nbp ansible-playbook site.yml\n```\n\n### Accessing the Hosts\n\nTo display the IP addresses for your infrastructure, you can run the `./terraform.py` script manually by typing:\n\n```\nbp ./terraform.py\n```\n\nAmong other information, you should be able to see the IP addresses of each of your servers:\n\n```\n  . . .\n  \"_meta\": {\n    \"hostvars\": {\n      \"mysql-node-1\": {\n        \"ansible_host\": \"198.51.100.5\"\n      }, \n      \"mysql-proxy-1\": {\n        \"ansible_host\": \"198.51.100.6\"\n      }, \n      \"mysql-node-3\": {\n        \"ansible_host\": \"198.51.100.7\"\n      }, \n      \"mysql-node-2\": {\n        \"ansible_host\": \"198.51.100.8\"\n      }\n    }\n  }\n}\n```\n\n### Testing the Deployment\n\nOnce the infrastructure is configured, you can SSH into the ProxySQL server to check the setup.  SSH into the ProxySQL host from the computer with your Blueprint repository (this machine will have the correct SSH credentials).\n\nAfterwards, you can use ProxySQL in the following ways:\n\n#### Connect through ProxySQL to the playground database\n\nConnect to the demonstration database by using the connection information in the `playgrounduser.cnf` defaults file, located in the `root` user's home diretory by default:\n\n```\nmysql --defaults-file=playgrounduser.cnf\n```\n\nFrom here, you can view the contents of the sample table:\n\n```\nSELECT * FROM playground.equipment;\n```\n```\n+----+--------+-------+--------+\n| id | type   | quant | color  |\n+----+--------+-------+--------+\n|  1 | slide  |     2 | blue   |\n|  8 | swing  |    10 | yellow |\n| 15 | seesaw |     3 | green  |\n+----+--------+-------+--------+\n3 rows in set (0.00 sec)\n```\n\nWriting to the table should also work correctly.  ProxySQL will ensure that the operation goes to the primary write server:\n\n```\nINSERT INTO playground.equipment (type, quant, color) VALUES ('ladder', 4, 'orange');\n```\n```\nQuery OK, 1 row affected (0.00 sec)\n```\n\nIf you exit back into the shell, you can see ProxySQL cycle through the backend pool of read-only hosts for non-write operations:\n\n```\nmysql --defaults-file=playgrounduser.cnf -e 'select @@hostname'\n```\n```\n+--------------+\n| @@hostname   |\n+--------------+\n| mysql-node-2 |\n+--------------+\n```\n\nIssuing the command a few more times will usually cycle through other backends (some repeats may occur, but that's generally okay):\n\n```\nmysql --defaults-file=playgrounduser.cnf -e 'select @@hostname'\n```\n```\n+--------------+\n| @@hostname   |\n+--------------+\n| mysql-node-3 |\n+--------------+\n```\n\n#### Connect to the ProxySQL administration interface\n\nYou can connect to the ProxySQL administration interface to manage the ProxySQL instance and query MySQL group health data.  This will use the primary defaults file for the `root` user automatically:\n\n```\nmysql\n```\n\nFrom here, you view information about your ProxySQL configuration by querying the tables available.  For instance, to view the connected backends, type:\n\n```\nSELECT * FROM runtime_mysql_servers;\n```\n```\n+--------------+----------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+\n| hostgroup_id | hostname       | port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment |\n+--------------+----------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+\n| 2            | 198.51.100.5   | 3306 | ONLINE | 1      | 0           | 1000            | 0                   | 1       | 0              |         |\n| 3            | 198.51.100.7   | 3306 | ONLINE | 1      | 0           | 1000            | 0                   | 1       | 0              |         |\n| 3            | 198.51.100.5   | 3306 | ONLINE | 1      | 0           | 1000            | 0                   | 1       | 0              |         |\n| 3            | 198.51.100.8   | 3306 | ONLINE | 1      | 0           | 1000            | 0                   | 1       | 0              |         |\n+--------------+----------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+\n4 rows in set (0.00 sec)\n```\n\nHere, you can see four rows representing three servers (one of the servers is in both the 2 and 3 host groups).  To see what these hostgroup IDs represent, query the associated table:\n\n```\nselect * from runtime_mysql_group_replication_hostgroups;\n```\n```\n+------------------+-------------------------+------------------+-------------------+--------+-------------+-----------------------+-------------------------+---------+\n| writer_hostgroup | backup_writer_hostgroup | reader_hostgroup | offline_hostgroup | active | max_writers | writer_is_also_reader | max_transactions_behind | comment |\n+------------------+-------------------------+------------------+-------------------+--------+-------------+-----------------------+-------------------------+---------+\n| 2                | 4                       | 3                | 1                 | 1      | 1           | 1                     | 100                     | NULL    |\n+------------------+-------------------------+------------------+-------------------+--------+-------------+-----------------------+-------------------------+---------+\n1 row in set (0.01 sec)\n```\n\nWith this mapping, we can see that the group is configured to allow both reads and writes to go to the primary host, while the other hosts are only capable of accepting reads.\n\nYou can learn more about how the ProxySQL model of operation by reading [the project's wiki pages](https://github.com/sysown/proxysql/wiki).\n\n### Deprovisioning the Infrastructure\n\nTo destroy all of the servers in this Blueprint, move into the `terraform` directory again and use the `destroy` action:\n\n```\ncd terraform\nbp terraform destroy\n```\n\nYou will be prompted to confirm the action.  While you can easiliy spin up the infrastructure again using the Terraform and Ansible steps, keep in mind that any data you added will be lost on deletion.\n\n## Ansible Roles\n\nThis repository uses the following roles to configure the MySQL group replication and ProxySQL servers:\n\n* [MySQL group replication role](https://github.com/do-community/ansible-role-mysql)\n* [ProxySQL role](https://github.com/do-community/ansible-role-proxysql)\n\nYou can read the README files associated with each role to understand how to adjust the configuration.\n\n## How Do I Use This With My Existing Infrastructure?\n\nIf you already have an application server or servers, you can adapt the `terraform/main.tf` file to your needs.  You will want to remove the `mysql-proxy` `digitalocean_droplet` resource (which provisions a new application server) and set the `ansible_mysql_proxy` `ansible_host` resource to use the hostname and IP address of your existing infrastructure.  The `inventory_hostname` should be set to the name you want to use within Ansible and `ansible_host` should be set to the server's IP address.  You can configure as many of these resources as required.\n\nIf you already have a database server, you will need to dump the existing data to a file and then import it into the cluster.  This can be done manually once the cluster is provisioned, or can be done by Ansible if you place a dump file per database into the top-level `files` directory and configure the `mysql_databases` Ansible variable to load each file.\n\n## Customizing this Blueprint\n\nYou can customize this Blueprint in a number of ways depending on your needs.\n\n### Modifying Infrastructure Scale\n\n**Note:** Adjusting the scale will affect the cost of your deployment.\n\nTo adjust the scale of your infrastructure, open the `terraform/main.tf`file in a text editor:\n\n```\nnano terraform/main.tf\n```\n\nYou can change the number of MySQL group replication members involved in your database layer by adjusting the `count` parameter in the `digitalocean_droplet` definition for the `mysql-node` resources:\n\n```\n. . .\nresource \"digitalocean_droplet\" \"mysql-node\" {\n  count     = \"3\"\n  . . .\n```\n\nRead the [MySQL documentation on group replication fault tolerance](https://dev.mysql.com/doc/refman/5.7/en/group-replication-fault-tolerance.html) to understand the ways different configurations affect availability.  You should always deploy an odd number of MySQL servers to balance primary election majorities with fault tolerance.  According to the documentation, [a maximum of nine members are permitted](https://dev.mysql.com/doc/refman/5.7/en/group-replication-frequently-asked-questions.html#group-replication-maximum-number-servers).\n\nTo deploy more ProxySQL nodes, adjust the `count` parameter in the `digitalocean_droplet` definition for the `mysql-proxy` resources:\n\n```\n. . .\nresource \"digitalocean_droplet\" \"mysql-proxy\" {\n  count     = \"1\"\n  . . .\n```\n\nThis will create additional servers with ProxySQL configured to access your group.  Usually, these servers should be configured with your application software after the ProxySQL service has been configured.\n\nTo vertically scale either the MySQL servers or the ProxySQL application servers, you can adjust the `size` parameter associated with the instances.  Use `bp doctl compute size list` to get a list of available Droplet sizes.\n\n### Adjusting the Software Configuration\n\nTo adjust the way MySQL group replication or ProxySQL are deployed you need to modify the parameters that the Ansible playbook uses to configure each service.  The Ansible configuration for these components is primarily defined within the top-level `group_vars` directory and in the role defaults files (found in `roles/\u003crole_name\u003e/defaults/main.yml` after running the `setup.yml` playbook).\n\nConfiguration items that are needed by both MySQL and ProxySQL servers are defined in `group_vars/all.yml`  These variables typically use a `shared_` prefix and are referenced in the more specific `group_vars` files and to translate them to the variables the individual roles expect.  The `group_vars/mysql_nodes.yml` file is used to define configuration specific to the MySQL group members.  The `group_vars/mysql_proxy.yml` file is used to define configuration specific to the ProxySQL servers.\n\nTo understand what each variable means and how they work, read the variable descriptions within the README files associated with the individual roles.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdo-community%2Fdo-blueprint-mysqlgrouprepl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdo-community%2Fdo-blueprint-mysqlgrouprepl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdo-community%2Fdo-blueprint-mysqlgrouprepl/lists"}