Graph
Cases5 cases
1 to 5 of 5
IL-0240Cloudflare API requests failed and the dashboard slowed for hours after the authentication database lost its replicasCloudflare2020- Symptoms
On 2 November 2020 the Cloudflare API and dashboard were degraded for six hours and 33 minutes. The success rate of API queries dropped at times to 75%, and the dashboard was up to 80 times slower than normal, while Cloudflare's edge network kept working.
- Trigger
At 14:43 UTC a network switch in a control plane data center partly failed: it kept LACP and BGP running but stopped forwarding some packets, and it recovered on its own six minutes later.
- Root cause
- Component
- Contributing factor
- Detection
At 14:43 UTC alerts fired because the misbehaving switch was unreachable to pings. Engineers then saw that the primary authentication database was overwhelmed.
- Remediation
- Shed load from the primary authentication database by slowing SSL certificate pushes to the edge, emails and other features
- Moved API traffic that could use read replicas to the secondary data center by hand
- Sent authentication calls fully back to the primary data center when the dashboard got worse
- Rebuilt the first database replica, which put itself back into service at 21:20 UTC and returned performance to normal
- Ramped the turned-down services back up so asynchronous processing could catch up
- Action items
- Remove the cluster management limitation that requires rebuilding all replicas after a primary is promoted
- Redesign the user sessions system so dashboard traffic can be steered between data centers
- Change the auto-remediation configuration so a database replica is not promoted so quickly
- Tune each system involved to be more resilient to failures of its dependencies
- Lessons
Every system in the chain had redundancy and none failed completely; each only degraded, which made the chain of events much harder to model and foresee. Automating replica promotion so that it could trigger on a minute's notice had been a point of pride, but for at least one database a fast promotion can do more harm than the failure it answers. Most general-purpose cluster managers use Raft or Paxos rather than Byzantine fault tolerant protocols, accepting a rare failure mode in exchange for a protocol that is simpler to implement correctly and debug.
IL-0210GitHub's MySQL clusters failed over to the US West Coast and the site served slow, stale, inconsistent data for 24 hoursGitHub2018- Symptoms
At 22:54 UTC on 21 October 2018 GitHub's internal monitoring started alerting on many faults at once. By 23:02 UTC the first responders saw that the replication topologies of many MySQL clusters were in an unexpected state: the Orchestrator API showed topologies made only of servers in the US West Coast data center. When connectivity came back, the application tier had immediately started sending writes to the new West Coast primaries.
- Trigger
At 22:52 UTC on 21 October, routine maintenance to replace failing 100G optical equipment cut connectivity between GitHub's US East Coast network hub and its primary US East Coast data center for 43 seconds.
- Root cause
- Component
- Contributing factor
- Detection
GitHub's internal monitoring raised alerts on numerous faults at 22:54 UTC, two minutes after the partition. By 23:02 UTC the first responders had found, by querying the Orchestrator API, that many database clusters had a topology with only US West Coast servers.
- Remediation
- Locked the internal deployment tooling to stop further changes
- Paused webhook delivery and GitHub Pages builds to stop jobs writing metadata
- Restored the affected MySQL clusters from backups into the US East Coast data center and let them replicate from the West Coast
- Found ways to restore directly from the West Coast to get around the throughput limits of downloading from off-site storage
- Moved all database primaries back to the US East Coast data center
- Spread read traffic over additional MySQL read replicas in the US East Coast public cloud so replication could catch up
- Failed over to the original topology once the replicas were in sync
- Processed the backlog of webhook events and Pages builds, pausing to raise an internal TTL after about 200,000 webhook payloads were dropped
- Action items
- Reconcile the writes from the captured MySQL binary logs that were not replicated, automatically where possible and with user outreach otherwise
- Make sure status updates can be published even when GitHub Pages builds are paused
- Give more accurate public estimates of the time to repair
- Configure Orchestrator so it cannot promote database primaries across regional boundaries
- Move to a status reporting mechanism that shows the status of each component of the platform
- Serve GitHub traffic from multiple data centers in an active/active/active design with N+1 redundancy at the facility level
- Test assumptions about the system more proactively
- Validate failure scenarios systematically, with investment in fault injection and chaos engineering tooling
- Lessons
Orchestrator did what it was configured to do, but the application tier could not work with primaries on the other side of the country: leader election within one region is generally safe, while the sudden cross-country latency was a major contributing factor. The behaviour emerged from a partition larger than any GitHub had seen. Replication caught up along a power decay curve, not a straight line, so the linear estimates of recovery time were wrong. GitHub concluded that tighter operational controls and faster response are not enough on their own and that failure scenarios have to be validated before they happen.
IL-0430Mackerel's Redis stopped answering during a replication setup, keepalived failed over by mistake, and Mackerel degradedHatena2018- Symptoms
On 26 September 2018 at 10:51 JST the whole Mackerel monitoring service stopped working properly and its alive monitoring stopped. The application servers could not connect to Redis, which stores Mackerel's monitoring data, and could not return correct responses.
- Trigger
Redis memory use had been growing, so operators set up replication in order to scale Redis up. Building the replication took a long time and Redis stopped answering for a while, and keepalived treated this as a node failure and started a failover nobody intended.
- Root cause
- Component
- Contributing factor
- Remediation
- Switched back to the correct Redis and briefly saw the application return
- Restarted the application servers one after another, which did not improve the symptoms
- Detected the organizations posting inappropriate metrics and blocked their requests
- Adjusted the timeout interval of the application servers
- Temporarily added capacity to Diamond, the TSDB
- Increased the number of Kinesis shards and Redis Cluster shards
- Scaled out the API application servers
- Put Mackerel in maintenance mode, checked it internally and let outside requests back gradually
- Action items
- Raise the number of keepalived health checks for Redis so a brief load increase does not trigger a failover
- Scale Redis up
- Add more application servers
- Change the application to store only the monitoring data it needs in Redis, reducing Redis memory use
- Build a way to detect inappropriate API requests quickly and show them on a dashboard
- Build a function to block organizations making inappropriate requests quickly
- Keep improving the accuracy of detecting inappropriate requests and consider adding features such as an API limit
- Strengthen monitoring of the application servers' internal processing so problems are handled before they become outages
- Lessons
Hatena did not find why recovery took so long, but expects that keeping failover from reacting to short load spikes and giving the application more performance headroom would prevent an outage this long. It also aims to keep problems contained to a small part of the service when a failure does happen.
IL-0431During Mackerel's move to AWS, PostgreSQL failed over to a replica that had stopped replicating, losing an hour of dataHatena2017- Symptoms
On 7 August 2017, while checking the application after the maintenance that moved Mackerel from an on-premises data center to AWS, the team found that data updated during a specific time window was missing. Everything written to the PostgreSQL database between 14:30 and 15:30 JST was gone.
- Trigger
One hour after the application was switched to the newly promoted primary db001, db001 lost network connectivity and the database failed over to the standby db002.
- Root cause
- Component
- Contributing factor
- Detection
The team found the missing data while checking how the application behaved after the migration work.
- Remediation
- Tried to restore the lost updates by hand from the table data left on db001 and gave up
- Tried point-in-time recovery from the base backup and WAL and gave up
- Built a new replica db003 with db002 as primary to restore redundancy
- Kept db001 in maintenance state for investigation
- Watched db002 for some time to confirm the problem did not recur, then completed the migration
- Action items
- Change the PostgreSQL replica creation script to set recovery_target_timeline = 'latest' in recovery.conf by default
- Add a check to a server configuration test tool such as Serverspec that recovery.conf contains recovery_target_timeline = 'latest'
- Lessons
A setting needed only for a rare layout, such as a grandchild replica during a migration, was applied by hand through a script option and was forgotten. Because recovery_target_timeline = 'latest' is harmless on ordinary standbys too, Hatena now sets it by default whenever a replica is created. The staging rehearsal used the same layout and steps but had the setting right, so it could not catch the mistake. Hatena notes that a similar layout may be used again for a future PostgreSQL upgrade or a move to another region.
IL-0303GitHub's MySQL master failed over to a node with a cold buffer pool during a schema migration and GitHub.com went downGitHub2012- Symptoms
On Monday, September 10th, 2012, during a schema migration, the health checks on GitHub's MySQL master failed and Percona Replication Manager moved the 'active' role to another node of the new three-node cluster. That node's InnoDB buffer pool was cold and it performed poorly, its health checks failed in turn, and the role failed back to the original server. GitHub.com went down.
- Trigger
A schema migration on Monday, September 10th put more load on the master database than earlier migrations had, and Percona Replication Manager's health checks on the master failed.
- Root cause
- Component
- Contributing factor
- Detection
On the morning of September 11th, a developer told the operations team that the 'standby' node was returning incorrect query results.
- Remediation
- Enabled Pacemaker's maintenance-mode so no health checks or automatic failovers ran, and let the buffer pool warm
- Powered off the out-of-date node 'c' to end the partition
- Stopped Pacemaker and Heartbeat on nodes 'a' and 'b' and started them on node 'a' only
- Started MySQL on node 'a' in the active role
- Removed the events leaked to wrong dashboards and audited the wrongly routed repositories
- Contacted the owners of the exposed private repositories
- Action items
- Change the Pacemaker configuration so the active database role fails over only when an operations engineer starts it
- Find a way to warm the InnoDB buffer pool of slave databases so failovers do not hurt performance
- Audit the Pacemaker and Heartbeat stack, focusing on the code path behind the segfault
- Run hardware tests on the server where the segfault happened
- Lessons
GitHub concluded that automated failover is not the right strategy for its primary production database: for every failover in this incident, any member of the operations team would have said it should not happen. Failovers that must happen, in an emergency or during maintenance, should not hurt performance.
These 5 cases involve Database replication and Database failover manager. kubegap audits a Kubernetes cluster for gaps like these, read-only, from Claude Code or Codex; its checks cite public reports like the ones in this library.
By root cause4
DNS or network fault2 cases
- Component
- Contributing factor
- Organisation
Configuration change1 case
- Contributing factor
- Organisation
Operator error1 case
- Contributing factor
- Organisation
Software defect1 case
- Contributing factor
- Organisation