MySQL
Edka provisions MySQL on your cluster with
MOCO. Each database is a MOCO
MySQLCluster in the mysql namespace. Its volumes and Secrets stay in your
cluster, and its backups go to a bucket you own.
A MySQL database has Overview, Insights, Logs, Users & DB, Backups, and Settings tabs.
Prerequisites
Section titled “Prerequisites”- For
3or5instances with Require separate nodes, one eligible node for each instance. - For backups, an Object Storage integration with the Amazon S3 or S3-Compatible provider. The bucket must be reachable from your cluster, with credentials that can list, upload, read, and delete backup objects. Google Cloud Storage and Azure Blob Storage integrations are not MySQL backup targets.
- For a Tailscale endpoint, the Tailscale add-on installed on the cluster. For a private load balancer, private networking enabled on the cluster.
Create a database
Section titled “Create a database”- Open the cluster and select Databases under Workloads. Select Create Database, then pick MySQL.
- On General, enter the Database name and pick the MySQL version.
Set Instance count to
1 instance, or to3 instancesor5 instancesfor semi-synchronous replication with automatic failover. Set Storage size (Gi) and Storage class. The name and the storage class are fixed after creation. - On Resources, set CPU and memory, and the Replica placement.
- On Placement, pick a Node pool or keep Default cluster placement. Keep Tolerate node pool taints on when the pool is tainted.
- On Configuration, review the server settings.
- On Users, set the application database and user, and add more users and databases.
- On Access, keep External Access off for applications that connect from inside the cluster, or turn it on and pick a network.
- On Backup, select the backup storage and schedule, or restore an existing backup.
- Select Create MySQL.
The versions are 8.4.8.1 (the default), 8.4.3, and 8.0.40. The fourth
component in 8.4.8.1 identifies the MOCO image build. The MySQL server version
is 8.4.8.
Edka installs MOCO and cert-manager with the first MySQL database.
Kubernetes names
Section titled “Kubernetes names”The database name is a display name. In Kubernetes the database is called
mysql-<32 hex characters>, shown as Runtime resource in the
Configuration card on Overview. Copy endpoints from Overview instead
of building them from the display name.
| Object | Name |
|---|---|
| Write Service | moco-<runtime>-primary.mysql.svc.cluster.local:3306 |
| Read Service | moco-<runtime>-replica.mysql.svc.cluster.local:3306 |
| Pods | moco-<runtime>-0, moco-<runtime>-1, and so on |
Resources, placement, and storage
Section titled “Resources, placement, and storage”Each instance requests 250 m of CPU and 512 Mi of memory by default. These
are starting values to size for your workload. CPU limit (m) and Memory
limit (Mi) are optional, and empty means no limit.
Replica placement on the Resources tab has two options. Prefer
separate nodes lets replicas share a node when there are too few.
Require separate nodes keeps every instance on its own node and leaves pods
Pending when there are too few eligible nodes.
Each instance has its own data volume. Three instances with 10 GiB each
provision 30 GiB of data storage.
You can grow Storage size (Gi) from Settings, up to 1000. It cannot
shrink, and the storage class cannot change. Growing needs a StorageClass that
allows volume expansion. Edka reports the update ready once every volume has the
new capacity and the filesystem resize has finished.
Users and databases
Section titled “Users and databases”The Users & DB tab and the Users tab of Settings hold the same editor. Save the page to apply changes.
- Application Access creates the application Database and
Application user. Both names are fixed after creation. With the switch
off, applications use MOCO’s built-in
moco-writableaccount. - Add User creates an account as
'<name>'@'%'with a grant for each database you select. Read grantsSELECTandSHOW VIEW. Read and write addsINSERT,UPDATE,DELETE, andEXECUTE. Database owner grants the full set of privileges on that database. - Add Database creates a database.
The editor holds up to 50 users and 50 databases. The user name root, user
names starting with moco-, and MySQL’s system database names are reserved.
Edka leaves an account that already exists in MySQL alone. To take it over, turn on Adopt an existing account for that user, or Adopt an existing application user. Adopting replaces the account’s password and grants. On the users it manages, Edka revokes grants made outside Edka.
Desired state controls removal. For a database, Stop managing, keep data leaves the database in MySQL and Drop database and data deletes it permanently when you save. For a user, Delete user removes the account.
Passwords are stored in Kubernetes Secrets in the mysql namespace, with
username and password keys. Use the application credentials for application
connections.
Operator passwords
Section titled “Operator passwords”On the Access tab, Operator Passwords sets your own Admin password and Writable password for MOCO’s built-in accounts. The admin password can be at most 32 bytes, because MOCO also uses it for replication. Entering a new value rotates the password and restarts the instances one at a time.
Server settings
Section titled “Server settings”The Configuration tab sets MySQL server variables. An empty field uses the operator default. Saving a change restarts the instances one at a time.
| Field | Range | Default on create |
|---|---|---|
| Maximum connections | 10 to 10000 | 150 |
| Maximum packet size (Mi) | 1 to 1024 | 64 |
| InnoDB buffer pool (Mi) | 16 to 196608 | empty |
| Idle connection timeout (seconds) | 1 to 604800 | empty |
| Slow query threshold (seconds) | 0 to 3600 | 2 |
With InnoDB buffer pool (Mi) empty, MOCO sizes the cache from the instance resources. A value you enter can be at most 75% of the memory limit, or of the memory request when there is no limit. Slow Query Log is on by default. The form does not accept a MySQL configuration file.
Connections and TLS
Section titled “Connections and TLS”Overview shows the connection details. With External Access off, MySQL is reachable from inside the cluster only.
To reach it from outside, open the Access tab, turn on External Access,
pick a Network, and set the Port. The default is 3306. Inside the
cluster MySQL stays on 3306 whatever port you set. The networks, hostname, and
certificate work the same for every engine. See
External access.
| Network | Reachability |
|---|---|
LoadBalancer | A public IP, reachable from the internet. |
Private LoadBalancer | An IP in the cluster’s private network, reached through private routing. |
Tailscale | An endpoint on your tailnet. |
The hostname stays the same when you switch networks. Only its address changes, and Edka updates the DNS record within five minutes.
With external access on, MySQL serves the hostname’s certificate over TLS 1.2
and 1.3. The users Edka provisions and MOCO’s built-in moco-writable and
moco-readonly accounts get REQUIRE SSL on every network. Accounts you create
directly in SQL keep their own settings. Edka routes external traffic to the
primary only after the certificate is loaded and REQUIRE SSL is in place.
Turning external access off lifts REQUIRE SSL again.
Clients inside the cluster also need TLS while external access is on. The
certificate names only the Edka hostname, so they connect with
--ssl-mode=REQUIRED, which encrypts the connection without checking the
hostname. The Internal write and Internal read cards on Overview
list ssl-mode = REQUIRED among their parameters. The connection string on
those cards carries no TLS option, so add it in your client.
Once the certificate is issued, Verified connection on Overview shows the client command:
mysql --host='<hostname>' --port=3306 --user='<user>' --password --ssl-mode=VERIFY_IDENTITY --ssl-ca="$SYSTEM_CA_BUNDLE" '<database>'The MySQL CLI does not read the system trust store on its own. Set
SYSTEM_CA_BUNDLE to your operating system’s CA bundle, for example
/etc/ssl/cert.pem on macOS or /etc/ssl/certs/ca-certificates.crt on Debian
and Ubuntu. Other clients verify with their default trust stores.
Scheduled and manual backups
Section titled “Scheduled and manual backups”- Open Settings, then Backup, and turn on the Backups switch. The same tab is in the create form.
- Select Backup storage.
- Set Interval (hours) from
1to168. The default is24. - Set Retention (days) from
1to365. The default is7. - Review Workspace (Gi), the temporary volume for dumps and binary logs. It defaults to twice the data volume size.
- Save, then use Backups to inspect completed snapshots and failures.
The schedule runs on the hour in UTC, as the mysql-backup-<database-id>
CronJob in the mysql namespace. A backup starts once the interval has passed.
Scheduled backups keep running while Edka is unreachable, and the Backups
tab catches up when the connection returns. Backup now takes an extra
backup to the same destination. It is available when backups are on, the
database is ready, and no other backup is running. A backup job has a 24 hour
deadline.
Each backup holds a full dump and a binary log archive, written by
moco-backup to moco/mysql/<runtime>/<timestamp>/ in the bucket.
Each backup keeps the retention that was set when it was taken. Retention
removes expired backups unless a restore still uses them. Deleting a database
keeps its backups in the bucket and on the restore list until their retention
ends. Keep the storage integration and the bucket available.
Recovery window
Section titled “Recovery window”MySQL archives binary logs during backup runs, not continuously. A time between two snapshots becomes recoverable only after a later successful run has archived the logs that cover it. Backups shows the Latest confirmed recovery time. A schedule alone does not make every recent transaction recoverable.
A recovery time is a whole second in UTC, at or after the selected snapshot and strictly before the end of its archived interval. To recover at or after that boundary, select the next snapshot instead.
Restore to a new installation
Section titled “Restore to a new installation”- On Backups, select Restore beside a completed snapshot.
- Enter the New installation name, which defaults to
<source>-restored. - Under Recovery method, choose Restore this snapshot, or Restore to an archived time when the snapshot has an archived interval. For the latter, enter the Recovery time (UTC).
- Select a Storage class and a Storage size (Gi) at least as large as the source volume.
- Select Restore and follow the new database’s progress.
Restore creates a separate database on the backup’s exact MySQL version and leaves the source unchanged. The new database keeps the source’s instance count, resources, server settings, users, databases, and grants. It gets new passwords and default placement, and it starts with external access off, backups off, and operator passwords off. Set up access and backups afterwards, and point applications at the new connection details.
To recover a deleted database, start a new MySQL database, open the Backup tab, and pick the snapshot under Restore an existing backup. Organization owners and administrators can also select backups from other clusters in the organization. The storage integration must still point at the bucket and endpoint that hold the backup, and the destination cluster needs the storage class you select.
Maintenance and upgrades
Section titled “Maintenance and upgrades”Open Settings, then General. The Maintenance section has Switch primary and Rolling restart. Selecting either one starts it right away, without a confirmation step. Save or discard your edits first. Both need a healthy database with every instance synchronized. Switch primary needs at least three instances and moves the primary role to a synchronized replica.
Restarting a single instance database interrupts its connections. With replicas, a rolling restart runs without downtime for the primary, but the connections to each restarting instance close, so clients need to reconnect.
To upgrade, pick a newer MySQL version, including 8.0 to 8.4. Turn on
Acknowledge upgrade to MySQL
Monitoring
Section titled “Monitoring”Insights charts running queries, connections, CPU, and memory, and reports connection capacity, buffer pool hit ratio, running queries, and replication lag. CPU and memory include MOCO’s sidecar containers. History needs VictoriaMetrics installed on the cluster.
Troubleshooting
Section titled “Troubleshooting”-
Pods stay
Pending. Check Runtime Status on Overview for scheduling and storage warnings. Require separate nodes needs one eligible node for each instance. Backup jobs also need capacity for their workspace volume. -
Settings cannot be saved or the database cannot be deleted. Edka rejects both while a backup is running. Wait for it to finish.
-
Backups fail after rotating the integration’s access keys. Edka copies the keys into the cluster when you save the database settings. Save Changes is enabled only after an edit, so change a setting and save.
-
External access does not connect. Check the conditions on Overview. The verified command appears once the certificate is issued. Until then the card shows the certificate status. If
TLSReloadHealthyis false, the certificate reload failed. Inspect the<runtime>-tls-reloadCronJob and its Jobs in themysqlnamespace:Terminal window kubectl get cronjob,jobs -n mysqlCertificate issuance needs
cert-managerandedns-webhookin the cluster. -
The requested recovery time is unavailable. Use a completed snapshot, or a time inside its archived interval. Backup objects missing from the bucket must be put back before Edka can use them.
-
A restore failed. Read the status message and the logs of the
moco-restore-<runtime>Job in themysqlnamespace, correct the cause, and start a new restore from the completed snapshot. Edka does not rerun a failed restore on its own. -
Insights says metrics are not available. A database created before the MySQL exporter was added needs one settings save to turn the exporter on.