Incident Library
적용된 필터 구성 요소데이터베이스증상복제 지연조직GitLab모두 풀기검색어 없이 필터만 적용한 목록입니다. 최근 사례부터입니다.
추천 필터 검색하면 검색어에서 찾은 분류 값이 여기에 나옵니다.

그래프

  • 원인
  • 구성 요소
  • 증상
  • 기여 요인
  • 사례

사례2건

2건 중 1~2번째

  1. 증상

    2026-06-11 06:16 UTC 에 Pingdom 알림이 https://gitlab.com 의 HTTP 503 오류를 알렸다. 웹, 프런트엔드, API, git, 웹소켓, web-pages, CI 러너가 06:16~06:22 UTC 와 07:03~07:12 UTC 두 차례 503 을 냈다. 오류는 여러 서비스에 걸쳐 끊겼다 이어지기를 반복했고, 매번 5~10분 안에 저절로 회복했다.

    촉발

    us-east1-b 존의 GCP 스토리지 장애로 주 데이터베이스 노드가 쓰는 디스크의 스토리지 IO 성능이 떨어졌다.

    원인
    구성 요소
    기여 요인
    감지

    06:16:12 UTC 에 Pingdom 알림이 장애를 알렸다. 영향은 06:12 에 시작됐으므로 감지까지 약 4분이 걸렸다. 사용자에게 보이는 503 은 알림이 잡았지만, 먼저 나타난 신호인 디스크 IO 포화, pgBouncer 풀 포화, LWLock 경합에는 알림이 없었다.

    조치
    • 두 번째 구간이 데이터베이스와 연결 계층을 가리키자 07:11 UTC 에 데이터베이스 운영 tier2 로 장애를 에스컬레이션했다. 데이터베이스 전문가가 LWLock 경합, pg_wait_sampling_buffer_mapping 급증, 복제 지연을 깊이 진단했다.
    • 배포를 멈췄다.
    • 08:13 UTC 에 GCP TAM 에 연락하고 08:56 에 GCP 지원 케이스를 열었다. 클라우드 제공자가 스토리지 장애를 확인해 줬다.
    • 다시 나빠지면 바로 실행할 수 있게 us-east1-d 의 04 노드로 Patroni 주 노드 전환을 준비했다. 쓰기 처리량에 줄 영향도 따져 두었지만 실행하지는 않았다.
    • GCP 쪽 문제가 가라앉은 것으로 보이자 15:19 UTC 에 장애를 멈춰 두고 3시간 동안 지켜봤고, 재발이 없음을 확인한 뒤 해결로 처리했다.
    후속 조치
    • Patroni 주 데이터베이스 노드에 디스크 IO 포화와 큐 깊이 알림을 넣는다.
    • 명시적인 실행 기준을 담은 Patroni 주 노드 전환 런북을 쓴다.
    • 끊겼다 저절로 회복하는 장애에서 장애 상태를 언제 바꿀지 지침을 분명히 한다.
    • 디스크 IO 가 떨어지는 동안 자동으로 장애 조치했어야 했는지 검토한다.
    • Cells 는 장기적으로 영향 범위를 줄이도록 설계됐다. 그와 별도로 디스크 하나가 GitLab.com 전체를 멈추지 않도록 단기 완화책을 마련한다.
    • 주 노드가 응답하지 않을 때 애플리케이션의 데이터베이스 부하 분산이 요청을 덜어 내거나 다른 곳으로 보내, 요청이 60초 Rack 타임아웃까지 쌓이지 않고 빨리 실패하게 한다.
    • pgBouncer 풀 포화와 LWLock 경합이 전면 장애보다 먼저 튀었으므로, 이 둘을 먼저 나타나는 신호로 보고 알림을 걸지 검토한다.
    교훈

    디스크 하나가 나빠진 것만으로 GitLab.com 전체가 멈췄다. 데이터베이스 부하 분산이 빨리 실패하지 않아 요청이 60초 Rack 타임아웃까지 쌓였다. 빨리 실패하지 않는 문제는 이전 장애 #18269 에서 얻은 교훈과 겹쳤다. 장애 조치 기준이 미리 정해져 있지 않아 문제가 다시 날지 몰라 지켜보고 기다리는 데 많은 시간을 썼다. 클라우드 제공자 장애가 넓게 퍼진 상황이라 어느 존이 정상인지 미리 확인할 수도 없었다. 끊겼다 저절로 회복하는 장애에서는 장애 상태를 언제 Fixing 이나 Monitoring 으로 옮길지 정하기 어려웠다.

  2. 증상

    2017년 1월 31일 19:00 UTC 무렵 GitLab.com 의 데이터베이스 부하가 올랐고, 많은 사용자가 이슈와 머지 리퀘스트에 댓글을 달지 못했다. 스팸으로 의심되는 부하였고, 잡는 데 몇 시간이 걸렸다.

    촉발

    1월 31일 23:00 UTC 무렵 데이터베이스 부하로 세컨더리의 복제가 멈췄고, 세컨더리를 다시 맞추던 엔지니어가 세컨더리가 아니라 프라이머리에서 PostgreSQL 데이터 디렉터리를 지웠다.

    원인
    구성 요소
    기여 요인
    감지

    프라이머리에서 데이터 디렉터리를 지운 엔지니어가 스스로 실수를 알아채고 1~2초 만에 삭제를 멈췄다.

    조치
    • pg_basebackup 이 복제 연결이 모자라다고 알리자 max_wal_senders 를 기본값 3 에서 32 로 잠시 올렸고, PostgreSQL 이 재시작을 거부하자 max_connections 를 8000 에서 2000 으로 낮췄다.
    • 엔지니어가 프라이머리에서 데이터를 지우고 있다는 것을 알아채고 1~2초 만에 삭제 작업을 멈췄지만, 약 300 GB 가 이미 지워졌다.
    • 데이터 손실을 가장 줄일 수 있는 유일한 방법으로 장애 6시간 전에 만든 LVM 스냅샷을 쓰기로 하고, 스테이징의 PostgreSQL 데이터 디렉터리를 약 18시간 동안 운영으로 복사해 복원했다.
    • 웹훅 삭제를 거치지 않은 별도 스테이징 데이터베이스를 LVM 스냅샷으로 띄워 웹훅 테이블의 SQL 덤프를 만들고, 복원한 GitLab.com 데이터베이스에 가져왔다.
    • 장애 전에 쓰였을 수 있는 ID 를 다시 쓰지 않도록 모든 데이터베이스 시퀀스를 100,000 씩 올렸다.
    • GitLab.com 을 차례로 다시 열었다.
    • 17:20 UTC 이후에 만든 프로젝트는 NFS 클러스터에 남은 Git 저장소로 가장 기본적인 형태만 복원했고, 이슈와 머지 리퀘스트 같은 데이터는 되살리지 못했다.
    후속 조치
    • 모든 호스트의 셸 프롬프트인 PS1 을 고쳐 호스트와 환경을 더 분명히 구분한다.
    • 백업을 Prometheus 로 모니터링한다.
    • PostgreSQL 의 max_connections 를 알맞은 값으로 둔다.
    • PostgreSQL 의 시점 복구와 연속 아카이빙을 검토한다.
    • 운영 데이터베이스의 LVM 스냅샷을 매시간 뜬다.
    • 운영 데이터베이스에 Azure 디스크 스냅샷을 켠다.
    • 스테이징을 ARM 환경으로 옮긴다.
    • 운영 복제본을 되살린다.
    • PostgreSQL 백업 복원을 자동으로 시험한다.
    • PostgreSQL 복제 문서와 런북을 고친다.
    • PostgreSQL 백업에 pgbarman 을 쓸지 검토한다.
    • 데이터베이스 백업과 실시간 복제에 WAL-E 를 쓸지 검토한다.
    • 스트리밍 방식의 데이터베이스 복원을 만든다.
    • 데이터 내구성을 책임질 담당자를 정한다.
    • 세컨더리를 여러 대 두고 부하를 나누도록 pgpool-II 3.6.1 을 묶고 PostgreSQL 연결 풀링과 부하 분산을 구성한다.
    • 개발자가 데이터베이스 마이그레이션을 시험할 수 있도록 스테이징에서 Rails 마이그레이션을 실행하고 되돌리는 도구를 만든다.
    • 데이터베이스뿐 아니라 GitLab.com 인프라 전체의 복구 절차를 만들고 그 절차의 담당자를 정한다.
    • 공개 백업 모니터링 대시보드를 만들었고, 지금은 pg_dump 백업 데이터만 있지만 데이터를 더 넣는다.
    • 어뷰징 신고와 대응 시스템을 고쳐 스팸 신고로 사용자를 지울 때 데이터를 바로 영구 삭제하지 않게 한다.
    • 앞으로 공개하는 장애 문서에서는 엔지니어의 이름을 가린다.
    교훈

    GitLab 은 장애를 GitLab.com 이 약 18시간 멈춘 문제와 복원이 18시간 넘게 걸린 문제로 나눠 5 Whys 로 분석했다. 세컨더리를 다시 만드는 작업은 자동화되지도 제대로 문서화되지도 않아 손으로 해야 했다. 표준 백업은 PostgreSQL 버전이 맞지 않아 조용히 실패했고, 실패 알림 메일은 DMARC 서명이 없어 거부됐다. 다른 백업 절차를 믿고 Azure 디스크 스냅샷을 켜지 않았다. 백업 절차를 맡은 사람이 없어 아무도 정기적으로 시험하지 않았다. GitLab 은 운영 엔지니어가 특정 명령을 못 쓰게 막는 것보다 재해 복구를 고치고 지금 어느 호스트를 쓰는지 더 분명히 보이게 하는 데 집중하기로 했다. rm 을 더 안전한 별칭으로 바꾸면 실수로 지우는 것은 막지만 디스크 손상처럼 데이터를 잃는 다른 경우는 막지 못한다. 이상적인 환경은 실수해도 영향이 거의 없이 빠르게 복구할 수 있는 곳이고, 그러려면 복구 절차를 정기적으로 해 보고 변경을 쉽게 시험하고 되돌릴 수 있어야 한다.

내 클러스터에도 있는지 확인하기

이 2건에서 가장 많이 나오는 구성 요소: 클라우드 블록 스토리지, 데이터베이스. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.

원인별2