MySQL Hoge beschikbaarheid in productie: InnoDB-cluster, groepsreplicatie en Kubernetes-operators
Een handleiding voor productie-ingenieurs voor InnoDB Cluster, Group Replication, MySQL Operator voor Kubernetes, Percona XtraDB Cluster, multi-cloudstrategieën en bare metal k3s/Rancher-implementaties met Longhorn-opslag
Het draaien van MySQL in productie is voor de meeste technische teams bekend terrein. Het uitvoeren ervan met echte hoge beschikbaarheid (waarbij een defect aan een knooppunt, een netwerkpartitie of het uitvallen van een volledige beschikbaarheidszone niet resulteert in downtime of gegevensverlies) vereist een weloverwogen architectuur. Deze gids doorloopt elke laag van die architectuur: van de replicatieprimitieven binnen MySQL zelf, via de Kubernetes-operators die het levenscyclusbeheer automatiseren, over de beheerde en zelfbeheerde opties van elke grote cloudprovider, en tot aan bare metal k3s-clusters beheerd door Rancher.
Aan het einde van dit artikel beschikt u over een compleet mentaal model voor het kiezen en gebruiken van MySQL HA in productie, samen met concrete configuratievoorbeelden die u kunt aanpassen aan uw eigen omgeving.
MySQL InnoDB-clusterarchitectuur
InnoDB Cluster is Oracle's geïntegreerde oplossing met hoge beschikbaarheid voor MySQL. Het combineert drie componenten: MySQL Group Replication voor gegevenssynchronisatie, MySQL Shell voor clusterbeheer en MySQL Router voor transparante verbindingsroutering en automatische failover. Samen vormen ze een zelfherstellend cluster dat knooppuntstoringen kan tolereren zonder handmatige tussenkomst.
De architectuur is elegant in zijn eenvoud. Applicaties maken verbinding met de MySQL Router, die het bewustzijn van de clustertopologie in stand houdt door het Metagegevensschema van het InnoDB Cluster op te vragen. Wanneer de primaire mislukt, kiest Group Replication een nieuwe primaire uit de resterende secundaire, en stuurt de MySQL Router het schrijfverkeer automatisch om naar de nieuwe primaire, meestal binnen enkele seconden. Leesverkeer kan over alle secundairen worden verdeeld voor horizontale leesschaling.
Basisprincipes van groepsreplicatie
MySQL Groepsreplicatie is de basis van InnoDB Cluster. Het maakt gebruik van een op Paxos gebaseerd consensusprotocol om ervoor te zorgen dat elke transactie die op de primaire knooppunten wordt gepleegd, naar een meerderheid van de knooppunten wordt gerepliceerd voordat deze wordt bevestigd. Dit biedtvirtuele synchrone replicatie- een garantie dat vastgelegde gegevens aanwezig zijn op ten minste een meerderheid van de clusterleden op het moment van vastleggen.
Groepsreplicatie werkt in twee modi:
- Single-Primary Mode— Eén knooppunt accepteert schrijfbewerkingen (de primaire); alle andere zijn alleen-lezen secundaire bestanden. Dit is de aanbevolen en standaardmodus. Het vermijdt schrijfconflicten volledig omdat slechts één knooppunt transacties kan genereren.
- Multi-primaire modus— Alle knooppunten accepteren gelijktijdig schrijfbewerkingen. Dit biedt een hogere schrijfdoorvoer voor werkbelastingen die netjes over verschillende tabellen of sleutelruimten worden verdeeld, maar introduceert de mogelijkheid van certificeringsconflicten wanneer gelijktijdige transacties dezelfde rijen wijzigen. Conflicterende transacties worden teruggedraaid op één knooppunt. Gebruik multi-primary alleen als uw toepassing is ontworpen om certificeringsfouten en logica voor opnieuw proberen af te handelen.
InnoDB-cluster instellen met MySQL Shell
MySQL Shell biedt de AdminAPI, een reeks functies die de gehele levenscyclus van het cluster automatiseren. Hier vindt u de volledige installatievolgorde voor een cluster met 3 knooppunten.
# Step 1: Prepare each MySQL instance (run on all 3 nodes)
# Ensure my.cnf has required settings
[mysqld]
server-id=1 # unique per node: 1, 2, 3
gtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE
binlog_transaction_dependency_tracking=WRITESET
transaction_write_set_extraction=XXHASH64
loose-group_replication_start_on_boot=OFF
plugin_load_add='group_replication.so'
plugin_load_add='mysql_clone.so'
report_host='mysql-node-1' # unique per node
# Step 2: Use MySQL Shell to configure and create the cluster
mysqlsh -- dba configure-instance root@mysql-node-1:3306 --clusterAdmin=gradmin --clusterAdminPassword='SecurePass123!'
mysqlsh -- dba configure-instance root@mysql-node-2:3306 --clusterAdmin=gradmin --clusterAdminPassword='SecurePass123!'
mysqlsh -- dba configure-instance root@mysql-node-3:3306 --clusterAdmin=gradmin --clusterAdminPassword='SecurePass123!'
# Step 3: Connect to the first node and create the cluster
mysqlsh gradmin@mysql-node-1:3306
# Inside MySQL Shell:
var cluster = dba.createCluster('productionCluster', {
memberWeight: 90,
exitStateAction: 'ABORT_SERVER',
consistency: 'BEFORE_ON_PRIMARY_FAILOVER',
expelTimeout: 10
})
# Step 4: Add remaining nodes
cluster.addInstance('gradmin@mysql-node-2:3306', {recoveryMethod: 'clone'})
cluster.addInstance('gradmin@mysql-node-3:3306', {recoveryMethod: 'clone'})
# Step 5: Verify cluster status
cluster.status()
DerecoveryMethod: 'clone'-optie maakt gebruik van de MySQL Clone Plugin om een volledige gegevenskopie uit te voeren van het primaire naar het toetredende lid, wat veel sneller is dan incrementeel herstel uit binaire logs voor grote datasets.
MySQL Routerconfiguratie
MySQL Router wordt opgestart tegen het cluster en genereert automatisch het configuratiebestand.
# Bootstrap MySQL Router against the cluster
mysqlrouter --bootstrap gradmin@mysql-node-1:3306 \
--directory /opt/mysqlrouter \
--conf-use-sockets \
--user=mysqlrouter \
--name='production-router'
# Start MySQL Router
/opt/mysqlrouter/start.sh
# Default ports after bootstrap:
# 6446 — R/W (routes to primary)
# 6447 — R/O (round-robin across secondaries)
# 6448 — R/W (X Protocol)
# 6449 — R/O (X Protocol)
-applicaties maken verbinding met de R/W-poort van de router voor schrijfbewerkingen en de R/O-poort voor leesreplica's. Wanneer de primaire mislukt, detecteert de router de topologiewijziging en wordt de route binnen enkele seconden omgeleid.
MySQL-implementatie voor meerdere regio's
Voor noodherstel en leesbewerkingen met lage latentie in verschillende regio's kan MySQL in meerdere regio's worden ingezet. InnoDB ClusterSet breidt InnoDB Cluster uit om asynchrone replicatie tussen een primair cluster en een of meer replicaclusters in verschillende regio's te ondersteunen.
InnoDB ClusterSet werkt met één primair cluster dat alle schrijfbewerkingen afhandelt, en een of meer replicaclusters die asynchroon wijzigingen ontvangen. In een rampscenario kan een replicacluster worden gepromoveerd naar primair via MySQL Shell.
# Create a ClusterSet from an existing InnoDB Cluster
mysqlsh gradmin@mysql-node-1:3306
var cluster = dba.getCluster()
var cs = cluster.createClusterSet('globalSet')
# Create a replica cluster in eu-west region
cs.createReplicaCluster('gradmin@mysql-eu-node-1:3306', 'euWestCluster', {
recoveryMethod: 'clone'
})
var euCluster = cs.getCluster('euWestCluster')
euCluster.addInstance('gradmin@mysql-eu-node-2:3306', {recoveryMethod: 'clone'})
euCluster.addInstance('gradmin@mysql-eu-node-3:3306', {recoveryMethod: 'clone'})
# Emergency failover (when primary cluster is unreachable)
cs.forcePrimaryCluster('euWestCluster')
MySQL op Kubernetes — Operatorpatroon
Het uitvoeren van MySQL op Kubernetes vereist het oplossen van verschillende uitdagingen die niet van toepassing zijn op stateless workloads: stabiele netwerkidentiteiten, permanente opslag, geordend opstarten en afsluiten, en clusterbewuste gezondheidscontroles. Kubernetes-operators coderen deze domeinspecifieke operationele kennis in een controller die aangepaste bronnen in de gaten houdt en de feitelijke status van MySQL afstemt op de gewenste status die is aangegeven in YAML.
MySQL-operator voor Kubernetes (Oracle)
Oracle's MySQL Operator voor Kubernetes implementeert en beheert InnoDB Cluster-instances native op Kubernetes. Het creëert StatefulSets voor MySQL-serverpods, implementaties voor MySQL-router en verwerkt geautomatiseerde failover-, schalings-, back-up- en configuratiewijzigingen.
# Install the MySQL Operator via Helm
helm repo add mysql-operator https://mysql.github.io/mysql-operator/
helm repo update
helm install mysql-operator mysql-operator/mysql-operator \
--namespace mysql-operator \
--create-namespace \
--set image.pullPolicy=IfNotPresent
Zodra de operator actief is, implementeert u een InnoDB-cluster door een aangepaste bron te maken.
apiVersion: v1
kind: Secret
metadata:
name: mysql-root-credentials
namespace: production
stringData:
rootUser: root
rootHost: '%'
rootPassword: 'ProductionSecurePass123!'
---
apiVersion: mysql.oracle.com/v2
kind: InnoDBCluster
metadata:
name: production-mysql
namespace: production
spec:
secretName: mysql-root-credentials
instances: 3
tlsUseSelfSigned: true
router:
instances: 2
datadirVolumeClaimTemplate:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Gi
storageClassName: gp3-encrypted
mycnf: |
[mysqld]
innodb_buffer_pool_size=4G
innodb_log_file_size=1G
innodb_flush_log_at_trx_commit=1
sync_binlog=1
max_connections=500
innodb_io_capacity=2000
innodb_io_capacity_max=4000
innodb_read_io_threads=8
innodb_write_io_threads=8
performance_schema=ON
slow_query_log=ON
long_query_time=1
podSpec:
containers:
- name: mysql
resources:
requests:
cpu: "2"
memory: 8Gi
limits:
cpu: "4"
memory: 16Gi
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: component
operator: In
values: [mysqld]
topologyKey: topology.kubernetes.io/zone
De pod-anti-affiniteitsregel zorgt ervoor dat MySQL-pods worden verspreid over beschikbaarheidszones, waardoor fouttolerantie op zoneniveau wordt geboden. Met hetmycnf-blok kunt u een op productie afgestemde MySQL-configuratie rechtstreeks via de CR injecteren.
Percona-operator voor MySQL (PXC)
Percona Operator voor MySQL implementeert Percona XtraDB Cluster (PXC), een multi-primaire synchrone replicatieoplossing gebaseerd op Galera. PXC verschilt van InnoDB Cluster doordat elk knooppunt schrijfbewerkingen kan accepteren (echt multi-primair), en replicatie synchroon is op certificeringsniveau met behulp van de wsrep API.
# Install Percona Operator
helm repo add percona https://percona.github.io/percona-helm-charts/
helm repo update
helm install pxc-operator percona/pxc-operator \
--namespace pxc \
--create-namespace
# Percona XtraDB Cluster Custom Resource
apiVersion: pxc.percona.com/v1
kind: PerconaXtraDBCluster
metadata:
name: production-pxc
namespace: pxc
spec:
crVersion: '1.14.0'
secretsName: pxc-secrets
pxc:
size: 3
image: percona/percona-xtradb-cluster:8.0.35
resources:
requests:
memory: 8Gi
cpu: "2"
limits:
memory: 16Gi
cpu: "4"
volumeSpec:
persistentVolumeClaim:
storageClassName: gp3-encrypted
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 200Gi
affinity:
antiAffinityTopologyKey: topology.kubernetes.io/zone
configuration: |
[mysqld]
innodb_buffer_pool_size=4G
innodb_flush_log_at_trx_commit=1
wsrep_provider_options="gcache.size=2G; gcs.fc_limit=256"
wsrep_slave_threads=8
wsrep_certify_nonPK=1
wsrep_trx_fragment_size=10M
max_connections=500
haproxy:
enabled: true
size: 3
image: percona/haproxy:2.8.5
resources:
requests:
memory: 1Gi
cpu: 500m
proxysql:
enabled: false
backup:
image: percona/percona-xtradb-cluster-operator:1.14.0-pxc8.0-backup-pxb8.0.35
storages:
s3-backup:
type: s3
verifyTLS: true
s3:
bucket: production-mysql-backups
region: us-east-1
credentialsSecret: aws-s3-credentials
schedule:
- name: daily-full
schedule: "0 3 * * *"
keep: 7
storageName: s3-backup
- name: hourly-incremental
schedule: "0 * * * *"
keep: 24
storageName: s3-backup
De Percona Operator verzorgt geautomatiseerde back-ups naar S3, point-in-time herstel, rolling upgrades en ProxySQL of HAProxy voor verbindingsroutering. De op Galera gebaseerde replicatie in PXC biedt echte synchrone multi-primaire schrijfbewerkingen: elke vastgelegde transactie bestaat gegarandeerd op alle knooppunten.
Verbindingsroutering: MySQL-router versus ProxySQL
Zowel de MySQL Router als ProxySQL dienen als databaseproxy's, maar ze hebben verschillende sterke punten.
MySQL Routeris speciaal gebouwd voor InnoDB Cluster. Het leest de metagegevens van het cluster, houdt topologiewijzigingen bij en routeert verbindingen naar de juiste primaire of secundaire. De configuratie is minimaal en integreert naadloos met het MySQL-ecosysteem. Het nadeel is de beperkte routering op queryniveau: deze werkt op verbindingsniveau, niet op queryniveau.
ProxySQLis een MySQL-proxy voor algemeen gebruik met geavanceerde functies: lees-/schrijfsplitsing op queryniveau, querycaching, verbindingsmultiplexing, queryherschrijving en geavanceerde routeringsregels. Het blinkt uit in omgevingen waar u een nauwkeurige controle nodig heeft over de manier waarop query's worden gedistribueerd.
# ProxySQL configuration for read/write splitting
# proxysql.cnf
mysql_servers:
(
{ hostgroup_id=10, hostname="mysql-primary", port=3306, max_connections=200, weight=1000 },
{ hostgroup_id=20, hostname="mysql-secondary-1", port=3306, max_connections=200, weight=500 },
{ hostgroup_id=20, hostname="mysql-secondary-2", port=3306, max_connections=200, weight=500 }
)
mysql_query_rules:
(
{ rule_id=1, active=1, match_digest="^SELECT .* FOR UPDATE$", destination_hostgroup=10, apply=1 },
{ rule_id=2, active=1, match_digest="^SELECT", destination_hostgroup=20, apply=1 },
{ rule_id=3, active=1, match_digest=".*", destination_hostgroup=10, apply=1 }
)
mysql_replication_hostgroups:
(
{ writer_hostgroup=10, reader_hostgroup=20, comment="InnoDB Cluster" }
)
In Kubernetes-omgevingen kan ProxySQL worden uitgevoerd als zijspancontainer in uw toepassingspods of als een speciale implementatie. Door het als zijspan uit te voeren worden netwerk-hops geëlimineerd, maar wordt het gebruik van pod-bronnen verhoogd; een specifieke implementatie is eenvoudiger op schaal te beheren.
Vergelijking van-cloudproviders: beheerde versus zelfbeheerde
AWS: RDS Multi-AZ versus Aurora versus zelfbeheerd op EKS
Amazon RDS Multi-AZbiedt automatische failover tussen een primaire en een standby-instantie in verschillende beschikbaarheidszones. De failover duurt doorgaans 60-120 seconden. Het maakt gebruik van synchrone fysieke replicatie naar de standby-omgeving. Leesreplica's kunnen worden toegevoegd voor leesschaling, maar ze gebruiken asynchrone replicatie. RDS verzorgt back-ups, patches en monitoring, maar beperkt uw controle over de MySQL-configuratie en versiekeuze.
Amazon Aurora MySQLis een cloud-native herschrijving van de MySQL-opslagengine. Het scheidt rekenkracht en opslag: de opslaglaag is een gedistribueerd, fouttolerant systeem dat gegevens op zes manieren repliceert over drie AZ's. Aurora biedt een failover van minder dan 10 seconden, maximaal 15 leesreplica's met minimale replicatievertraging en automatische opslagopschaling tot 128 TiB. Aurora Serverless v2 voegt automatische rekenschaling toe voor onvoorspelbare werklasten. De afweging is de kosten (Aurora is 20-40% duurder dan RDS) en verminderde compatibiliteit met bepaalde MySQL-functies.
Zelfbeheerd op EKSgeeft u volledige controle over de MySQL-versie, configuratie en replicatietopologie. Gebruik dit wanneer u specifieke MySQL-functies nodig heeft die niet beschikbaar zijn in beheerde services, wanneer u multi-cloud-portabiliteit nodig heeft of wanneer kostenoptimalisatie op schaal de operationele overhead rechtvaardigt.
# EKS StorageClass for MySQL with gp3 volumes
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gp3-encrypted
provisioner: ebs.csi.aws.com
parameters:
type: gp3
iops: "6000"
throughput: "250"
encrypted: "true"
fsType: ext4
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Retain
allowVolumeExpansion: true
Azure: flexibele server versus zelfbeheerd op AKS
Azure-database voor MySQL flexibele serverbiedt zone-redundante HA met automatische failover, leesreplica's in dezelfde regio en maximaal 16 TiB-opslag. Het ondersteunt configureerbare onderhoudsvensters, de mogelijkheid om instances te stoppen/starten (handig voor kostenbesparingen op het gebied van ontwikkelen/testen) en integratie met Azure Private Link voor netwerkisolatie. De Business Critical-laag biedt de beste prestaties met lokale SSD-opslag.
Zelfbeheerd op AKSmaakt gebruik van Azure Managed Disks (Premium SSD v2 aanbevolen voor databaseworkloads) met de MySQL Operator of Percona Operator. AKS biedt ondersteuning voor beschikbaarheidszones en de Azure CNI voor VNET-integratie op podniveau.
# AKS StorageClass for MySQL
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: premium-ssd-zrs
provisioner: disk.csi.azure.com
parameters:
skuName: Premium_ZRS
cachingMode: None
DiskIOPSReadWrite: "5000"
DiskMBpsReadWrite: "200"
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Retain
allowVolumeExpansion: true
Google Cloud: Cloud SQL versus zelfbeheerd op GKE
Google Cloud SQL voor MySQLbiedt regionale instanties met automatische failover tussen zones, leesreplica's (inclusief interregionaal) en geautomatiseerde back-ups met herstel op een bepaald tijdstip. Cloud SQL biedt het hoogste niveau van beheerd gemak met integratie in het IAM-, VPC- en monitoring-ecosysteem van Google. De Enterprise Plus-laag voegt vrijwel geen downtime-onderhoud en datacache toe voor verbeterde leesprestaties.
Zelfbeheerd op GKEgebruikt Persistent Disk SSD of Hyperdisk voor opslag. GKE Autopilot vereenvoudigt het knooppuntbeheer en kan de MySQL Operator draaien met minimale operationele overhead.
# GKE StorageClass for MySQL
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ssd-regional
provisioner: pd.csi.storage.gke.io
parameters:
type: pd-ssd
replication-type: regional-pd
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Retain
allowVolumeExpansion: true
Blank metaal: k3s + Rancher + Longhorn
Niet elke workload hoort thuis in de publieke cloud. Voor datasoevereiniteit, compliance, kostenoptimalisatie of latentievereisten bieden bare metal Kubernetes-clusters met k3s met Rancher-beheer en Longhorn-opslag een platform van productiekwaliteit voor MySQL HA.
k3s Installatie en configuratie
k3s is een lichtgewicht, gecertificeerde Kubernetes-distributie, ideaal voor rand- en blank metaal. Het bundelt alle componenten op het besturingsvlak in één enkel binair bestand en gebruikt SQLite of ingebedde etcd voor statusopslag.
# Install k3s server (first control-plane node)
curl -sfL https://get.k3s.io | sh -s - server \
--cluster-init \
--tls-san 10.10.0.10 \
--disable traefik \
--disable servicelb \
--write-kubeconfig-mode 644
# Join additional server nodes
curl -sfL https://get.k3s.io | K3S_TOKEN=$(cat /var/lib/rancher/k3s/server/node-token) sh -s - server \
--server https://10.10.0.10:6443 \
--tls-san 10.10.0.10
# Join worker nodes
curl -sfL https://get.k3s.io | K3S_URL=https://10.10.0.10:6443 \
K3S_TOKEN=$(cat /var/lib/rancher/k3s/server/node-token) sh -s -
Longhorn-opslag voor MySQL
Longhorn is een cloud-native gedistribueerd blokopslagsysteem gebouwd voor Kubernetes. Het repliceert gegevens tussen knooppunten, biedt snapshots en back-ups en integreert native met de Kubernetes CSI-driver. Voor MySQL biedt Longhorn de persistente, gerepliceerde opslaglaag die cloudproviders gebruiken met hun beheerde schijfaanbod.
# Install Longhorn
helm repo add longhorn https://charts.longhorn.io
helm repo update
helm install longhorn longhorn/longhorn \
--namespace longhorn-system \
--create-namespace \
--set defaultSettings.defaultReplicaCount=3 \
--set defaultSettings.storageMinimalAvailablePercentage=15 \
--set defaultSettings.guaranteedInstanceManagerCPU=12
# StorageClass for MySQL on Longhorn
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: longhorn-mysql
provisioner: driver.longhorn.io
parameters:
numberOfReplicas: "3"
staleReplicaTimeout: "2880"
dataLocality: best-effort
diskSelector: ssd
fsType: ext4
reclaimPolicy: Retain
volumeBindingMode: Immediate
allowVolumeExpansion: true
MetalLB voor taakverdeling
Op bare metal is er geen cloud-load balancer. MetalLB vult dit gat door externe IP-adressen toe te wijzen aan Kubernetes Services van het type LoadBalancer met behulp van Layer 2 (ARP) of BGP-modus.
# MetalLB IP Address Pool and L2 Advertisement
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: mysql-pool
namespace: metallb-system
spec:
addresses:
- 10.10.0.100-10.10.0.110
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: mysql-l2
namespace: metallb-system
spec:
ipAddressPools:
- mysql-pool
Back-up- en herstelstrategieën
Een cluster met hoge beschikbaarheid beschermt tegen knooppuntfouten. Back-ups beschermen tegen datacorruptie, onbedoelde verwijderingen, applicatiefouten en noodherstelscenario's waarbij het hele cluster verloren gaat. Je hebt beide nodig.
Logische back-ups met mysqldump
mysqldumpproduceert back-ups in SQL-formaat die draagbaar en voor mensen leesbaar zijn. Voor databases van minder dan 50 GB is dit de eenvoudigste optie. Voor grotere datasets maken de vergrendelings- en exporttijd het onpraktisch voor productiegebruik tijdens kantooruren.
# Full logical backup with consistent snapshot
mysqldump --all-databases \
--single-transaction \
--routines \
--triggers \
--events \
--set-gtid-purged=ON \
--result-file=/backups/full-$(date +%Y%m%d-%H%M%S).sql
# Compressed backup piped to S3
mysqldump --all-databases --single-transaction | \
gzip | aws s3 cp - s3://mysql-backups/full-$(date +%Y%m%d).sql.gz
Fysieke back-ups met Percona XtraBackup
Percona XtraBackup voert snelle, niet-blokkerende fysieke back-ups uit van InnoDB-gegevens. Het kopieert InnoDB-gegevensbestanden terwijl het redo-log wordt bijgehouden en past vervolgens het redo-log toe tijdens de voorbereidingsfase om een consistente back-up te maken. Het is dramatisch sneller dan mysqldump voor grote datasets en ondersteunt incrementele back-ups.
# Full physical backup
xtrabackup --backup \
--target-dir=/backups/full \
--user=backup_user \
--password=SecureBackupPass \
--parallel=4 \
--compress \
--compress-threads=4
# Incremental backup based on previous full
xtrabackup --backup \
--target-dir=/backups/incr-$(date +%H) \
--incremental-basedir=/backups/full \
--user=backup_user \
--password=SecureBackupPass
# Prepare (apply redo log) and restore
xtrabackup --prepare --target-dir=/backups/full
xtrabackup --prepare --target-dir=/backups/full \
--incremental-dir=/backups/incr-01
# Copy back to data directory
xtrabackup --copy-back --target-dir=/backups/full --datadir=/var/lib/mysql
chown -R mysql:mysql /var/lib/mysql
Binair logboek (binlog) Point-in-Time herstel
Binaire logs registreren elke gegevensmodificerende transactie. Gecombineerd met een volledige back-up maken ze point-in-time herstel (PITR) mogelijk: herstel naar een specifiek moment, niet alleen naar het tijdstip van de laatste back-up.
# Enable binlog retention (my.cnf)
[mysqld]
log_bin=mysql-bin
binlog_expire_logs_seconds=604800 # 7 days
binlog_format=ROW
gtid_mode=ON
enforce_gtid_consistency=ON
# Restore from backup then replay binlogs to a specific point
mysqlbinlog --start-datetime="2026-04-12 08:00:00" \
--stop-datetime="2026-04-12 09:30:00" \
mysql-bin.000042 mysql-bin.000043 | mysql -u root -p
# Or replay to a specific GTID position
mysqlbinlog --include-gtids="3c2d4f9e-d17e-ec59-9029-6aafa8accef8:1-5000" \
mysql-bin.000042 | mysql -u root -p
Kubernetes Back-up CronJob
In Kubernetes moeten back-ups worden uitgevoerd als CronJobs in plaats van als ad-hocopdrachten. Dit zorgt ervoor dat back-ups worden geautomatiseerd, bewaakt en gewaarschuwd kunnen worden als ze mislukken.
apiVersion: batch/v1
kind: CronJob
metadata:
name: mysql-backup
namespace: production
spec:
schedule: "0 2 * * *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 7
failedJobsHistoryLimit: 3
jobTemplate:
spec:
activeDeadlineSeconds: 7200
template:
spec:
restartPolicy: OnFailure
containers:
- name: backup
image: percona/percona-xtrabackup:8.0.35
command:
- /bin/sh
- -c
- |
BACKUP_DIR=/backups/$(date +%Y%m%d-%H%M%S)
mkdir -p $BACKUP_DIR
xtrabackup --backup \
--host=production-mysql.production.svc \
--user=backup_user \
--password=$BACKUP_PASSWORD \
--target-dir=$BACKUP_DIR \
--parallel=4 \
--compress
xtrabackup --prepare --target-dir=$BACKUP_DIR
# Upload to S3
aws s3 sync $BACKUP_DIR s3://mysql-backups/$(date +%Y%m%d)/
# Cleanup local
rm -rf $BACKUP_DIR
env:
- name: BACKUP_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-backup-credentials
key: password
volumeMounts:
- name: backup-scratch
mountPath: /backups
resources:
requests:
cpu: "1"
memory: 2Gi
limits:
cpu: "2"
memory: 4Gi
volumes:
- name: backup-scratch
emptyDir:
sizeLimit: 100Gi
Monitoring met Percona Monitoring en Beheer (PMM)
Percona Monitoring and Management (PMM) is een open-source monitoringplatform dat speciaal is gebouwd voor observatie van databases. Terwijl Prometheus en Grafana algemene Kubernetes-monitoring bieden, voegt PMM MySQL-specifieke inzichten toe: queryanalyses (QAN) die langzame query's identificeren, dashboards met replicatievertraging, hitratio's van de InnoDB-bufferpool, controverse over tabelvergrendelingen en meer.
# Deploy PMM Server on Kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
name: pmm-server
namespace: monitoring
spec:
replicas: 1
selector:
matchLabels:
app: pmm-server
template:
metadata:
labels:
app: pmm-server
spec:
containers:
- name: pmm-server
image: percona/pmm-server:2
ports:
- containerPort: 443
env:
- name: DISABLE_TELEMETRY
value: "1"
volumeMounts:
- name: pmm-data
mountPath: /srv
resources:
requests:
cpu: "1"
memory: 4Gi
limits:
cpu: "2"
memory: 8Gi
volumes:
- name: pmm-data
persistentVolumeClaim:
claimName: pmm-data-pvc
---
apiVersion: v1
kind: Service
metadata:
name: pmm-server
namespace: monitoring
spec:
type: ClusterIP
selector:
app: pmm-server
ports:
- port: 443
targetPort: 443
# Register MySQL instances with PMM Client (run on each MySQL pod or sidecar)
pmm-admin config --server-url=https://admin:password@pmm-server.monitoring:443 --server-insecure-tls
pmm-admin add mysql \
--username=pmm_monitor \
--password=MonitorPass123 \
--host=127.0.0.1 \
--port=3306 \
--query-source=perfschema \
--service-name=mysql-node-1
Query Analytics vanPMM is bijzonder waardevol in de productie. Het legt elke query vast die op de server wordt uitgevoerd (via prestatieschema of langzaam querylogboek), verzamelt ze op basis van vingerafdruk en toont statistieken zoals gemiddelde latentie, onderzochte rijen versus verzonden rijen en vergrendelingstijd. Op deze manier identificeert u de query's die de prestaties van uw toepassing verslechteren.
Productieconfiguratie Tuning
De standaard MySQL-configuratie is afgestemd op een kleine, algemene werklast. Productieomgevingen met speciale databaseservers hebben aanzienlijk verschillende instellingen nodig. Hier volgen de kritische parameters en hoe u deze kunt dimensioneren.
InnoDB-bufferpool
De InnoDB-bufferpool is waar MySQL tabel- en indexgegevens in het geheugen opslaat. Het is de meest impactvolle configuratieparameter. Voor een speciale MySQL-server stelt u deze in op 70-80% van het beschikbare RAM-geheugen.
[mysqld]
# Memory: 16Gi container limit -> allocate ~12Gi to buffer pool
innodb_buffer_pool_size = 12G
innodb_buffer_pool_instances = 8 # 1 per GB (up to 64)
innodb_buffer_pool_chunk_size = 1536M # pool_size / instances
Logboekconfiguratie opnieuw uitvoeren
Het redo-logboek absorbeert schrijfbewerkingen voordat deze naar gegevensbestanden worden gespoeld. Grotere redo-logboeken verminderen de frequentie van checkpoint-flushes en verbeteren de schrijfdoorvoer. MySQL 8.0.30+ gebruiktinnodb_redo_log_capacityin plaats van de oudereinnodb_log_file_size.
[mysqld]
# MySQL 8.0.30+
innodb_redo_log_capacity = 4G
# MySQL 8.0.29 and earlier
# innodb_log_file_size = 2G
# innodb_log_files_in_group = 2
Duurzaamheid versus prestatie-afweging
De combinatie vaninnodb_flush_log_at_trx_commitensync_binlogbepaalt uw duurzaamheidsgarantie.
- Maximale duurzaamheid(aanbevolen voor productie):
innodb_flush_log_at_trx_commit=1+sync_binlog=1. Elke transactie wordt naar het redo-logboek en de binaire aanmeldingsschijf gewist voordat deze wordt bevestigd. Geen gegevensverlies bij crash. - Gebalanceerde:
innodb_flush_log_at_trx_commit=2+sync_binlog=1. Het Redo-logboek wordt per commit naar de cache van het besturingssysteem geschreven, maar slechts één keer per seconde naar de schijf gespoeld. Bij een besturingssysteemcrash kan maximaal 1 seconde aan transacties verloren gaan (MySQL-crash is nog steeds veilig). - Maximale prestaties(niet aanbevolen voor productie):
innodb_flush_log_at_trx_commit=0+sync_binlog=0. Schrijfbewerkingen worden periodiek in batches uitgevoerd en leeggemaakt. Risico om bij een crash tot 1 seconde aan transacties te verliezen.
[mysqld]
# Production durability settings
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1
innodb_doublewrite = ON
innodb_checksum_algorithm = crc32
I/O-configuratie
[mysqld]
# SSD-optimised I/O settings
innodb_io_capacity = 4000
innodb_io_capacity_max = 8000
innodb_read_io_threads = 8
innodb_write_io_threads = 8
innodb_flush_method = O_DIRECT
innodb_file_per_table = ON
innodb_open_files = 10000
Verbinding en draadbeheer
[mysqld]
max_connections = 500
max_connect_errors = 1000000
thread_cache_size = 64
table_open_cache = 4096
table_open_cache_instances = 16
back_log = 1500
# Thread pool (MySQL Enterprise or Percona)
thread_pool_size = 16
thread_pool_max_threads = 1000
Tijdelijke tabellen en sorteerbuffers
[mysqld]
tmp_table_size = 64M
max_heap_table_size = 64M
sort_buffer_size = 4M
join_buffer_size = 4M
read_rnd_buffer_size = 2M
Volledige productieconfiguratiesjabloon
[mysqld]
# Identity
server-id = 1
report_host = mysql-node-1
# GTID Replication
gtid_mode = ON
enforce_gtid_consistency = ON
binlog_format = ROW
log_bin = mysql-bin
binlog_expire_logs_seconds = 604800
log_slave_updates = ON
relay_log_recovery = ON
# InnoDB Engine
innodb_buffer_pool_size = 12G
innodb_buffer_pool_instances = 8
innodb_redo_log_capacity = 4G
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1
innodb_doublewrite = ON
innodb_flush_method = O_DIRECT
innodb_io_capacity = 4000
innodb_io_capacity_max = 8000
innodb_read_io_threads = 8
innodb_write_io_threads = 8
innodb_file_per_table = ON
innodb_open_files = 10000
innodb_adaptive_hash_index = ON
innodb_change_buffering = all
# Connections
max_connections = 500
max_connect_errors = 1000000
thread_cache_size = 64
table_open_cache = 4096
table_open_cache_instances = 16
back_log = 1500
# Temp / Sort
tmp_table_size = 64M
max_heap_table_size = 64M
sort_buffer_size = 4M
join_buffer_size = 4M
# Monitoring
performance_schema = ON
slow_query_log = ON
long_query_time = 1
log_queries_not_using_indexes = ON
log_throttle_queries_not_using_indexes = 60
# Security
local_infile = OFF
skip_name_resolve = ON
default_authentication_plugin = caching_sha2_password
# Group Replication (InnoDB Cluster)
plugin_load_add = 'group_replication.so'
plugin_load_add = 'mysql_clone.so'
loose-group_replication_start_on_boot = OFF
loose-group_replication_bootstrap_group = OFF
loose-group_replication_recovery_use_ssl = ON
loose-group_replication_ssl_mode = REQUIRED
Failover-testen en chaos-engineering
Een systeem met hoge beschikbaarheid dat nog nooit onder storingsomstandigheden is getest, is niet echt hoog beschikbaar: het is een hypothese. Failovertesten moeten deel uitmaken van uw normale operationele ritme, en niet iets waarvan u ontdekt dat het werkt (of niet werkt) tijdens een feitelijk incident.
Gecontroleerde failovertest
# Test 1: Graceful primary failover (InnoDB Cluster)
mysqlsh gradmin@mysql-node-1:3306
var cluster = dba.getCluster()
cluster.setPrimaryInstance('gradmin@mysql-node-2:3306')
# Verify: cluster.status() should show node-2 as PRIMARY
# Test 2: Simulate primary crash
# On the primary node:
kill -9 $(pidof mysqld)
# Monitor: watch the cluster elect a new primary
# Verify: applications reconnect via MySQL Router within seconds
# Test 3: Network partition simulation
# On the primary node, block Group Replication port:
iptables -A INPUT -p tcp --dport 33061 -j DROP
iptables -A OUTPUT -p tcp --dport 33061 -j DROP
# The isolated node should be expelled; cluster continues with remaining members
# Cleanup:
iptables -D INPUT -p tcp --dport 33061 -j DROP
iptables -D OUTPUT -p tcp --dport 33061 -j DROP
# Test 4: Kubernetes pod deletion
kubectl delete pod mysql-0 -n production --grace-period=0 --force
# The StatefulSet controller recreates the pod
# The operator rejoins it to the cluster
Chaos Engineering met Litmus of Chaos Mesh
Gestructureerde chaos-engineeringtools injecteren systematisch fouten en meten de explosieradius. Chaos Mesh, een CNCF-project, integreert native met Kubernetes.
# Chaos Mesh: Kill a MySQL pod randomly
apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
name: mysql-pod-kill
namespace: production
spec:
action: pod-kill
mode: one
selector:
namespaces:
- production
labelSelectors:
app.kubernetes.io/component: mysqld
scheduler:
cron: "0 */4 * * *"
---
# Chaos Mesh: Network delay between MySQL pods
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
name: mysql-network-delay
namespace: production
spec:
action: delay
mode: one
selector:
namespaces:
- production
labelSelectors:
app.kubernetes.io/component: mysqld
delay:
latency: "200ms"
jitter: "50ms"
duration: "5m"
scheduler:
cron: "30 */6 * * *"
---
# Chaos Mesh: Disk I/O stress
apiVersion: chaos-mesh.org/v1alpha1
kind: IOChaos
metadata:
name: mysql-io-latency
namespace: production
spec:
action: latency
mode: one
selector:
namespaces:
- production
labelSelectors:
app.kubernetes.io/component: mysqld
volumePath: /var/lib/mysql
path: '*'
delay: '100ms'
percent: 50
duration: '5m'
Wat te meten tijdens failovertests
- Recovery Time Objective (RTO)— Hoe lang duurt het van foutdetectie tot serviceherstel? InnoDB Cluster bereikt doorgaans 5-30 seconden. Percona XtraDB Cluster kan sneller zijn omdat er geen verkiezing is (alle knooppunten zijn beschrijfbaar).
- Recovery Point Objective (RPO)— Hoeveel gegevens gaan verloren tijdens een failover? Bij synchrone replicatie (Group Replication in single-primary mode, PXC) is de RPO nul voor vastgelegde transacties. Bij asynchrone replicatie (ClusterSet cross-region) is RPO gelijk aan de replicatievertraging.
- Foutpercentage van applicaties— Hoeveel applicatieverzoeken mislukken tijdens de failover-periode? Hiermee wordt niet alleen de failover van de database getest, maar ook de logica voor het opnieuw proberen van de verbinding van uw applicatie en de herrouteringssnelheid van de MySQL Router.
- Verbindingsafvoertijd— Hoe lang duurt het voordat bestaande verbindingen met de oude primaire aansluiting leeglopen en opnieuw worden aangesloten op de nieuwe primaire?
Runbook: checklist voor fouten bij het primaire knooppunt
- Controleer of het cluster een nieuwe primaire heeft gekozen:
cluster.status() - Bevestig dat de MySQL-router routeert naar de nieuwe primaire: controleer de routerlogboeken en het aantal verbindingen
- Monitor replicatievertraging op resterende secundaire bestanden:
SELECT * FROM performance_schema.replication_group_member_stats - Als het defecte knooppunt kan worden hersteld, sluit u er dan opnieuw aan aan:
cluster.rejoinInstance('gradmin@failed-node:3306') - Als het defecte knooppunt niet kan worden hersteld, verwijdert u het en voegt u een nieuw knooppunt toe:
cluster.removeInstance('gradmin@failed-node:3306', {force: true}) - Controleer de clustergezondheid: alle leden ONLINE, geen replicatiefouten, back-upschema intact
- Update uw capaciteitsplan: als u met twee knooppunten werkt, heeft u geen fouttolerantie totdat de derde is hersteld
Beveiligingsversterking
Production MySQL-implementaties moeten naast basisauthenticatie ook een aantal beveiligingsproblemen aanpakken.
-codering tijdens transport en in rust
[mysqld]
# TLS for client connections
ssl_ca = /etc/mysql/certs/ca.pem
ssl_cert = /etc/mysql/certs/server-cert.pem
ssl_key = /etc/mysql/certs/server-key.pem
require_secure_transport = ON
tls_version = TLSv1.3
# Encryption at rest (InnoDB tablespace encryption)
early-plugin-load = keyring_file.so
keyring_file_data = /var/lib/mysql-keyring/keyring
innodb_undo_log_encrypt = ON
innodb_redo_log_encrypt = ON
default_table_encryption = ON
Kubernetes Geheimen en verzegelde geheimen
# Never store database credentials in plain YAML
# Use Sealed Secrets or an external secret manager
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: mysql-root-credentials
namespace: production
spec:
encryptedData:
rootUser: AgBy3i4OJSWK+PiTy...
rootPassword: AgCtr7pJ2XQWK+Pi...
template:
metadata:
name: mysql-root-credentials
namespace: production
type: Opaque
Auditregistratie
[mysqld]
# MySQL Enterprise Audit (or Percona Audit Log plugin)
plugin-load-add = audit_log.so
audit_log_format = JSON
audit_log_policy = LOGINS
audit_log_rotate_on_size = 100M
audit_log_rotations = 10
-beslissingsmatrix: uw MySQL HA-architectuur kiezen
De juiste architectuur hangt af van uw specifieke eisen. Hier vindt u een beslissingskader.
- Enkele cloud, beheerde voorkeur, MySQL-compatibel— Gebruik Aurora (AWS), Flexibele Server Business Critical (Azure) of Cloud SQL Enterprise Plus (GCP). Deze bieden de laagste operationele overhead.
- Enkele cloud, zelfbeheerd, heeft volledige MySQL-controle nodig— Gebruik MySQL Operator of Percona Operator op EKS/AKS/GKE met cloud-native opslagklassen.
- Multi-cloud of hybride cloud— Gebruik Percona Operator met PXC of MySQL Operator met InnoDB Cluster. De Kubernetes-abstractielaag maakt uw MySQL-implementatie draagbaar in de cloud.
- Blank metaal of rand— Gebruik k3s met Rancher, Longhorn-opslag, MetalLB en MySQL Operator of Percona Operator.
- Maximale schrijfdoorvoer, multi-primary vereist— Gebruik Percona XtraDB Cluster (Galera) met de Percona Operator. Alle knooppunten accepteren schrijfbewerkingen met synchrone certificering.
- Mondiale distributie met noodherstel— Gebruik InnoDB ClusterSet met asynchrone replicatie tussen regio's. Accepteer de RPO-afweging van asynchrone replicatie voor de latentievoordelen van lokale schrijfbewerkingen.
Operationele checklist voor productie MySQL HA
Voordat u uw MySQL HA-implementatie productieklaar verklaart, valideert u elk item op deze checklist.
- Clustergezondheid— Alle leden rapporteren ONLINE-status. Groepsreplicatie vertoont geen fouten.
- Geautomatiseerde back-ups— CronJob of door de operator beheerde back-ups die op schema worden uitgevoerd. Back-ups geverifieerd door periodieke hersteltests.
- Monitoring— PMM of Prometheus/Grafana verzamelt MySQL-statistieken. Waarschuwingen geconfigureerd voor replicatievertraging, verbindingsverzadiging, bufferpoolhitratio van minder dan 99% en schijfruimte.
- Failover getest— Primaire failover getest in de afgelopen 30 dagen. RTO en RPO gemeten en binnen SLA-doelstellingen.
- Verbindingsroutering— MySQL Router of ProxySQL gecontroleerd op gezondheid en taakverdeling. Applicatieverbindingsreeksen verwijzen naar de router, niet naar individuele MySQL-instanties.
- Beveiliging— TLS vereist voor alle verbindingen. Versleuteling in rust ingeschakeld. Inloggegevens opgeslagen in een geheime manager. Auditregistratie actief. Databasegebruikers met de minste bevoegdheden voor elke toepassing.
- Resourcelimieten— Kubernetes-resourceverzoeken en -limieten zijn op de juiste manier ingesteld. PodDisruptionBudgets aanwezig. Pod-anti-affiniteit verspreidt MySQL-pods over zones.
- Capaciteitsplan— Opslaggebruik bewaakt met waarschuwingen op 70% en 85%. Volume-uitbreiding getest. Verticale en horizontale schaalprocedures gedocumenteerd.
- Runbooks— Gedocumenteerde procedures voor primaire failover, knooppuntvervanging, back-upherstel, versie-upgrade en nood-alleen-lezen-modus.
- Chaostesten— Regelmatige chaos-experimenten gepland om aannames over veerkracht te valideren.
Conclusie
MySQL hoge beschikbaarheid in productie is geen enkele technologiekeuze; het is een systeem van in elkaar grijpende beslissingen die de replicatielaag, het orkestratieplatform, het opslagsubsysteem, de monitoringstack en de operationele processen eromheen omvatten. InnoDB Cluster met Group Replication biedt de fundamentele HA-primitief. Kubernetes-operators van Oracle en Percona automatiseren het levenscyclusbeheer dat anders veel engineeringtijd zou vergen. Cloudbeheerde services ruilen controle in voor het gemak. Bare metal-implementaties met k3s, Rancher en Longhorn bewijzen dat u geen cloudprovider nodig heeft om MySQL HA op productieniveau te draaien.
Het meest kritische inzicht is dat hoge beschikbaarheid een eigenschap is van het hele systeem, en niet alleen van de database. Het omvat de manier waarop uw applicatie verbindingsfouten en nieuwe pogingen afhandelt, hoe uw proxylaag mislukte knooppunten detecteert en eromheen routeert, hoe uw monitoring waarschuwingen geeft voordat gebruikers het merken, hoe uw back-upstrategie herstel mogelijk maakt van scenario's die HA alleen niet aankan, en hoe uw team failover-procedures toepast zodat ze netjes worden uitgevoerd onder de stress van een echt incident.
Bouw het doelbewust, test het regelmatig en behandel uw runbooks als levende documenten die evolueren met elk incident en elk chaos-experiment. Dat is hoe MySQL zijn plaats verdient als betrouwbaar, zeer beschikbaar dataplatform in de productie.