Skip to content
SYS.DOCS // DOCS

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.

  • For 3 or 5 instances 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.
  1. Open the cluster and select Databases under Workloads. Select Create Database, then pick MySQL.
  2. On General, enter the Database name and pick the MySQL version. Set Instance count to 1 instance, or to 3 instances or 5 instances for semi-synchronous replication with automatic failover. Set Storage size (Gi) and Storage class. The name and the storage class are fixed after creation.
  3. On Resources, set CPU and memory, and the Replica placement.
  4. On Placement, pick a Node pool or keep Default cluster placement. Keep Tolerate node pool taints on when the pool is tainted.
  5. On Configuration, review the server settings.
  6. On Users, set the application database and user, and add more users and databases.
  7. On Access, keep External Access off for applications that connect from inside the cluster, or turn it on and pick a network.
  8. On Backup, select the backup storage and schedule, or restore an existing backup.
  9. 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.

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.

ObjectName
Write Servicemoco-<runtime>-primary.mysql.svc.cluster.local:3306
Read Servicemoco-<runtime>-replica.mysql.svc.cluster.local:3306
Podsmoco-<runtime>-0, moco-<runtime>-1, and so on

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.

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-writable account.
  • Add User creates an account as '<name>'@'%' with a grant for each database you select. Read grants SELECT and SHOW VIEW. Read and write adds INSERT, UPDATE, DELETE, and EXECUTE. 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.

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.

The Configuration tab sets MySQL server variables. An empty field uses the operator default. Saving a change restarts the instances one at a time.

FieldRangeDefault on create
Maximum connections10 to 10000150
Maximum packet size (Mi)1 to 102464
InnoDB buffer pool (Mi)16 to 196608empty
Idle connection timeout (seconds)1 to 604800empty
Slow query threshold (seconds)0 to 36002

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.

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.

NetworkReachability
LoadBalancerA public IP, reachable from the internet.
Private LoadBalancerAn IP in the cluster’s private network, reached through private routing.
TailscaleAn 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:

Terminal window
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.

  1. Open Settings, then Backup, and turn on the Backups switch. The same tab is in the create form.
  2. Select Backup storage.
  3. Set Interval (hours) from 1 to 168. The default is 24.
  4. Set Retention (days) from 1 to 365. The default is 7.
  5. Review Workspace (Gi), the temporary volume for dumps and binary logs. It defaults to twice the data volume size.
  6. 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.

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.

  1. On Backups, select Restore beside a completed snapshot.
  2. Enter the New installation name, which defaults to <source>-restored.
  3. 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).
  4. Select a Storage class and a Storage size (Gi) at least as large as the source volume.
  5. 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.

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 , then select Apply Upgrade. Save the upgrade on its own, apart from configuration or credential changes. Replicas upgrade first. Downgrades are rejected. To return to an older version, restore a backup taken on that version into a new database. Take and verify a backup before upgrading.

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.

  • 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 TLSReloadHealthy is false, the certificate reload failed. Inspect the <runtime>-tls-reload CronJob and its Jobs in the mysql namespace:

    Terminal window
    kubectl get cronjob,jobs -n mysql

    Certificate issuance needs cert-manager and edns-webhook in 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 the mysql namespace, 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.