Shopify2023-10-18Incident / postmortem
Debugging Systems in the Cloud: MySQL, Kubernetes, and Cgroups
Summary
KateSQL, Shopify’s Database-as-a-Service platform on GKE, investigated why otherwise comparable MySQL Pods took between 10 and 30 minutes to be created during instance replacement. Measurements found extreme differences for Pods with identical resources and datasets: one required 2,120 seconds for initialization and 1,104 seconds for startup, while another took 74 and 17 seconds, respectively; affected Pods also accumulated more slow queries involving temporary memory tables. Profiling showed InnoDB’s single-threaded buffer pool initialization spending substantial time in mmap calls and the Linux memory cgroup function mem_cgroup_commit_charge, while affected nodes had roughly 50,000 memory cgroups. The team linked the slowdown to a Linux kernel cgroup memory leak and slab reparenting behavior, then improved performance through node replacement, memory.force_empty testing, and GKE 1.18 upgrades with relevant fixes.
Context
During KateSQL instance replacement, MySQL Pod creation times varied from 10 to 30 minutes, impairing the ability to replace instances quickly for maintenance tasks such as configuration changes and upgrades. Slow Pods also showed gradually declining performance and more slow queries involving temporary memory tables. Newer Kubernetes nodes performed better than nodes with months of uptime, despite matching software versions.
Approach / What changed
The team compared initialization and startup timings, analyzed MySQL and InnoDB behavior, captured strace and on-CPU perf data, examined slab allocation and memory cgroup counts, and consulted Linux and Google kernel engineers. They mitigated the issue by moving Pods off older nodes, tested memory.force_empty to remove dead cgroups, evaluated cache-dropping and workload-isolation workarounds, and created GKE 1.18 clusters with COS and upstream cgroup fixes.
Takeaways
Identical MySQL Pods showed sharply different timings: one took 2,120 seconds to initialize and 1,104 seconds to start, while another took 74 and 17 seconds.
Affected nodes had approximately 50,000 memory cgroups, and perf profiling showed InnoDB initialization spending much of its time in mem_cgroup_commit_charge.
GKE 1.18 clusters produced consistent InnoDB buffer pool initialization and query performance after several weeks of operation.
Source and freshness
- Source
- shopify.engineering
- Published
- Added to Yomu
- Last updated
Summaries are generated from the original by a language model. Check the original before relying on it.
Keep reading
Related reading
The Good Stuff
Paid picks we use ourselves. Links carry a referral code — a subscription through one earns us a commission at no extra cost to you.
The best engineering reads, once a week
One useful email. Unsubscribe anytime.