Incident Library
  • Root cause
  • Component
  • Symptom
  • Contributing factor
  • Case

Cases8 cases

7 to 8 of 8

  1. Symptoms

    On 13 March 2018 at 12:14 UTC every table in travis-ci.com's production PostgreSQL database was truncated. Alerts fired right away, and customers reported missing account data; people who signed in saw blank user profiles.

    Trigger

    At 12:04 UTC a developer ran a test suite in an old tmux shell that still had a DATABASEURL environment variable pointing at the production database, and the Database Cleaner gem sent a truncate query to it. The query was blocked for about 10 minutes and executed at 12:14 UTC.

    Root cause
    Component
    Contributing factor
    Detection

    Alerts fired immediately after the truncation, and customers reported missing account data.

    Remediation
    • Took all applications offline
    • Provisioned a replacement database from a snapshot taken that morning
    • Reattached the restored database and brought platform services back up
    • Worked through the backlog of builds until it cleared
    • Revoked all affected login tokens by 14:22 UTC on 14 March
    • Contacted affected customers and advised them to rotate stored credentials and check build logs
    Action items
    • Revoke the truncate permission on the databases
    • Make the internal spechelpers check for the DATABASEURL environment variable
    • Make the developer shell prompt warn when a DATABASE_URL is set
    • Submit a pull request to the Database Cleaner gem guarding against a remote DATABASE_URL
    • Create an alias for the follower database so it is easy to connect to for work against production data
    • Automate database failover and maintenance to cut manual recovery steps
    Lessons

    Developers connected to the production primary with write access because the tooling made the read-only follower hard to reach. While responding, Travis CI left user-facing applications running, which created duplicate user ids, and did not turn some alerts back on, which hid the stopped cron scheduler. Even the most experienced developers can make an inadvertent mistake that causes a large outage. The whole production database was recovered with only about 15 minutes of data loss.

  2. Symptoms

    At about 1 AM on 9 February 2017, UC Berkeley's DataHub was reported down: users trying to log in got a proxy error. The hub pod was running, but its log was full of sqlite errors.

    Trigger

    While debugging, an operator ran `.save jupyterhub.sqlite` in sqlite3 inside the hub pod without having attached the database, which replaced the JupyterHub database file with an empty one.

    Root cause
    Component
    Contributing factor
    Detection

    DataHub was reported down at about 1 AM, when users got a proxy error at login. At 1:12 AM a user reported that he could log in but all his notebooks were gone.

    Remediation
    • Scaled the hub to 0 replicas
    • Rebuilt the JupyterHub sqlite database by matching Kubernetes PVC names back to user ids
    • Set cookie_id to null instead of a dummy value and attached the rebuilt database to the hub
    • Changed the cookie secret in the hub pod and restarted it to log all users out
    • Deleted all user pods to log everyone out
    • Ran a script that filled in cookie_id for all users, restarted the hub and deleted all user pods again
    • Dropped the new users with a '.' in their name and renamed the older users from '-' to '.'
    Action items
    • Report upstream that JupyterHub uses only part of the cookie secret and discards the rest
    • Report upstream that the cookie_id column of the users table should have UNIQUE and NOT NULL constraints
    • Ask KubeSpawner to support username hashes in PVC and pod names so the names stay the same when the database is deleted
    • Ask OAuthenticator to support using the id from the Google authenticator as the user id, giving stable user ids
    • Switch to Google Cloud SQL, a hosted and managed MySQL database
    • Take regular and tested backups of the database
    • Start an operational FAQ of things to do and not to do
    • Set up better monitoring and paging
    • Document escalation procedures explicitly
Check your cluster for this

These 8 cases involve Database and Database replication. 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 cause2

Operator error7 cases

  1. IL-0577 Ficilcom's production Neon PostgreSQL database was reset by prisma migrate reset meant for the local database
  2. IL-0286 An exercise cleanup destroyed Honeycomb's Kafka brokers, leaving partitions leaderless and ingest crash-looping
  3. IL-0576 Every dataset in CareNet's production BigQuery data warehouse was deleted, and UNDROP SCHEMA could not restore them
  4. IL-0242 Both PostgreSQL servers behind matrix.org were lost during a disk expansion, and the homeserver was down for 24 hours
  5. IL-0565 Cookie Run: Kingdom's CockroachDB cluster failed when 16 of 24 nodes lost their filesystems, causing a 36-hour outage
  6. IL-0332 A test run against the production database truncated every table and travis-ci.com was down for about 5.5 hours
  7. IL-0506 UC Berkeley DataHub logins failed and students got empty home directories after the JupyterHub database was overwritten

Certificate or credential expiry1 case

Organisation
  1. IL-0490 Records were missing from LootLocker's new MySQL database after a migration cutover and the service degraded for 3 hours