MySQL Router
Overview
MySQL Router is Oracle's official lightweight connection proxy for MySQL. It gives applications a single stable endpoint and routes each connection to a healthy backend. It is the standard connection tier in front of a MySQL InnoDB Cluster or replica set.
This SecureAnyCloud image installs MySQL Router 8.4 from Oracle's official APT repository on Ubuntu 24.04 LTS (Noble Numbat). It also bundles a MySQL 8.4 LTS Community server as the default backend, so the appliance routes live traffic as soon as it boots.
What you get:
- MySQL Router 8.4 from Oracle's official APT repository
- A bundled MySQL 8.4 LTS Community server as the default backend
- Four routing listeners: classic and X protocol, each with a read/write and a read-only port
- A unique MySQL root password and a unique application-user password, generated automatically on first boot, with no credential baked into the image
Topology
The image ships a self-contained routing tier. Use it immediately, then re-point it at your own database in production.
Listener Port Bind Routes to
Classic protocol, read/write 6446 0.0.0.0 MySQL 127.0.0.1:3306
Classic protocol, read-only 6447 0.0.0.0 MySQL 127.0.0.1:3306
X protocol, read/write 6448 0.0.0.0 MySQL 127.0.0.1:33060
X protocol, read-only 6449 0.0.0.0 MySQL 127.0.0.1:33060
The bundled MySQL server is bound to loopback (127.0.0.1) and is reachable only through the router. MySQL authentication is the security gate: each VM has its own password, and anonymous login is not allowed.
In production, you point the router at your own MySQL server or InnoDB Cluster. This is a configuration change, not a boot dependency.
Prerequisites
- An Azure subscription with permission to create virtual machines
- An SSH key pair, whose public key you upload during VM creation
- A MySQL client installed locally, if you want to connect from your workstation
Step 1 - Deploy from the Azure Portal
- Find MySQL Router 8.4 on Ubuntu 24.04 by SecureAnyCloud in the Azure Marketplace and select Create.
- On the Basics tab, select or create a resource group, choose East US as the region, and set the VM size to Standard_B2s (2 vCPU / 4 GB RAM) or larger.
- Under Administrator account, choose SSH public key and paste your public key.
- On the Networking tab, open the router ports you intend to use, in addition to 22 (SSH). Use 6446 (read/write) and 6447 (read-only) for the classic protocol, and 6448 and 6449 for the X protocol. Restrict the source to your application subnet.
- Select Review + create, then Create.
Step 2 - Deploy with the Azure CLI
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:mysql-router:default:latest
az vm create \
--resource-group <your-resource-group> \
--name mysql-router \
--image sac1647283583153:mysql-router:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_rsa.pub \
--public-ip-sku StandardWhen the VM is running, open the router read/write port:
az vm open-port --port 6446 --resource-group <your-resource-group> --name mysql-routerStep 3 - Connect over SSH
ssh azureuser@<vm-ip>On first boot, mysql-router-firstboot.service starts the backend MySQL server and generates the per-VM root and application passwords. It also creates the default SecureAnyCloud database and the sac_app user, then starts MySQL Router.
Allow 30-60 seconds for the service to finish before you connect.
Step 4 - Retrieve your credentials
sudo cat /stage/scripts/mysql-router-credentials.logThe file is owned by root:root with mode 0600. It lists the generated passwords, the router ports and ready-to-use connect commands. Store the passwords somewhere safe before you rotate them.
Step 5 - Verify the routing topology
Confirm that both services are active, then inspect the listening ports. The router listens on 0.0.0.0, while the backend MySQL server listens on loopback only.
systemctl is-active mysql mysqlrouter
sudo ss -tlnp | grep -E ':(3306|33060|6446|6447|6448|6449) 'Step 6 - Connect through the router
Connect to the router read/write port (6446) with the generated application password. Write a sentinel row, then read it back. The row records the backend port the connection actually reached, which proves the traffic went through the router.
APP_USER=$(sudo awk -F= '/^app_user=/{print $2}' /stage/scripts/mysql-router-credentials.log)
APP_PASS=$(sudo awk -F= '/^app_password=/{print $2}' /stage/scripts/mysql-router-credentials.log) MYSQL_PWD="$APP_PASS" mysql -u "$APP_USER" -h 127.0.0.1 -P 6446 sac --table <<'SQL' CREATE TABLE IF NOT EXISTS demo (id INT PRIMARY KEY AUTO_INCREMENT, note VARCHAR(64), via_port INT, backend_port INT); INSERT INTO demo (note, via_port, backend_port) VALUES ('hello via router', 6446, @@port); SELECT note, via_port AS connected_to_router_port, backend_port AS mysql_server_port FROM demo ORDER BY id DESC LIMIT 1; SQLYou connected to the router on 6446, but the backend reports its port as 3306. The connection was routed through MySQL Router to the MySQL server behind it.
Step 7 - Use the read-only port and inspect the router log
Read the same data back over the router's read-only port (6447). Then confirm that the router logged that it is accepting connections on each routing port.
APP_USER=$(sudo awk -F= '/^app_user=/{print $2}' /stage/scripts/mysql-router-credentials.log)
APP_PASS=$(sudo awk -F= '/^app_password=/{print $2}' /stage/scripts/mysql-router-credentials.log) MYSQL_PWD="$APP_PASS" mysql -u "$APP_USER" -h 127.0.0.1 -P 6447 sac --table \
-e "SELECT note, via_port, backend_port FROM demo ORDER BY id DESC LIMIT 3;"
sudo grep 'Start accepting' /var/log/mysqlrouter/mysqlrouter.log | tail -4Step 8 - Point the router at your own MySQL or InnoDB Cluster
In production, the router fronts your own database. Edit the destinations in /etc/mysqlrouter/mysqlrouter.conf and restart the service. For a single server, change the destinations lines to your host:
sudo sed -i 's#destinations=127.0.0.1:3306#destinations=<your-mysql-host>:3306#' /etc/mysqlrouter/mysqlrouter.conf
sudo sed -i 's#destinations=127.0.0.1:33060#destinations=<your-mysql-host>:33060#' /etc/mysqlrouter/mysqlrouter.conf
sudo systemctl restart mysqlrouterFor a MySQL InnoDB Cluster, re-bootstrap the router against the cluster. The router then tracks membership and failover automatically. Bootstrapping rewrites mysqlrouter.conf with a metadata cache.
sudo mysqlrouter --bootstrap <cluster-admin>@<your-mysql-host>:3306 \
--user mysqlrouter --force sudo systemctl restart mysqlrouterStep 9 - Manage the service
sudo systemctl status mysqlrouter --no-pagersudo /usr/local/sbin/mysql-router-status.shsudo journalctl -u mysqlrouter -n 50 --no-pagerStep 10 - Security recommendations
- Point the router at your own MySQL server or InnoDB Cluster (Step 8). Keep the bundled backend for evaluation only, or repurpose it as a production node.
- Open only the router ports your applications need (6446/6447 for classic, 6448/6449 for X protocol). Restrict the NSG source to your application subnet.
- Rotate the generated application password, and create least-privilege users for each application:
ROOT_PASS=$(sudo awk -F= '/^root_password=/{print $2}' /stage/scripts/mysql-router-credentials.log)
mysql -u root --password="${ROOT_PASS}" --socket=/var/run/mysqld/mysqld.sock <<SQL ALTER USER 'sac_app'@'%' IDENTIFIED WITH caching_sha2_password BY '<new-password>'; FLUSH PRIVILEGES; SQL- Keep the system patched with
sudo apt-get update && sudo apt-get upgrade -y.
Troubleshooting
Router not accepting connections. Confirm that it is listening, then check the log:
sudo ss -tlnp | grep 6446sudo tail -n 50 /var/log/mysqlrouter/mysqlrouter.logBackend unreachable. The router starts even when its destination is down, and it returns errors to clients until the backend is up. Confirm that the backend MySQL server is running and reachable from the router host:
sudo systemctl status mysql --no-pagerSupport
This image is provided and supported by SecureAnyCloud. For deployment questions, configuration help or bug reports, contact us at sales@secureanycloud.com.
For upstream documentation, see the MySQL Router 8.4 Reference.
Deploy on Azure
Launch mysql-router with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com