Configuration
The MYSQL module is driven by the inventory: you declare the desired cluster, and mysql.yml converges the live state to match. This page covers topology planning and every configuration block; see Parameters for the full reference.
Before You Deploy
- Target nodes are
NODE-managed, with the shared CA installed at/etc/pki/ca.crt(managed by thenode_carole; the MySQL role only issues leaf certificates); - Package repositories include the
mysqlmodule:node_repo_modules: node,infra,mysql, or a local repo cached withrepo_extra_packages: [mysql]; - The platform is in the support matrix:
x86_64on EL 8/9/10, Debian 12/13, Ubuntu 22/24; oraarch64on EL 9/10; - The three platform passwords (
mysql_root_password,mysql_monitor_password,mysql_cluster_password) are set to production values — preflight rejectsCHANGE_MEplaceholders.
Identity
Each cluster is an inventory group with two required identity parameters:
| Parameter | Level | Description |
|---|---|---|
mysql_cluster | Cluster | Cluster name; must match the inventory group holding the members. Also the backup directory and the cls monitoring label |
mysql_seq | Instance | 1 for standalone; sequential 1..3 for HA; doubles as server_id |
Topology is inferred from member count: 1 member is a standalone, 3 members form an InnoDB Cluster; any other count is rejected at preflight. mysql_seq=1 is only the bootstrap coordinator, not the runtime primary.
Instance names follow {{ mysql_cluster }}-{{ mysql_seq }} (e.g. my-test-1). The inventory host address (IP or resolvable hostname) is the advertised MySQL and MGR address and cannot be changed by an ordinary rerun.
Standalone Instance
The minimal standalone declaration:
Standalone instances have no Router (6446/6447 do not exist); clients connect to 3306 directly. Backups, monitoring, and TLS behave exactly as in HA mode.
Three-Node InnoDB Cluster
This yields a single-primary MGR cluster: one writable PRIMARY, two read-only SECONDARY members, tolerating one node failure. Every member runs a Router, so port 6446 on any member reaches the current primary.
Every mysql.yml run must select all members of the cluster with -l (or omit -l to converge every MySQL cluster). Partial member selection is rejected at preflight — a deliberate guard against topology divergence.
Databases
mysql_databases declares databases additively:
| Field | Default | Description |
|---|---|---|
name | required | Database name, [A-Za-z0-9_$-]; system schema names are rejected |
encoding | utf8mb4 | Character set |
collate | utf8mb4_0900_ai_ci | Collation |
Each entry accepts only these three fields; preflight validation rejects additional keys.
Convergence is additive: reruns create missing databases, but removing an entry never drops one. Deleting data is a manual operation by design.
The platform enables sql_require_primary_key=ON by default, so creating a PK-less table fails with ERROR 3750. This is not pedantry: PK-less tables are read-only under MGR and block AdminAPI cluster rebuilds during disaster recovery. Define a primary key on every table (invisible-column PKs work too); override via mysql_parameters only if you truly must.
Users
mysql_users declares users and grants additively:
Grant scopes are written as 'db.table', with * wildcards on either side ('*.*', 'app.*'); values are comma-separated privilege names. Preflight validates usernames, hosts, scopes, and privilege words, rejecting malformed declarations.
Semantics:
- Missing users are created; existing users get their password and connection limit updated;
- Grants in
privare applied, but removing a mapping does not REVOKE; - The platform identities (
root,dbuser_monitor,dbuser_cluster,dbuser_backup) cannot be declared; - The server enforces TLS: the client default
PREFERREDmode negotiates encryption automatically, and plaintext (DISABLED) connections are rejected; prefer an explicitVERIFY_CA.
Parameter Overrides
mysql_parameters overrides [mysqld] options, rendered at the end of the managed config so the last value wins:
Rules and safety:
- Keys must be plain option names (letter first;
._-allowed); values must be single-line scalars; - The rendered config still passes
mysqld --validate-config, so a bad option fails at deploy time without touching the running service; - Platform-reserved options cannot be overridden: identity and protocol (
user,pid_file,server_id,datadir,socket,port,bind_address,mysqlx_bind_address,report_host,mysqlx, …), replication and plugins (gtid_mode,enforce_gtid_consistency,log_bin,relay_log,plugin_load*,clone,plugin_clone,plugin_mysqlx,group_replication_*, …), and TLS (require_secure_transport,ssl_*) are role-managed and rejected if declared; - Parameter changes trigger an orchestrated rolling restart: secondaries first, primary last.
Memory needs no configuration: the buffer pool is 25% of node memory (256MB floor), redo capacity is half the buffer pool (128MB–4GB), and replica parallelism follows CPU count. For precise control, override innodb_buffer_pool_size and friends via mysql_parameters.
Backup Settings
The backup contract (details in Administration):
- One XtraBackup full physical backup per day, prepared immediately after — the output directory is directly restorable;
- Standalone backs up locally; in HA every member’s timer fires, but only the current PRIMARY actually runs — other members skip cleanly;
- Layout is
<path>/<cluster>/<UTC timestamp>/, with an atomiclatestsymlink and retention-based pruning; - No incremental chain, no binlog archiving, no PITR: for a standalone the recovery point is the most recent backup.
After a failover, new backups land on the new primary’s local disk. Before restoring, check the latest timestamp on all members and take the newest. For off-site protection, sync the backup directory yourself (e.g. a scheduled rclone/rsync job).
Platform Credentials
Credential lifecycle rules:
- Passwords must be single-line and must not keep the
CHANGE_MEprefix — enforced at preflight; - On HA clusters,
mysql_cluster_passwordcannot be rotated by an ordinary rerun: it is embedded in cluster metadata and Router keyrings, so implicit rotation is rejected (standalone instances have no such binding and rotate normally); mysql_root_passwordcannot be silently reset either: if the live root password differs from the declaration, the task fails explicitly instead of overwriting it.
Credential material lives in /etc/mysql/pigsty/ (root-owned: directory 0700, files 0600), including ready-to-use client configs for local operations:
Full Example
Standalone plus three-node HA, matching the four-node sandbox:
See conf/demo/mysql.yml for the full template. Note that conf/mysql.yml is the OpenHalo template (a MySQL-compatible PostgreSQL kernel) and is unrelated to this module.