{"id":"IL-0334","org":"Instapaper","date":"2017-02-09","docs":[],"title":{"en":"Instapaper's RDS MySQL bookmarks table hit the 2TB ext3 file size limit, inserts failed and the service went down","ko":"RDS MySQL 의 bookmarks 테이블이 2TB 파일 크기 한도에 닿아 INSERT 가 실패하고 Instapaper 가 31시간 동안 멈췄다"},"domain":["database","aws"],"impact":{"scope":"Instapaper service down for 31 hours, then five days of limited access to archives until full recovery on February 14; no user articles were lost","users":"Instapaper users","region":"unknown"},"review":{"written_by":"session","reviewed_at":null,"reviewed_by":null},"lessons":{"en":"A filesystem limit that Instapaper did not know about and could not see made both the production database and all its backups useless, and the only way out was to restore the data onto a new filesystem. Because the hosted database could only be reached through MySQL, filesystem-level fixes such as rsync needed Amazon engineers. Even with a perfect response, rebuilding the database would have taken at least 10 hours. The lack of a disaster recovery plan for this kind of failure, and the estimate of the dump time from row counts, made the downtime and recovery longer than necessary, and the response could have drawn better on Pinterest's and AWS's people. The new escalation workflow and monthly backup tests would not have prevented this failure but would speed up the response to a future one.","ko":"팀이 알지 못했고 볼 수도 없었던 파일 시스템 한도 때문에 운영 데이터베이스뿐 아니라 모든 백업까지 쓸 수 없게 됐다. 호스팅된 인스턴스에는 MySQL 로만 접근할 수 있어서 rsync 같은 파일 시스템 수준의 해결책은 Amazon 엔지니어의 도움 없이는 쓸 수 없었다. 완벽하게 대응했어도 진단부터 데이터베이스 재구축까지 다운타임은 최소 10시간이었을 것이다. 이 문제는 미리 내다보고 막기 어려웠지만, 이런 장애를 위한 재해 복구 계획이 없어 다운타임과 복구 시간이 필요 이상으로 길어졌다. 데이터베이스를 다시 만드는 데 며칠이 걸린다는 것을 알았다면 곧바로 제한된 서비스 복구로 들어가 첫날의 다운타임을 크게 줄일 수 있었다. Pinterest 안에서, 그리고 AWS 팀과 더 잘 소통했다면 쓸 수 있는 자원을 더 잘 활용했을 것이다. 글쓴이는 다른 회사가 호스팅하는 기술이라도 매일 운영에 쓰는 기술의 한도를 이해하는 것이 자신의 책임이라고 밝혔다."},"related":[],"sources":[{"url":"https://medium.com/making-instapaper/instapaper-outage-cause-recovery-3c32a7e9cc5f","kind":"blog","archived":"https://web.archive.org/web/20260306053318/https://medium.com/making-instapaper/instapaper-outage-cause-recovery-3c32a7e9cc5f"}],"summary":{"en":"MySQL RDS instances created before April 2014 run on an ext3 filesystem with a 2TB file size limit; later instances use ext4 with a 6TB limit. Instapaper's first RDS instance was created in June 2013, when betaworks moved Instapaper from Softlayer to AWS with two devops contractors; any knowledge of the limit probably left with them. In March 2015, to fix performance problems during the backup window, the team created a read replica of that instance, upgraded it from MySQL v5.6.18 and cut over to it with about 5 minutes of downtime. Although created after April 2014, the replica inherited the original instance's filesystem and its 2TB limit. On February 9, 2017 the bookmarks table passed 2TB and inserts failed. Every backup was a filesystem snapshot under the same limit, and there was no disaster recovery plan for this kind of failure.\n\nGuided by Pinterest's SRE team, Instapaper dumped the 2.5TB production database to a 5.5TB RAID-0 disk on an i2.8xlarge instance. When the dump proved far slower than estimated, the team switched to a contingency plan and, in about six hours, built a temporary production instance with limited access to archives, which went live after 31 hours of downtime. Over the weekend RDS engineers worked on two parallel paths: an Aurora read replica of the old database, finished in about 24 hours but risky because Aurora had not been tested with the Instapaper codebase, and a new MySQL RDS instance loaded without secondary indexes in 8 hours, where each of the three secondary indexes then took about 16 hours. Because the indexes were too slow, an Amazon engineer mounted an ext4 filesystem on the failed production database and copied the data across with rsync in about 8 hours, giving an ext4-backed instance with all data and indexes.\n\nRDS engineers then set up row-based replication from the binary logs of the temporary production database to the new ext4 instance, which took about three hours to catch up on the changes made since Thursday. The new database was promoted to master and the application was deployed to point at it. Full service was restored on February 14 without losing any older articles, recent changes or articles saved after the outage.","ko":"Instapaper 는 MySQL 데이터베이스를 Amazon RDS 에서 운영했다. 2013년 6월에 만든 원래 인스턴스는 2015년 초 백업 시간대에 성능 문제를 겪었고, AWS 지원은 MySQL v5.6.19 이상으로 올리면 풀린다고 했다. 2015년 3월 팀은 원래 인스턴스의 읽기 복제본을 만들어 MySQL 을 올리고 약 5분의 다운타임으로 전환했다. 새 인스턴스는 2014년 4월 뒤에 만들었지만 2013년 6월 인스턴스의 읽기 복제본이라 ext3 파일 시스템과 2TB 파일 크기 한도를 물려받았다. 2014년 4월 전에 만든 MySQL RDS 인스턴스는 ext3 를 써서 한도가 2TB 이고, 그 뒤에 만든 인스턴스는 ext4 를 써서 한도가 6TB 다. 이 한도를 알았던 사람이 있었다면, 2013년 Softlayer 에서 AWS 로 옮길 때 일한 betaworks 외부 계약자였을 것이다. RDS 콘솔에도 이를 알려 주는 것이 없었다.\n\n2월 9일 수요일 12:30PM PT 에 bookmarks 테이블이 2TB 를 넘어 INSERT 가 실패하기 시작했다. 10일치 자동 백업도 파일 시스템 스냅샷이라 같은 한도에 묶였다. 이런 장애를 위한 재해 복구 계획도 없었다. 팀은 AWS 지원, Pinterest 의 SRE 와 논의한 끝에 2.5TB 데이터베이스를 전체 덤프와 복원으로 다시 만들기로 했다. Pinterest SRE 팀의 안내로 i2.8xlarge 인스턴스의 5.5TB RAID-0 디스크에 덤프했지만 첫 시도는 24시간, 병렬로 돌린 두 번째 시도는 10시간이 걸렸다. 그래서 팀은 아카이브 접근을 제한한 임시 인스턴스를 약 6시간 만에 만들어, 31시간의 다운타임 끝에 2월 10일 목요일 7:30pm PT 에 운영에 올렸다.\n\n주말 동안 RDS 엔지니어들과 두 갈래로 복원을 진행했다. 하나는 옛 데이터베이스의 Aurora 읽기 복제본으로 약 24시간 만에 끝났다. 다른 하나는 새 MySQL RDS 인스턴스에 보조 인덱스 없이 데이터를 8시간 동안 넣은 뒤 보조 인덱스 세 개를 하나에 약 16시간씩 만드는 것이었다. 인덱스 생성이 너무 오래 걸리자 Amazon 엔지니어가 실패한 운영 데이터베이스에 ext4 파일 시스템을 마운트하고 ext3 에서 ext4 로 rsync 를 약 8시간 돌려, 데이터와 인덱스가 모두 있는 ext4 데이터베이스를 얻었다. 임시 운영 데이터베이스의 바이너리 로그로 행 기반 복제를 약 3시간 돌려 목요일부터 월요일까지의 변경을 맞췄다. 그다음 새 데이터베이스를 마스터로 승격하고 애플리케이션이 이를 가리키도록 배포했다. 2월 14일에 전체 복구를 마쳤고, 사용자의 글은 하나도 잃지 않았다."},"trigger":{"en":"At 12:30PM PT on February 9 the bookmarks table grew past the 2TB file size limit of the instance's filesystem.","ko":"2월 9일 수요일 12:30PM PT 에 bookmarks 테이블이 2TB 파일 크기 한도를 넘었다."},"severity":"unknown","symptoms":["writes-rejected","service-unavailable"],"timeline":{"detected_after":null,"resolved_after":"31h"},"date_kind":"incident","detection":null,"components":["database","database-backup","database-replication"],"root_cause":"capacity","remediation":[{"text":{"en":"Dumped the production database to a 5.5TB RAID-0 disk on an i2.8xlarge instance with Pinterest's SRE team","ko":"Pinterest SRE 팀의 안내로 Instapaper 운영 데이터베이스를 i2.8xlarge 인스턴스의 5.5TB RAID-0 디스크에 덤프했다. 첫 시도는 24시간, 병렬로 돌린 두 번째 시도는 10시간이 걸렸다."}},{"text":{"en":"Launched a temporary production instance with limited access to archives","ko":"덤프가 너무 오래 걸리자 아카이브 접근을 제한한 채 동작하는 인스턴스를 약 6시간 만에 만들어, 31시간의 다운타임 끝에 운영에 올렸다."}},{"text":{"en":"Set up an Aurora read replica of the old database as one recovery path","ko":"옛 데이터베이스의 Aurora 읽기 복제본을 만들었다. Aurora 는 Instapaper 코드로 충분히 시험해 보지 않아 위험하다고 봤지만 만들기는 쉬웠다. 약 24시간 만에 끝났다."}},{"text":{"en":"Imported the data into a new MySQL RDS instance without secondary indexes, then built the indexes","ko":"새 MySQL RDS 인스턴스를 만들어 보조 인덱스 없이 데이터를 모두 넣었다. 8시간이 걸렸다. 그 뒤 보조 인덱스 세 개를 하나에 약 16시간씩 만들었다."}},{"text":{"en":"Had an Amazon engineer rsync the data from the ext3 filesystem to an ext4 filesystem mounted on the failed database","ko":"Amazon 엔지니어가 실패한 운영 데이터베이스에 ext4 파일 시스템을 마운트하고 ext3 파일 시스템에서 ext4 파일 시스템으로 rsync 를 약 8시간 돌려, 데이터와 인덱스가 모두 있는 ext4 데이터베이스 인스턴스를 만들었다."}},{"text":{"en":"Synced the new ext4 database with the temporary production database through row-based replication","ko":"RDS 엔지니어들이 임시 운영 데이터베이스의 바이너리 로그로 새 ext4 데이터베이스에 행 기반 복제를 걸어 목요일부터 월요일까지의 변경을 맞췄다. 약 3시간이 걸렸다."}},{"text":{"en":"Promoted the new database to master and pointed the application at it","ko":"새 데이터베이스를 마스터로 승격하고 애플리케이션 코드가 새 데이터베이스를 가리키도록 배포했다."}}],"action_items":[{"text":{"en":"Define a workflow that escalates system-wide Instapaper outages immediately to Pinterest's SRE team","ko":"Instapaper 전체 장애가 나면 Pinterest 의 SRE 팀에 바로 에스컬레이션하는 절차를 만든다."}},{"text":{"en":"Test MySQL backups every month instead of every three months","ko":"MySQL 백업 시험 주기를 석 달에 한 번에서 한 달에 한 번으로 늘린다."}},{"text":{"en":"Put a process in place with Pinterest's SRE team to recover from this type of failure","ko":"Pinterest 의 SRE 팀과 함께 이런 장애가 다시 나면 복구할 수 있는 절차를 마련한다."}}],"contributing":["limit-unknown","monitoring-blind-spot","backup-unverified","no-runbook","limited-debug-access"],"recurrence_of":null,"symptoms_text":{"en":"On Wednesday, February 9, 2017 at 12:30PM PT, inserts of new entries into the bookmarks table of Instapaper's MySQL database on Amazon RDS started to fail with an error. The bookmarks table, which stores the articles Instapaper users save, had grown past 2TB, and the Instapaper service was down until Thursday, February 10 at 7:30pm PT.\n\nNothing on the RDS side warned of the problem. As far as Instapaper could tell, the RDS console offered no monitoring, alert or log that showed the table approaching a 2TB file size limit, or that the instance was subject to such a limit at all, and even after the outage nothing marked the database as having a critical issue. The ten days of automated daily RDS backups were filesystem snapshots with the same limit, so none of them could be used to recover.\n\nAfter a long call with AWS support and talks with Pinterest's Site Reliability engineers, the only way forward was a full dump and restore of the 2.5TB database to a new instance. Instapaper had estimated six to eight hours for the dump from the number of rows, but the first 25 percent of bookmarks held only 10 percent of the data: the first dump took 24 hours and a second, parallelised one took 10 hours.","ko":"2월 9일 수요일 12:30PM PT 부터 Instapaper 사용자가 저장한 글을 담는 MySQL 의 bookmarks 테이블에 새 항목을 넣으면 오류가 나기 시작했다. Instapaper 서비스는 2월 10일 목요일 7:30pm PT 까지 멈췄다.\n\nbookmarks 테이블은 2TB 파일 크기 한도를 넘었다. 2014년 4월 전에 만든 MySQL RDS 인스턴스는 파일 크기 한도가 2TB 인 ext3 파일 시스템을 쓴다. 그 뒤에 만든 인스턴스는 ext4 파일 시스템을 쓰고 한도가 6TB 다. Instapaper 의 인스턴스는 2015년 3월에 만들었지만 2013년 6월 인스턴스의 읽기 복제본으로 만들었기 때문에 같은 파일 시스템과 2TB 한도를 물려받았다.\n\nRDS 콘솔에는 2TB 한도에 다가가고 있다거나 애초에 그 한도가 적용된다는 것을 알려 주는 모니터링, 알림, 로그가 없었다. 글을 쓴 시점에도 데이터베이스에 심각한 문제가 있다는 표시는 없었다.\n\n10일치 자동 백업도 모두 파일 시스템 스냅샷이라 같은 2TB 한도에 묶여 있었다. 팀은 처음에 행 수를 보고 데이터베이스 덤프에 6~8시간이 걸린다고 어림했다. 하지만 첫 시도는 24시간, 병렬로 돌린 두 번째 시도는 10시간이 걸렸다. bookmarks 의 앞쪽 25 퍼센트 행이 전체 데이터의 10 퍼센트밖에 되지 않았기 때문이다."},"updated_at":"2026-11-14T12:33:58.833032Z","url":"https://benchlet.com/incidentlib/app/cases/IL-0334","org_slug":"instapaper"}