Skip to content

Latest commit

 

History

History
172 lines (139 loc) · 8.41 KB

File metadata and controls

172 lines (139 loc) · 8.41 KB

MySQL Router compatibility plugin

The mysql_router plugin lets a ProxySQL 4.0 build register with an InnoDB Cluster as a MySQL Router-compatible instance. It reads MySQL InnoDB Cluster Metadata 2.2, maintains ProxySQL-native servers, users, hostgroups, rules, and listeners, and reconciles them as topology and account state change.

Build and install

Build the core and the real plugin with the same feature tiers and toolchain:

make PROXYSQL40=1 PROXYSQL31=1 -j2
make PROXYSQL40=1 PROXYSQL31=1 -C plugins/mysql_router all
sudo make install

The source-tree artifact is plugins/mysql_router/proxysql_mysql_router.so; make install places it in /usr/lib/proxysql/plugins/proxysql_mysql_router.so. The plugin is part of the ProxySQL 4.0 build surface and is not yet included in release packages.

Bootstrap and normal startup

Supply the metadata password through a readable file descriptor. Passwords in the bootstrap URI are rejected.

exec 3< /run/secrets/mysql-router-bootstrap-password
proxysql --load-plugin=mysql_router \
  --bootstrap cluster_admin@db1.example:3306 \
  --bootstrap-password-fd=3 \
  --router-name=proxysql-router-1

Bootstrap uses the MySQL Shell-compatible registration and account contracts, stores the service credential through the core encrypted-secret service, and publishes the first complete topology before marking local bootstrap complete. Bootstrap is a one-shot configuration step: it writes the configuration to disk, including the Router endpoints in mysql-interfaces, and then exits. A bootstrap run never opens client listeners and never serves traffic. After bootstrap, start ProxySQL normally while continuing to load the plugin:

proxysql --load-plugin=mysql_router

The plugin resumes from its persisted identity, starts its reconciliation worker, and opens the Router-owned listener gates only after a complete live generation is available. MYSQL ROUTER RECONCILE requests an immediate reconciliation through the Admin interface.

Metadata connection TLS

Bootstrap accepts the MySQL Router TLS options for the metadata connection: --ssl-mode, --ssl-ca, --ssl-capath, --ssl-cert, --ssl-key, --ssl-cipher, --ssl-crl and --ssl-crlpath. Bootstrap stores them in mysql_router_config (metadata_ssl_mode, metadata_ssl_ca, ..., metadata_ssl_crlpath). The reconciler then uses the same TLS settings for every later metadata, health and user-sync connection.

Mode Behavior
DISABLED Plaintext.
PREFERRED (default) Requests TLS, and continues in plaintext only if the server does not offer it.
REQUIRED Requires TLS. The connection fails if TLS is not negotiated. The certificate is not verified. See the note below.
VERIFY_CA Requires TLS and verifies the server certificate against --ssl-ca/--ssl-capath. Connector/C also checks the hostname, so this is as strict as VERIFY_IDENTITY.
VERIFY_IDENTITY Requires TLS and verifies the certificate chain and the server hostname.

VERIFY_CA and VERIFY_IDENTITY require --ssl-ca or --ssl-capath. They never fall back to the system trust store. A client certificate and its key must be given together. Configurations that break these rules are rejected both by bootstrap and when the reconciler loads its configuration. Deployments bootstrapped before these keys existed have no metadata_ssl_* rows and use PREFERRED.

With REQUIRED, Connector/C 3.3 cannot refuse a server that offers no TLS before authenticating. ProxySQL checks for TLS once the connection is established and closes it if TLS was not negotiated, but by then the server has already received the metadata user name and the password's challenge response. The password itself is not sent unless the metadata account uses a cleartext authentication plugin. As in MySQL, REQUIRED does not verify the server, so it protects only against passive eavesdropping, not against an active attacker. Use VERIFY_CA or VERIFY_IDENTITY when the network path is not trusted: in those modes, Connector/C refuses a server without TLS before it authenticates.

Endpoints

Port Behavior
6033 Existing ProxySQL MySQL endpoint; fully operator-owned and query-aware
6446 Router Classic read/write endpoint; writer route, then fast-forward after the first COM_QUERY
6447 Router Classic read-only endpoint; eligible reader route, then fast-forward after the first COM_QUERY
6450 Router Classic read/write-split endpoint; remains query-aware and uses native ProxySQL query rules

The port numbers above are defaults. --conf-base-port and the listener options can move the three Router endpoints; behavior follows the compiled endpoint intent, not a hard-coded port comparison.

Like every other MySQL listener in ProxySQL, the Router endpoints are opened only at startup. Publication stores the Router endpoints in mysql-interfaces (memory and disk) but never opens or closes a listener at runtime. If a publication stages a mysql-interfaces value that differs from the active listeners, ProxySQL logs a warning, and the change takes effect at the next restart.

The direct rules use the native query-rule attribute {"switch_to_fast_forward":true}. Operators can insert a lower rule ID with apply=1 to override a Router default for selected users or traffic. Such operator rules remain operator-owned and are preserved byte-for-byte during Router reconciliation. The 6450 rules do not contain the fast-forward action, so normal ProxySQL query processing, hostgroup selection, and transaction tracking remain available there.

Network partitions

Each cluster member reports Group Replication health from its own point of view. A member cut off in a minority partition still answers queries, but it sees itself ONLINE and its peers UNREACHABLE, so its view has no quorum. The reconciler does not publish such a view while another member may still have quorum. It tries the other known members first and uses the first view that has quorum. Only if no reachable member reports quorum does it apply the cluster's unreachable_quorum_allowed_traffic policy to the view it has. This applies both to normal metadata reads and to the health-only fallback used while metadata is unavailable.

Ownership and collisions

The plugin allocates eight hostgroups for stable writer/reader routes and internal Group Replication, asynchronous-reader, and offline roles. It also owns its five baseline rules, its three listener endpoints, and only the users that were successfully normalized from metadata. Ownership is recorded in the core plugin ledger in both memory and disk.

Publication is one atomic generation across main, disk, and live runtime (servers, users, and query rules; listeners change only at restart). Unrelated operator servers, users, rules, interfaces, and attributes are not replaced. A collision with an operator-owned identity fails that object closed; the plugin reports the conflict rather than taking ownership. Explicit user release keeps the local row and transfers ownership to the operator.

Status and diagnostics

Useful Admin queries include:

SELECT * FROM runtime_mysql_router_status;
SELECT * FROM runtime_mysql_router_topology;
SELECT * FROM runtime_mysql_router_hostgroups;
SELECT * FROM runtime_mysql_router_users;
SELECT * FROM stats_mysql_router_refresh ORDER BY refresh_id DESC LIMIT 20;
SELECT * FROM stats_mysql_router_errors ORDER BY last_seen DESC;
SELECT rule_id,proxy_port,destination_hostgroup,attributes,comment
  FROM runtime_mysql_query_rules WHERE comment LIKE 'mysql_router:%';

runtime_mysql_router_status reports metadata and registration availability, active topology/user generations, gate readiness, staleness, collisions, and the last error. Closed listener gates reject an accepted connection before a session or MySQL handshake is created; they reopen only after the plugin has a complete usable generation.

Supported scope

The current foundation supports InnoDB Cluster Metadata 2.2, Group Replication members, and MySQL Shell-managed asynchronous read replicas. Routing Guidelines are deliberately not imported in this change; follow-up issue #6145 tracks conversion to or direct use of ProxySQL-native routing policy.

Current exclusions are MySQL X Router endpoints, takeover of an existing MySQL Router deployment, InnoDB ReplicaSet, ClusterSet, and release packaging. Each requires its own reviewed implementation and acceptance plan.