MySQL support · 24×7 enterprise MySQL DBA engineering for 8.4 LTS, 9.7 LTS and every managed MySQL cloud
MySQL Support: 24×7 Enterprise MySQL DBA Engineering
MinervaDB provides enterprise MySQL support for organisations that cannot afford guesswork in their transaction tier. Principal engineers own your incidents, tune InnoDB and replication from evidence, design and rehearse failover, prove backups by restoring them, and plan upgrades across MySQL 8.4 LTS, 9.7 LTS and the new calendar-versioned releases, on bare metal, Kubernetes, Amazon RDS and Aurora, Google Cloud SQL, Azure Database for MySQL and HeatWave.
What MySQL support covers
Full-stack MySQL support, from InnoDB to the cloud console
Our MySQL support engagements cover the whole MySQL lifecycle. Every item below is delivered by engineers who read source-level behaviour, not by a ticket queue that forwards your problem.
24×7 incident response
Severity 1 answered in 15 minutes by a named engineer on your bridge: outages, replication breaks, corruption, runaway locking and failed failovers.
Performance engineering
performance_schema digests, EXPLAIN ANALYZE, InnoDB buffer and redo sizing, index design and query rewrites, verified with before-and-after numbers.
High availability
GTID replication, semi-sync, Group Replication and InnoDB Cluster, Galera and Percona XtraDB Cluster, ProxySQL and MySQL Router, with rehearsed failover.
Backup and recovery
XtraBackup, MySQL Shell dump and load, binlog point-in-time recovery and cloud snapshots, proven by scheduled restore drills with measured RTO.
Upgrades and migrations
8.0 to 8.4 LTS and on to 9.7 LTS, MariaDB and Percona Server moves, on-premises to cloud and back, with rollback paths at every step.
Security and audit
Roles, least privilege, TLS everywhere, caching_sha2_password migration, audit logging and evidence for SOC 2, PCI DSS, HIPAA, GDPR and DPDP.
01 · Version landscape
MySQL support in 2026: 8.0 is gone, the LTS lines decide the plan
Oracle shipped MySQL 8.0.46 in April 2026 as the final 8.0 release and moved to calendar versioning: LTS lines for stability and quarterly Innovation releases such as 26.7.0. Our MySQL support starts by placing every instance on this map.
Figure 1. MySQL release lines in 2026 and the MySQL support action we recommend for each. Source: Oracle MySQL release announcements.
We still run MySQL 8.0. What is the safest path?
Upgrade to MySQL 8.4 LTS first, not straight to an Innovation release. 8.4 changes several defaults, disables mysql_native_password by default and removes long-deprecated features, so we run the MySQL Shell upgrade checker, migrate authentication, test on a replica, and promote with a rollback replica kept on the old version.
Should we move to MySQL 9.7 LTS or 26.7?
9.7 LTS is the next long-term landing zone and brings the Hypergraph optimizer and Group Replication observability features to Community. 26.7 is an Innovation release with quarterly successors; we use it where a specific feature, such as the Change Stream Applier for parallel replication, justifies faster upgrade cycles.
Do you support Percona Server and MariaDB too?
Yes. MySQL support at MinervaDB covers Oracle MySQL Community and Enterprise, Percona Server for MySQL and Percona XtraDB Cluster, and MariaDB, including migrations between them where GTID formats and features differ.
Upgrade readiness check, run before any 8.0 to 8.4 LTS move
# MySQL support, upgrade readiness: run BEFORE any 8.0 -> 8.4 LTS move.
# MySQL Shell's upgrade checker inspects schemas, users, plugins and settings
# against the target release. Credentials come from the environment or a login path.
mysqlsh -- util check-for-server-upgrade "${MYSQL_USER}@${MYSQL_HOST}:3306" \
--target-version=8.4.11 \
--output-format=JSON > upgrade-check-$(date +%F).json
-- Accounts still on mysql_native_password: the plugin is disabled by default
-- in MySQL 8.4, so these logins fail after the upgrade unless migrated first.
SELECT user, host, plugin
FROM mysql.user
WHERE plugin = 'mysql_native_password'
ORDER BY user, host;
-- Migrate one account at a time (application credentials from your vault).
ALTER USER 'app_rw'@'10.%' IDENTIFIED WITH caching_sha2_password BY '${APP_RW_PASSWORD}';02 · InnoDB internals
How MySQL commits, and why it decides your latency
Good MySQL DBA support starts with the commit path. A transaction is prepared in the InnoDB redo log, written and synced to the binary log by a group-commit leader, then committed in binlog order. Every durability setting maps to one fsync in that pipeline.
Figure 2. The two-phase commit path. Crash recovery uses the binary log to decide which prepared transactions commit.
Because group commit batches many sessions into one binlog fsync, sync_binlog = 1 and innodb_flush_log_at_trx_commit = 1 usually cost far less than teams fear, and relaxing them trades a small latency gain for data loss on a crash and broken replicas. We relax durability only when the business has accepted the RPO in writing.
The other decisive settings are memory and I/O: a buffer pool sized to the working set, a redo log large enough that checkpoints never stall writes, and I/O capacity matched to what the storage sustains rather than its burst rating. MySQL 8.4 changed several InnoDB defaults, including innodb_io_capacity, the change buffer and the adaptive hash index, so an upgrade is also a configuration review.
Is the InnoDB adaptive hash index on in MySQL 8.4?
No. It is off by default in 8.4. We re-enable it only where workload evidence, such as repeated equality lookups on a hot index with low contention, shows a benefit, because it can become a contention point under concurrent writes.
InnoDB baseline for MySQL 8.4 LTS, with default, reason and reload behaviour per line
# /etc/my.cnf.d/minervadb-innodb.cnf -- MySQL 8.4 LTS, dedicated 64 GB host (illustrative) # Format per line: parameter = proposed # 8.4 default -> why ; dynamic or restart [mysqld] innodb_buffer_pool_size = 44G # 128M -> ~70% of RAM for the working set ; dynamic (resizes in chunks) innodb_redo_log_capacity = 8G # 100M -> absorb write bursts without checkpoint stalls ; dynamic innodb_flush_log_at_trx_commit = 1 # 1 -> keep: full durability, group commit amortises fsync ; dynamic sync_binlog = 1 # 1 -> keep: binlog survives crash, required for safe PITR/replicas ; dynamic innodb_io_capacity = 4000 # 10000 -> match the volume's sustained IOPS, not its burst ; dynamic innodb_io_capacity_max = 8000 # 2x io_capacity -> ceiling for flushing under pressure ; dynamic innodb_flush_method = O_DIRECT # avoid double caching in the OS page cache ; restart binlog_format = ROW # deterministic replication and CDC ; dynamic (new sessions) gtid_mode = ON # positionless failover and PITR ; staged change via OFF_PERMISSIVE/ON_PERMISSIVE enforce_gtid_consistency = ON # prerequisite for gtid_mode=ON ; dynamic binlog_expire_logs_seconds = 604800 # 30 days -> 7 days, sized to the backup cadence ; dynamic max_connections = 800 # 151 -> sized to pooler output, not to app instances ; dynamic performance_schema = ON # evidence source for every diagnosis ; restart
03 · Performance engineering
MySQL support that starts from evidence, not from opinions
Every performance engagement in our MySQL support practice begins with the same question: which statement shapes own the database time, and why? performance_schema answers the first half; EXPLAIN ANALYZE and InnoDB metrics answer the second.
Statement digests, plan proof and unused indexes
-- MySQL support diagnostics, step 1: which statement shapes own the database time?
SELECT LEFT(digest_text, 90) AS statement_shape,
count_star AS calls,
ROUND(sum_timer_wait / 1e12, 1) AS total_s, -- picoseconds -> seconds
ROUND(avg_timer_wait / 1e9, 2) AS avg_ms,
ROUND(sum_rows_examined / NULLIF(sum_rows_sent, 0), 1) AS examined_per_sent,
sum_no_index_used AS no_index_used,
sum_created_tmp_disk_tables AS tmp_disk_tables
FROM performance_schema.events_statements_summary_by_digest
WHERE schema_name NOT IN ('mysql', 'sys', 'performance_schema')
ORDER BY sum_timer_wait DESC
LIMIT 15;
-- Step 2: prove the cause on one execution (MySQL 8.0.18+ EXPLAIN ANALYZE).
EXPLAIN ANALYZE
SELECT o.order_id, o.amount
FROM orders AS o
WHERE o.customer_id = 48213
AND o.created_at >= NOW() - INTERVAL 30 DAY;
-- Step 3: indexes that cost writes but serve no reads since the last restart.
SELECT object_schema, object_name, index_name
FROM sys.schema_unused_indexes
WHERE object_schema NOT IN ('mysql', 'sys');Lock waits and purge lag during an incident
-- MySQL support during a blocking incident: who waits on whom (MySQL 8.0+).
SELECT waiting_pid,
LEFT(waiting_query, 60) AS waiting_query,
blocking_pid,
LEFT(blocking_query, 60) AS blocking_query,
wait_age_secs,
locked_table,
locked_index
FROM sys.innodb_lock_waits
ORDER BY wait_age_secs DESC;
-- Undo history that purge cannot remove: a long-open transaction is pinning it.
SELECT name, count AS history_list_length
FROM information_schema.innodb_metrics
WHERE name = 'trx_rseg_history_len';
SELECT trx_id, trx_mysql_thread_id AS pid,
TIMESTAMPDIFF(SECOND, trx_started, NOW()) AS open_secs,
trx_rows_modified, LEFT(trx_query, 60) AS current_query
FROM information_schema.innodb_trx
ORDER BY trx_started
LIMIT 10;
-- Killing a session (KILL <pid>) rolls its work back: confirm with the owner first.What does examined_per_sent tell you?
How many rows MySQL read for every row it returned. Values in the thousands mean a missing or unusable index, or a predicate the optimizer cannot push into the index, and they are the first thing we fix.
Why does history list length matter?
It counts undo records purge has not yet removed. A long-open transaction pins them, so reads walk longer version chains and the undo tablespace grows. We find and close the transaction before it becomes an outage.
Do you change configuration on production during tuning?
Only dynamic parameters, one at a time, with the before-and-after metric recorded and a rollback value prepared. Restart-only changes go through a maintenance window on a replica first.
04 · Replication and high availability
MySQL DBA support for replication, failover and routing
Replication lag is a design problem, and failover is only real once it has been rehearsed. We choose the topology from the RPO you can accept, put routing in front of it, and drill the failover until the time is a measured number.
Figure 3. Four MySQL high-availability topologies and their trade-offs.
Replication health and lag per applier worker, plus Group Replication membership
-- MySQL support for replication: applier health and real lag per worker (8.0+).
SELECT c.channel_name,
c.service_state AS io_state,
a.worker_id,
a.service_state AS sql_state,
TIMESTAMPDIFF(MICROSECOND,
a.last_applied_transaction_original_commit_timestamp,
a.last_applied_transaction_end_apply_timestamp) / 1e6 AS last_txn_lag_s,
a.last_error_number,
LEFT(a.last_error_message, 80) AS last_error
FROM performance_schema.replication_connection_status AS c
JOIN performance_schema.replication_applier_status_by_worker AS a
ON a.channel_name = c.channel_name
ORDER BY last_txn_lag_s DESC;
-- Group Replication / InnoDB Cluster: membership, role and state of every node.
SELECT member_host, member_port, member_role, member_state, member_version
FROM performance_schema.replication_group_members;ProxySQL read/write split that follows read_only after failover
-- MySQL support for routing: ProxySQL 2.x read/write split (admin interface, port 6032). -- Hostgroup 10 = writer, 20 = readers. Monitor credentials come from your secret store. INSERT INTO mysql_servers (hostgroup_id, hostname, port, max_replication_lag) VALUES (10, 'db-primary.internal', 3306, 0), (20, 'db-replica-1.internal', 3306, 5), -- shunned if lag > 5 s (20, 'db-replica-2.internal', 3306, 5); INSERT INTO mysql_replication_hostgroups (writer_hostgroup, reader_hostgroup, check_type) VALUES (10, 20, 'read_only'); -- follows read_only after a failover INSERT INTO mysql_query_rules (rule_id, active, match_digest, destination_hostgroup, apply) VALUES (100, 1, '^SELECT .* FOR UPDATE', 10, 1), -- locking reads stay on the writer (200, 1, '^SELECT ', 20, 1); -- other reads go to replicas LOAD MYSQL SERVERS TO RUNTIME; SAVE MYSQL SERVERS TO DISK; LOAD MYSQL QUERY RULES TO RUNTIME; SAVE MYSQL QUERY RULES TO DISK;
How do you reduce replication lag?
By fixing its cause: multi-threaded apply with the right dependency tracking, row-based binlogs, primary keys on every table, and splitting giant transactions. MySQL 26.7 adds the Change Stream Applier for up to 1,024 workers per channel, which we evaluate per workload.
Group Replication or Galera?
Group Replication and InnoDB Cluster are the native Oracle path with MySQL Router; Galera via Percona XtraDB Cluster or MariaDB suits teams already invested in it. Both need careful handling of large transactions and write conflicts, which we design for up front.
How often do you test failover?
At least quarterly in production-like environments, and after every topology change. Each drill records time to new primary, client errors and any data divergence.
05 · Backup and recovery
A MySQL backup counts only after it has been restored
Our MySQL support treats recovery as a measured capability. We combine physical backups with binary-log point-in-time recovery and run restore drills on separate hosts, so RPO and RTO are numbers from the last drill, not from a contract.
Restore drill: XtraBackup plus binlog PITR, with guards against touching production
#!/usr/bin/env bash
# MySQL support, recovery drill: physical backup + binlog point-in-time recovery.
# Restores to a SEPARATE host/datadir. Never run against the production datadir.
set -euo pipefail
: "${MYSQL_USER:?}" "${MYSQL_PWD:?}" "${BACKUP_DIR:?}" "${RESTORE_DATADIR:?}" "${STOP_AT:?e.g. 2026-10-04 09:14:00}"
# 1. Hot physical backup (Percona XtraBackup 8.4 for MySQL 8.4).
xtrabackup --backup --user="${MYSQL_USER}" --target-dir="${BACKUP_DIR}/base"
xtrabackup --prepare --target-dir="${BACKUP_DIR}/base"
BINLOG_POS=$(cat "${BACKUP_DIR}/base/xtrabackup_binlog_info")
echo "Backup consistent at: ${BINLOG_POS}"
# 2. Guard: the restore target must be empty and must not be the live datadir.
LIVE=$(mysql -N -e "SELECT @@datadir")
[[ "$(realpath "${RESTORE_DATADIR}")/" != "$(realpath "${LIVE}")/" ]] || { echo "Refusing: live datadir."; exit 1; }
[[ -z "$(ls -A "${RESTORE_DATADIR}" 2>/dev/null)" ]] || { echo "Refusing: ${RESTORE_DATADIR} not empty."; exit 1; }
read -r -p "Type 'RESTORE TO ${RESTORE_DATADIR}' to continue: " A
[[ "${A}" == "RESTORE TO ${RESTORE_DATADIR}" ]] || { echo "Aborted."; exit 1; }
# 3. Copy back, start the drill instance, then replay binlogs up to the incident.
xtrabackup --copy-back --target-dir="${BACKUP_DIR}/base" --datadir="${RESTORE_DATADIR}"
chown -R mysql:mysql "${RESTORE_DATADIR}"
# (start mysqld on the drill host with --datadir=${RESTORE_DATADIR} --skip-replica-start)
mysqlbinlog --skip-gtids=false --stop-datetime="${STOP_AT}" "${BACKUP_DIR}"/binlogs/binlog.0* \
| mysql --host=drill-host --user="${MYSQL_USER}"
# 4. Validate: row counts and latest business timestamp, then record the elapsed time as RTO.
mysql --host=drill-host -e "SELECT COUNT(*), MAX(created_at) FROM shop.orders;"| Method | Best for | Restore speed | PITR |
|---|---|---|---|
| Percona XtraBackup | large self-managed datasets | fast (physical copy) | with binlogs |
| MySQL Shell dump/load | logical moves, cloud migrations | parallel, medium | with binlogs |
| Storage or cloud snapshots | RDS, Aurora, Cloud SQL, Azure | fast, lazily loaded | provider PITR window |
| mysqldump | small schemas, exports | slow (single thread) | with binlogs |
How long should we keep binary logs?
At least one full backup interval plus a margin, so any moment since the oldest retained backup can be reached. We size binlog_expire_logs_seconds and off-host binlog streaming together with the backup schedule.
What do you check after a restore?
Row counts and the latest business timestamp on key tables, checksum comparisons for critical data, application smoke tests, and the elapsed time, which becomes the measured RTO.
06 · Security and compliance
MySQL security engineered for audit, not for appearance
Enterprise MySQL support includes the controls auditors ask about and the evidence that proves them: roles and least privilege, encryption in transit and at rest, strong authentication and audit trails.
Roles, TLS-only service accounts and a privilege audit
-- MySQL support, security baseline (MySQL 8.0+ roles; 8.4 defaults to caching_sha2_password).
CREATE ROLE IF NOT EXISTS 'app_read', 'app_write', 'ops_dba';
GRANT SELECT ON shop.* TO 'app_read';
GRANT SELECT, INSERT, UPDATE, DELETE ON shop.* TO 'app_write';
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'ops_dba'; -- no SUPER for daily work
CREATE USER 'svc_orders'@'10.20.%'
IDENTIFIED WITH caching_sha2_password BY '${SVC_ORDERS_PASSWORD}'
REQUIRE SSL -- refuse unencrypted connections
PASSWORD EXPIRE INTERVAL 90 DAY
FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LOCK_TIME 1;
GRANT 'app_write' TO 'svc_orders'@'10.20.%';
SET DEFAULT ROLE 'app_write' TO 'svc_orders'@'10.20.%';
-- Audit: accounts that can do everything, and accounts allowed from anywhere.
SELECT user, host FROM mysql.user WHERE Super_priv = 'Y' OR host = '%';Do you handle encryption at rest?
Yes: InnoDB tablespace, redo, undo and binlog encryption with a keyring component or a KMS, plus key rotation procedures and recovery testing so encrypted backups remain restorable.
Which audit options do you deploy?
MySQL Enterprise Audit where licensed, Percona Audit Log Plugin on Percona Server, and the managed-service audit features on RDS, Aurora, Cloud SQL and Azure, routed to your SIEM with retention matched to your compliance regime.
Can you help with compliance evidence?
We map database controls to SOC 2, PCI DSS, HIPAA, GDPR and India's DPDP Act requirements and produce the configuration evidence, access reviews and audit samples assessors request.
07 · Managed MySQL clouds
MySQL support on RDS, Aurora, Cloud SQL, Azure and HeatWave
Managed MySQL removes host administration, not engineering. Each service diverges from community MySQL in privileges, parameters and upgrade policy, and our MySQL support covers those differences explicitly.
| Service | What differs from self-managed MySQL | What we engineer |
|---|---|---|
| Amazon RDS for MySQL | no SUPER, parameter groups, provider-scheduled maintenance, Extended Support charges past end of standard support | parameter baselines, Multi-AZ failover tests, version calendar, RDS Proxy |
| Amazon Aurora MySQL | shared distributed storage, Aurora-specific versions and replica lag model | writer/reader endpoints, Global Database DR, I/O cost review |
| Google Cloud SQL for MySQL | managed flags, maintenance windows, HA via regional instances | flags tuning, read replicas, cross-region DR, Query Insights analysis |
| Azure Database for MySQL Flexible Server | server parameters, zone-redundant HA, managed backups | HA configuration, replica design, performance tuning, backup drills |
| HeatWave MySQL | Oracle-managed version tracks, in-memory analytics accelerator | workload fit assessment, version planning, exit options |
08 · 24×7 MySQL support operations
How a MySQL support incident runs, and what we commit to
Our 24×7 MySQL DBA support is run by principal engineers with access to your runbooks, monitoring and change history before the first incident. Response targets are commitments for an engineer to be actively working the problem.
Figure 4. The MySQL support incident flow and response targets: S1 15 minutes, S2 12 hours, S3 24 hours, S4 48 hours.
Onboarding
Access, topology map, baselines from performance_schema, backup and failover review, and a ranked risk register in the first weeks.
Proactive reviews
Monthly health checks: growth, slow-query trends, replication, backups, security drift and the version calendar.
Change engineering
Online schema changes with gh-ost or pt-online-schema-change, upgrades and configuration changes, each with a rollback path.
Knowledge transfer
Runbooks, RCAs and alert definitions stay with your team, so support builds capability instead of dependency.
FAQ
MySQL support questions we are asked most
Short answers to the questions CIOs, CTOs and DBA leads ask before choosing a MySQL support partner.
What is included in MinervaDB MySQL support?
24×7 incident response, performance engineering, replication and high-availability design, backup and recovery with restore drills, upgrades and migrations, security hardening and monthly proactive reviews, across self-managed and managed MySQL.
How fast do you respond to a MySQL outage?
Severity 1 incidents get a named engineer working the problem within 15 minutes, 24×7×365. Severity 2 is 12 hours, Severity 3 is 24 hours and Severity 4 is 48 hours.
Is MySQL support different from remote DBA?
Support is centred on incidents and expert escalation; remote DBA adds routine operations such as patching, user management and capacity work. Many clients combine both; see our MySQL remote DBA service.
Do you support MySQL on Kubernetes?
Yes, including the Oracle MySQL Operator, Percona Operator for MySQL and Percona XtraDB Cluster operators, with attention to storage classes, pod disruption budgets and backup integration.
Can you take over an estate in the middle of an incident?
Yes. Emergency engagements start with read-only access and an evidence capture, then mitigation; formal onboarding follows once service is stable.
Are you tied to Oracle or any vendor?
No. MinervaDB is vendor-neutral and sells no licences, so recommendations, including when to stay on MySQL and when another engine fits better, are based only on your workload.
Guidance on this page is general and version-pinned to the releases named. Test every configuration change, upgrade, failover and restore step in a non-production environment first, verify backups by restoring them, and maintain a robust disaster-recovery posture. Related services: MySQL consulting · MySQL optimization · MySQL upgrades and migration · 24×7 emergency DBA coverage · MySQL 8.4 Reference Manual
Need MySQL support you can call at 3 a.m.?
Talk to a MySQL principal engineer about your estate, your SLAs and your next upgrade. contact@minervadb.com · +1 (844) 588-7287.