{"id":"IL-0490","org":"LootLocker","date":"2026-04-28","docs":[],"title":{"en":"Records were missing from LootLocker's new MySQL database after a migration cutover and the service degraded for 3 hours","ko":"관리형 데이터베이스에서 자체 MySQL로 옮긴 뒤 이전 직전에 쓴 기록이 새 데이터베이스에 없어 LootLocker 서비스가 저하됐다"},"domain":["database"],"impact":{"scope":"LootLocker service degraded for about three hours on migration day; a window of writes from 2026-04-19 to 2026-04-20 was missing from the new database until it was replayed over the next two days","users":"a specific subset of users","region":"unknown"},"review":{"written_by":"session","reviewed_at":null,"reviewed_by":null},"lessons":{"en":"The failure was a silent side effect of an unrelated change made eight days earlier: the replication process recovered and kept working, so there was no signal that data had been dropped, and a pre-cutover integrity check would have caught it. Deleting the source database before validating the new one made recovery much harder. Choosing a live migration to avoid downtime left no clean point to verify integrity, and the resulting degradation and two days of piecemeal recovery far exceeded what a short planned maintenance window would have cost. The announcement on Discord was not clear enough about the impact and came with too little notice.","ko":"이전 작업 자체는 문제가 없었고, 실패는 8일 전 관련 없는 변경이 조용히 남긴 부작용이었다. 복제 프로세스가 다시 살아나 정상으로 돌았기 때문에 데이터를 잃었다는 신호가 없었고, 전환 전에 데이터 무결성을 확인했다면 트래픽을 다시 받기 전에 잡았을 것이다. 새 데이터베이스의 무결성을 확인하기 전에 원본 데이터베이스를 지운 탓에 복구가 크게 복잡해졌으므로 앞으로는 전환 뒤 확인이 끝날 때까지 원본을 남긴다. 중단을 줄이려고 고른 라이브 이전에는 트래픽이 돌아오기 전에 무결성을 확인할 틈이 없었다. 그 결과 약 3시간의 서비스 저하와 이틀의 복구가 이어졌고, 이는 계획된 유지보수로 서비스를 잠깐 멈췄을 때보다 훨씬 큰 영향이었다. Discord 공지는 영향이 분명하지 않았고 고객이 대비할 시간을 충분히 주지 못했다."},"related":[],"sources":[{"url":"https://lootlocker.com/blog/db-postmortem-data-loss-during-database-migration/","kind":"blog","archived":"https://web.archive.org/web/20260613055415/https://lootlocker.com/blog/db-postmortem-data-loss-during-database-migration"}],"summary":{"en":"LootLocker was moving from a large managed database provider to a custom MySQL deployment run with a European infrastructure partner, using a temporary one-off replication process for the length of the migration. On 2026-04-20 a credential rotation crashed that process. It recovered automatically within minutes, but the data batches in flight at the moment of the crash were dropped and never replayed, and because of how replication offsets and timezones interacted, the lost window also included some data from the previous day. Nothing monitored the health or replication lag of the sync process, and no pre-cutover step required a sync health and integrity check.\n\nThe cutover ran at 10:34 BST on 2026-04-28 without problems, and at about 10:40 the source database was deleted on the assumption that no rollback path was needed. Data anomalies were found at about 11:30, normal service behaviour was back by about 13:30, and the root cause was identified at about 19:00. Because the source database was gone, LootLocker had to ask the previous provider to restore it before the dropped batches could be replayed, which delayed recovery. The affected records were replayed for the impacted users over 2026-04-29 and 2026-04-30 without further disruption. LootLocker cannot fully rule out that more data written during the window of instability was affected.","ko":"LootLocker는 대형 관리형 데이터베이스 사업자를 떠나 유럽 인프라 협력사 위에서 직접 운영하는 MySQL로 데이터베이스를 옮기고 있었다. 이전 기간 동안 임시 일회성 복제 프로세스가 두 데이터베이스를 맞췄다. 2026-04-20 16:20 BST 무렵 관련 없는 설정 수정 작업 중에 자격 증명을 교체하자 그 자격 증명을 쓰던 복제 프로세스가 죽었다. 프로세스는 몇 분 만에 스스로 살아났지만 그 순간 처리 중이던 묶음은 버려진 채 다시 재생되지 않았다. 프로세스가 정상으로 돌았고 상태나 복제 지연을 보는 모니터링도 없어서 이 손실은 드러나지 않았다.\n\n2026-04-28 10:34 BST에 새 데이터베이스로 전환했고 전환 자체는 문제없이 끝났다. 10:40 무렵 되돌릴 길이 더는 필요 없다고 보고 원본 데이터베이스를 지웠다. 11:30 무렵 운영에서 데이터 이상이 보여 조사를 시작했고, 팀은 원인보다 서비스 동작을 되살리는 일을 먼저 해 13:30 무렵 정상으로 돌렸다. 19:00 무렵 원인을 찾았지만, 버려진 묶음을 다시 재생하려면 지운 원본 데이터베이스가 필요해 이전 사업자에게 복원을 요청해야 했고 복구가 늦어졌다.\n\n원본 데이터베이스를 복원한 뒤 2026-04-29부터 2026-04-30까지 영향을 받은 사용자의 기록을 조금씩 다시 재생했고, 그동안 서비스는 더 멈추지 않았다. LootLocker는 불안정했던 기간에 쓴 데이터 일부가 더 영향을 받았을 가능성을 완전히 배제할 수 없다고 밝혔다. LootLocker는 기여 요인으로 네 가지를 들었다. 임시 동기화 프로세스에 모니터링이 없었고, 런북에 전환 전 동기화 상태와 무결성을 확인하는 단계가 없었다. 자격 증명을 교체할 때 그 자격 증명을 쓰는 프로세스에 미칠 영향을 따지지 않았고, 새 데이터베이스의 무결성을 확인하기 전에 원본 데이터베이스를 지웠다."},"trigger":{"en":"On 2026-04-20 at about 16:20 BST, a routine credential rotation, made as part of an unrelated configuration fix, changed the credentials that the temporary replication process used for its database connection, and the process crashed.","ko":"2026-04-20 16:20 BST 무렵 관련 없는 설정 수정 작업 중에 자격 증명을 교체했다. 그 자격 증명으로 데이터베이스 연결을 잡고 있던 임시 일회성 복제 프로세스가 죽었고, 그 순간 처리 중이던 데이터 묶음이 버려진 뒤 다시 재생되지 않았다."},"severity":"sev2","symptoms":["data-loss"],"timeline":{"detected_after":"56m","resolved_after":"2h 56m"},"date_kind":"incident","detection":{"en":"Data anomalies were detected in production at about 11:30 BST, about an hour after the cutover.","ko":"2026-04-28 11:30 BST 무렵 운영에서 데이터 이상을 발견하고 조사를 시작했다. 8일 전의 손실은 그때까지 아무 신호도 없었다."},"components":["database","database-replication"],"root_cause":"certificate-expiry","remediation":[{"text":{"en":"Restored normal service behaviour first and deferred the root cause analysis","ko":"근본 원인을 찾는 일보다 서비스의 정상 동작을 되살리는 일을 먼저 했고, 전환 약 3시간 뒤인 13:30 BST 무렵 정상 동작이 돌아왔다."}},{"text":{"en":"Requested a restore of the deleted source database from the previous provider","ko":"버려진 묶음을 다시 재생할 원본으로 쓰려고 이전 사업자에게 지운 원본 데이터베이스의 복원을 요청했다."}},{"text":{"en":"Replayed the affected records for impacted users from the restored source database","ko":"2026-04-29부터 2026-04-30까지 원본 데이터베이스를 복원하고 영향을 받은 사용자의 기록을 다시 재생했다. 이 동안 서비스는 더 멈추지 않았다."}}],"action_items":[{"text":{"en":"Perform technical changes of comparable risk in a scheduled maintenance window instead of as live cutovers","ko":"위험도가 비슷한 기술 변경은 라이브 전환 대신 계획된 유지보수 시간 안에 한다. 트래픽을 다시 받기 전에 무결성을 확인할 수 있도록 짧은 계획 중단을 받아들인다."}},{"text":{"en":"Require a pre-cutover checklist that verifies replication or sync processes are live and caught up just before cutover","ko":"이런 변경에는 전환 전 점검표를 두고, 전환 직전에 데이터 복제나 동기화 프로세스가 살아 있고 따라잡았는지 확인한다."}},{"text":{"en":"Require an explicit downstream impact review for credential rotations of service accounts used by long-running processes","ko":"오래 도는 프로세스가 쓰는 서비스 계정의 자격 증명을 교체할 때는 그 뒤에 영향을 받을 곳을 명시적으로 검토한다."}},{"text":{"en":"Keep source systems until integrity in the target has been independently verified after cutover","ko":"전환 뒤 대상 쪽의 무결성을 따로 확인하기 전에는 원본 시스템을 내리거나 지우지 않는다."}},{"text":{"en":"Publish planned maintenance and migration notices in the in-product News feed as well as Discord, with clear impact statements and more advance notice","ko":"계획된 유지보수와 이전을 고객에게 알릴 때 Discord와 함께 웹 콘솔에서 보이는 제품 안 News 피드에도 올리고, 영향을 분명히 적고, 이번보다 훨씬 일찍 알린다."}}],"contributing":["delayed-effect-change","monitoring-blind-spot","assumption-unverified","no-safeguard-on-destructive-change"],"recurrence_of":null,"symptoms_text":{"en":"About an hour after LootLocker cut over from a managed database provider to its own MySQL deployment on 2026-04-28, data anomalies showed up in production. A small window of writes made shortly before the migration, spanning 2026-04-19 to 2026-04-20, had never reached the new database, and the service stayed degraded for about three hours after the cutover.\n\nThe gap traced back eight days, to a brief crash of the temporary replication process that synced the two databases. The process recovered on its own within minutes and kept replicating normally, so nothing showed at the time that the batches in flight during the crash had been dropped. The team first restored normal service behaviour and put off the root cause analysis, which identified the dropped batches later that evening.","ko":"2026-04-28 10:34 BST에 새 데이터베이스로 전환한 뒤 11:30 무렵 운영에서 데이터 이상이 보였다. 이전 직전에 쓴 짧은 기간의 데이터가 새 데이터베이스로 복제되지 않았고, 서비스는 전환 때부터 약 3시간 저하됐다.\n\n빠진 것은 2026-04-19부터 2026-04-20에 걸친 짧은 기간의 쓰기였다. 복제 오프셋과 시간대가 맞물린 방식 때문에 전날 데이터 일부도 이 기간에 들어갔다.\n\n데이터가 빠진 일은 8일 전에 이미 일어났지만 이전 당일까지 아무도 몰랐다. 복제 프로세스는 잠깐 죽었다가 몇 분 만에 스스로 살아나 정상으로 복제를 이어 갔기 때문에 무언가를 잃었다는 신호가 없었다. 임시 동기화 프로세스의 상태나 복제 지연을 보는 모니터링과 알림도 없었다.\n\n팀은 근본 원인을 찾기보다 서비스 동작을 되살리는 일을 먼저 했고, 13:30 무렵 서비스가 정상으로 돌아왔다. 원인은 그날 19:00 무렵 찾았지만, 원본 데이터베이스는 전환 직후인 10:40 무렵 이미 지운 뒤였다."},"updated_at":"2026-11-14T12:34:13.523831Z","url":"https://benchlet.com/incidentlib/app/cases/IL-0490","org_slug":"lootlocker"}