Chapter 22 · Production Capstone: Design, Secure, Scale, Tune, and Recover MySQL

Execute Failure/Recovery Drills and Defend the Final MySQL Production Design

Inject safe failures, measure detection and recovery, verify data correctness, and defend the final production design with explicit tradeoffs, unmet SLOs, rollback boundaries, and next improvements.

Advanced capstone180–300 minServiceHub production capstoneMySQL Community Server 8.4.10 LTSInnoDBsingle local server mandatoryMySQL Shell 8.4.10 + Router 8.4.10 optional HA extension3-member single-primary InnoDB Cluster production targetLast reviewed: August 2026

Learning outcomes

The capstone ends by deliberately breaking the disposable system. A design that works only in the happy path is not production-ready. Each drill has four measurements: detection, response, recovery time, and data correctness. The final deliverable is a design defense that states what met its SLO, what did not, what complexity the architecture introduces, and what would be improved next.

01

Inject safe blocked-connection, deadlock, load-spike, accidental-data-change, and optional node-loss failures in disposable infrastructure.

02

Capture MySQL/Performance Schema/log evidence that distinguishes the symptom from its mechanism.

03

Measure recovery time and verify business invariants instead of calling a service healthy when a process merely restarted.

04

Identify ambiguous transaction outcomes and explain where idempotency/reconciliation prevents duplicate business actions.

05

Defend the final MySQL design with explicit cost, complexity, unmet SLOs, upgrade/recovery paths, and revisit triggers.

Use one drill record for every failure

text · failure-drill evidence form
Drill ID / timestamp: _____________________________Failure injected: _________________________________Expected detector: ________________________________Detected at: ______________________________________Operator/application action: ______________________Recovery declared at: _____________________________Measured detection time: __________________________Measured recovery time: ___________________________RPO / lost-or-ambiguous operations: _______________Business invariants checked: ______________________MySQL/Router/log evidence: ________________________SLO met? yes/no/unknown: __________________________What made recovery harder: ________________________Follow-up owner and change: _______________________

Do not backfill times from memory after the drill. Timestamp each phase as it happens. Unknown is an acceptable result; invented precision is not.

Drill 1: blocked connection / secure transport failure

The easiest failure to debug badly is a connection failure. Operators often restart MySQL before distinguishing wrong host, TLS verification, account host matching, lockout, firewall, Router endpoint, or server availability. The capstone starts with evidence.

text · negative connection tests — disposable account only
# Expected failure because the account requires TLS:mysql -h 127.0.0.1 -P 3306 -u sh_cap_app -p --ssl-mode=DISABLED# Positive path; for production use VERIFY_CA / VERIFY_IDENTITY with trusted CA:mysql -h 127.0.0.1 -P 3306 -u sh_cap_app -p --ssl-mode=REQUIRED
sql · server-side evidence after successful secure connection
SELECT USER(),CURRENT_USER(),CURRENT_ROLE(),CONNECTION_ID();SHOW SESSION STATUS LIKE 'Ssl_cipher';SHOW GRANTS FOR CURRENT_USER;SELECT PROCESSLIST_ID,PROCESSLIST_USER,PROCESSLIST_HOST,PROCESSLIST_DBFROM performance_schema.threadsWHERE PROCESSLIST_ID=CONNECTION_ID();

The wrong response is “grant everything to root and retry.” The minimum repair is to fix the actual transport/account/routing condition while preserving least privilege.

Drill 2: deadlock and retry boundary

Deadlocks are expected in concurrent transactional systems. The database detects a cycle and rolls back one transaction. The application owns the transaction boundary and retries only when the operation is safe to repeat.

sql · Session A — create one half of a deterministic deadlock
USE servicehub_capstone;START TRANSACTION;UPDATE work_orders SET priority=5 WHERE work_order_id=1;-- Wait here, then attempt after Session B locks row 2:UPDATE work_orders SET priority=5 WHERE work_order_id=2;
sql · Session B — reverse lock order
USE servicehub_capstone;START TRANSACTION;UPDATE work_orders SET priority=4 WHERE work_order_id=2;-- Now attempt row 1; one transaction should become the deadlock victim.UPDATE work_orders SET priority=4 WHERE work_order_id=1;COMMIT;
sql · diagnostic evidence after the deadlock
SHOW ENGINE INNODB STATUS;SELECT THREAD_ID,EVENT_ID,STATE,TRX_ID,ACCESS_MODE,ISOLATION_LEVELFROM performance_schema.events_transactions_current;SELECT *FROM performance_schema.data_lock_waits;

Repair the workload by taking locks in a consistent order and keeping transactions short. If a deadlock still occurs, retry the whole transaction with bounded backoff. Never retry only the final statement of a transaction whose earlier statements were rolled back.

Drill 3: load spike and the retry-storm trap

A transient slowdown becomes an outage when every application instance retries immediately and increases demand. The capstone load harness can deliberately raise concurrency until latency/error signals worsen. The application should use bounded connection pools, deadlines, jittered backoff, and graceful degradation rather than unlimited parallel retries.

text · safe load-spike procedure
1. Record baseline at concurrency 8.2. Run the same workload at concurrency 32 (or the highest safe laptop value).3. Capture p95/p99, error rate, Threads_running, CPU, storage latency, statement digests.4. Do NOT raise max_connections as the first reaction.5. Restore normal concurrency and confirm latency/error rate recover.6. Record whether the bottleneck was CPU, I/O, locks, bad SQL, pool pressure, or unknown.
sql · MySQL concurrency and wait evidence during the spike
SHOW GLOBAL STATUS WHERE Variable_name IN('Threads_connected','Threads_running','Connection_errors_max_connections', 'Aborted_clients','Aborted_connects');SELECT EVENT_NAME,COUNT_STAR,       ROUND(SUM_TIMER_WAIT/1000000000000,3) AS total_secondsFROM performance_schema.events_waits_summary_global_by_event_nameORDER BY SUM_TIMER_WAIT DESCLIMIT 15;

If raising concurrency reduces throughput and increases latency, the system is saturated. More queued work is not more capacity.

Drill 4: accidental data change and recovery decision

Logical damage is where HA can make things worse by rapidly propagating the mistake. Use only the disposable capstone. Record a recovery boundary, make one identifiable bad update, and choose between transaction rollback (if still open), compensating change (if semantically safe), or restore/PITR.

sql · inject and detect a disposable logical error
USE servicehub_capstone;SELECT COUNT(*) AS open_before FROM work_orders WHERE status='OPEN';SELECT NOW(6) AS incident_marker;-- Intentional lab mistake: committed logical damage.UPDATE work_orders SET status='CANCELLED' WHERE status='OPEN';COMMIT;SELECT COUNT(*) AS open_after FROM work_orders WHERE status='OPEN';SELECT COUNT(*) AS cancelled_after FROM work_orders WHERE status='CANCELLED';

Do not “repair” with an opposite mass update unless the original set is exactly knowable and no legitimate cancellations occurred concurrently. The safer production approach is to restore a backup to an isolated target, replay binary logs to the correct boundary, validate business invariants, and then plan controlled cutover/reconciliation.

Optional Drill 5: member/primary loss through Router

javascript · MySQL Shell — observe and inject one sandbox-member failure
var cluster = dba.getCluster('serviceHubCapstone')cluster.status({extended: 1})// Identify the current primary from status output.// Stop ONLY one disposable sandbox instance using the supported sandbox command,// or stop its mysqld process through your local lab method.// Then re-run:cluster.status({extended: 1})

Keep an application connection loop pointed at Router's read/write endpoint. Measure failed requests, reconnect time, ambiguous transactions, new primary identity, and business invariants. A three-member sandbox should retain quorum after one member loss. If two members are lost, quorum is lost; forcing quorum is an exceptional recovery procedure and must not be used as a routine “make it writable” command.

Correctness gates after every recovery

sql · business invariants that matter more than process state
USE servicehub_capstone;-- Every work order references a valid asset at the same site.SELECT COUNT(*) AS cross_site_mismatchesFROM work_orders wJOIN assets a ON a.asset_id=w.asset_idWHERE a.site_id<>w.site_id;-- Every event has a work order (also enforced by FK, checked explicitly here).SELECT COUNT(*) AS orphan_eventsFROM work_order_events eLEFT JOIN work_orders w ON w.work_order_id=e.work_order_idWHERE w.work_order_id IS NULL;-- No duplicate integration idempotency keys are possible because PK enforces it.SELECT COUNT(*) AS duplicate_keysFROM (  SELECT idempotency_key FROM integration_requests  GROUP BY idempotency_key HAVING COUNT(*)>1) d;SELECT status,COUNT(*)FROM work_orders GROUP BY status ORDER BY status;

“mysqld is running” is not a recovery criterion. Router reachability, replication state, schema version, application canaries, and business invariants all belong to the acceptance gate.

Final design defense

DecisionDefenseKnown cost / caveat
MySQL 8.4 LTS + InnoDBmatches relational ACID OLTP and team skill setrequires disciplined upgrades/patching and index/transaction engineering
single-primary 3-member InnoDB Clusterautomatic primary election with quorum safety; one member failure toleratedthree full copies; network/failure-domain design; certification/HA operational complexity
Router at app tierdecouples clients from primary identityRouter itself needs deployment/restart/monitoring strategy
tested logical backup + binlog PITRrecovers logical/operator damage independently of HArestore time/storage/log-retention discipline; must test continuously
least privilege + TLSlimits blast radius and protects transportcertificate/secret rotation and account lifecycle overhead
workload-derived index portfoliotargets actual access pathswrite/storage cost; portfolio must evolve with workload
Performance Schema + SLO dashboardties symptoms to server evidenceinstrumentation retention/overhead and alert tuning
expand/contract migrationssupports mixed application versions and safer rollbacktemporary schema/code complexity and longer change windows

The defense must also list what remains unmet. A laptop cannot prove datacenter failure domains, production storage latency, real 120-session concurrency, or true 99.95% monthly availability. Those are production acceptance items. The course has taught the mechanism for measuring them, not fabricated evidence that they already pass.

text · final go-live / design-defense packet
1. ADR + SLO/workload/capacity assumptions2. schema DDL + migration ledger/checksums3. index portfolio + EXPLAIN/EXPLAIN ANALYZE evidence4. security roles/accounts/TLS/session contract5. repeatable load-test code + >=3 run artifacts + OS/MySQL evidence6. backup manifest/checksum + latest successful restore test7. PITR preflight + retention/runway evidence8. topology diagram + cluster/replication/Router evidence9. dashboard/alerts + escalation owners10. incident runbooks + completed failure-drill records11. upgrade/rollback plan + point-of-no-return authority12. unmet SLOs, cost/complexity, known risks, revisit triggers, next improvements

Final capstone cleanup

sql · remove only the disposable single-node artifacts after exporting evidence
DROP DATABASE IF EXISTS servicehub_capstone_restore;DROP DATABASE IF EXISTS servicehub_capstone;DROP USER IF EXISTS 'sh_cap_app'@'127.0.0.1';DROP ROLE IF EXISTS 'r_sh_app_rw','r_sh_app_ro','r_sh_operator';

If you created sandbox Cluster/Router instances, remove them using the MySQL Shell/AdminAPI sandbox lifecycle appropriate to your environment after saving the cluster status and drill evidence. Never run capstone cleanup commands against a real database merely because names look familiar.

Course completion: what production judgment now means

Across 22 chapters, MySQL moved from a server you can query to a system you can defend: storage and MVCC, transactions and concurrency, indexes and plans, security, backup/PITR, replication and Cluster, observability, performance, large-table lifecycle, application reliability, upgrades, and specialized boundaries. The final skill is not memorizing every variable. It is forming a hypothesis, gathering evidence, choosing the smallest safe intervention, validating correctness, and preserving a recovery path.

Knowledge check

  1. Why is process restart not enough to declare recovery?
  2. How should an application handle a deadlock victim?
  3. Why can HA worsen accidental data damage?
  4. What does a laptop HA sandbox prove?
  5. What makes the final design defensible?
Reveal answers
  1. Service reachability, topology/replication state, application canaries, schema version, and business invariants must also be correct.
  2. Rollback is already forced for the victim; retry the complete idempotent transaction with bounded backoff, not one final statement.
  3. Healthy replication can propagate the bad transaction quickly; logical recovery therefore needs backups/PITR or another independent recovery path.
  4. Topology mechanics, routing, election/rejoin behavior and runbook practice—not production failure-domain independence or capacity.
  5. Traceability from measurable requirements to design choices, reproducible evidence, tested recovery/failure behavior, explicit tradeoffs, and honest unmet risks.

Authoritative references

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only assets compatible with the Ethereum/ERC-20 network. Do not send TRC-20/TRON assets.