Oracle’sMySQL Operatorfor Kubernetes is a convenient way to automate MySQL database provisioning within your cluster. One of the operator’s headline features is integrated hands-off backup support that increases your resiliency. Backups copy your database to external storage on a recurring schedule.

This article will walk you through setting up backups to an Amazon S3-compatible object storage service. You’ll also see how to store backups in Oracle Cloud Infrastructure (OCI) storage or local persistent volumes inside your cluster.

Preparing a Database Cluster

Install theMySQL operator in your Kubernetes clusterand create a simple database instance for testing purposes. Copy the YAML below and save it to

kind: Secret

name: mysql-root-user

rootHost: “%”

rootUser: “root”

rootPassword: “P@$$w0rd”


apiVersion: mysql.oracle.com/v2

kind: InnoDBCluster

name: mysql-cluster

secretName: mysql-root-user

instances: 3

tlsUseSelfSigned: true

instances: 1

Use Kubectl to apply the manifest:

Wait a few minutes while the MySQL operator provisions your Pods. Use Kubectl’sget podscommand to check on the progress. You should see four running Pods: one MySQL router instance and three MySQL server replicas.

mysql-cluster-0 2/2 Running 0 2m

mysql-cluster-1 2/2 Running 0 2m

mysql-cluster-2 2/2 Running 0 2m

mysql-cluster-router-6b68f9b5cb-wbqm5 1/1 Running 0 2m

Defining a Backup Schedule

The MySQL operator requires two components to successfully create a backup:

Schedules and profilesare created independentlyof each other. This lets you run multiple backups on different schedules using the same profile.

Each schedule and profile is associated with a specific database cluster. They’re created as nested resources within yourInnoDBClusterobjects. Each database you create with the MySQL operator needs its own backup configuration.

Backup schedules are defined by your database’sspec.backupSchedulesfield. Each item requires aschedulefield that specifies when to run the backup using a cron expression. Here’s an example that starts a backup every hour:

  • name: hourly

enabled: true

schedule: “0 * * * *”

backupProfileName: hourly-backup

ThebackupProfileNamefield references the backup profile to use. You’ll create this in the next step.

Creating Backup Profiles

Profiles are defined in thespec.backupProfilesfield. Each profile should have anameand adumpInstanceproperty that configures the backup operation.

  • name: hourly-backup

storage:

# …

Backup storage is configured on a per-profile basis in thedumpInstance.storagefield. The properties you need to supply depend on the type of storage you’re using.

S3 Storage

The MySQL operator can upload your backups straight to S3-compatible object storage providers. To use this method, you must create a Kubernetes secret that contains anawsCLI config file with your credentials.

name: s3-secret

credentials: |

[default]

aws_access_key_id = YOUR_S3_ACCESS_KEY

aws_secret_access_key = YOUR_S3_SECRET_KEY

Substitute in your own S3 access and secret keys, then use Kubectl to create the secret:

secret/s3-secret created

bucketName: backups

prefix: /mysql

config: s3-secret

profile: default

Applying this manifest will activate hourly database backups to your S3 account.

OCI Storage

The operator supports Oracle Cloud Infrastructure (OCI) object storage as an alternative to S3. It’s configured in a similar way. First create a secret for your OCI credentials:

name: oci-secret

fingerprint: YOUR_OCI_FINGERPRINT

passphrase: YOUR_OCI_PASSPHRASE

privatekey: YOUR_OCI_RSA_PRIVATE_KEY

region: us-ashburn-1

tenancy: YOUR_OCI_TENANCY

user: YOUR_OCI_USER

credentials: oci-secret

Modify thebucketNameandprefixfields to set the upload location in your OCI account. Thecredentialsfield must reference the secret that contains your OCI credentials.

Kubernetes Volume Storage

Local persistent volumes are a third storage option. This is less robust as your backup data will still reside inside your Kubernetes cluster. However it can be useful for one-off backups and testing purposes.

First create a persistent volume and accompanying claim:

kind: PersistentVolume

name: backup-pv

storageClassName: standard

storage: 10Gi

  • ReadWriteOnce

path: /tmp

apiVersion: v1

kind: PersistentVolumeClaim

name: backup-pvc

requests:

This example manifest is not suitable for production use. You should select an appropriatestorage classand volume mounting mode for your Kubernetes distribution.

Next configure your backup profile to use your persistent volume by adding astorage.persistentVolumeClaimfield:

persistentVolumeClaim:

claimName: backup-pvc

The persistent volume claim created earlier is referenced by theclaimNamefield. The MySQL operator will now deposit backup data into the volume.

Setting Backup Options

Backups are created using the MySQL Shell’sdumpInstanceutility. This defaults to exporting a complete dump of your server. The format writes structure and chunked data files for each table. The output is compressed with zstd.

You can pass options through todumpInstancevia thedumpOptionsfield in a MySQL operator backup profile:

chunking: false

compression: gzip

This example disables chunked output, creating one data file per table, and switches to gzip compression instead of zstd. You can find a complete reference for available options inthe MySQL documentation.

Restoring a Backup

The MySQL operator can initialize new database clusters using previously created files fromdumpInstance. This allows you to restore your backups straight into your Kubernetes cluster. It’s useful in recovery situations or when you’re migrating an existing database to Kubernetes.

Database initialization is controlled by thespec.initDBfield on yourInnoDBClusterobjects. Within this stanza, use thedump.storageobject to reference the backup location you used earlier. The format matches the equivalentdumpInstance.storagefield in backup profile objects.

name: mysql-cluster-recovered

prefix: /mysql/mysql20221031220000

Applying this YAML file will create a new database cluster that’s initialized with thedumpInstanceoutput in the specified S3 bucket. Theprefixfield must contain the full path to the dump files within the bucket. Backups created by the operator will automatically be stored in timestamped folders; you’ll need to indicate which one to recover by setting the prefix. If you’re restoring from a persistent volume, use thepathfield instead ofprefix.

Summary

Oracle’s MySQL operator automates MySQL database management within Kubernetes clusters. In this article you’ve learned how to configure the operator’s backup system to store complete database dumps in a persistent volume or object storage bucket.

Using Kubernetes to horizontally scale MySQL adds resiliency, but external backups are still vital in case your cluster’s compromised or data is accidentally deleted. The MySQL operatorcan restore a new database instancefrom your backup if you ever need to, simplifying the post-disaster recovery procedure.