17/10/2026 · VietTechies · Biên tập

Tối muộn ngày 31 tháng 1 năm 2017, trong lúc tìm cách sửa lại cơ chế nhân bản cơ sở dữ liệu (replication), một kỹ sư GitLab đã xóa sạch thư mục dữ liệu trên server PostgreSQL chính của GitLab.com. Anh tưởng mình đang thao tác trên server phụ. Chỉ trong vài giây, anh nhận ra mình nhầm và dừng lệnh lại. Nhưng đến lúc đó, theo lời GitLab, “trong khoảng 300 GB, chỉ còn lại chừng 4,5 GB”.
Khi cả nhóm đi tìm một bản sao để khôi phục, hóa ra các bản sao lưu cơ sở dữ liệu không thấy đâu, tính năng chụp nhanh ổ đĩa (snapshot) chưa được bật cho các server cơ sở dữ liệu, còn bản snapshot định kỳ hằng ngày thì đã cũ gần một ngày. Trong đêm đầu tiên, các kỹ sư GitLab viết rằng “trong năm kỹ thuật sao lưu/nhân bản đã triển khai, không kỹ thuật nào chạy ổn định, hoặc ngay từ đầu đã không được thiết lập”.
Bản sao giúp GitLab.com hoạt động trở lại vốn không được tạo ra để sao lưu. Khoảng sáu tiếng trước sự cố, chính người kỹ sư ấy đã tự tay tạo một snapshot cơ sở dữ liệu, vì anh đang làm về cân bằng tải và muốn có một bản sao mới nhất trên môi trường staging để thử nghiệm.
Server bị xóa nhầm như thế nào
Rắc rối bắt đầu từ tối hôm đó, khi tải trên cơ sở dữ liệu tăng vọt. Theo báo cáo phân tích sự cố (postmortem) của GitLab, đợt tăng tải này bắt nguồn từ hai chuyện xảy ra cùng lúc: spam, và một tiến trình đang xóa tài khoản cùng dữ liệu của một nhân viên GitLab. Tài khoản này đã bị đánh dấu là có hành vi lạm dụng và bị đưa vào lịch xóa do nhầm lẫn. Bản báo cáo sự cố đầu tiên của GitLab viết rằng những kẻ spam đang “nã dồn dập vào cơ sở dữ liệu bằng cách tạo các đoạn code ngắn (snippet)”. Các thao tác ghi vào cơ sở dữ liệu bị treo cứng một thời gian. Sau đó, server phụ — một bản sao của cơ sở dữ liệu, luôn sẵn sàng tiếp quản nếu server chính gặp sự cố — không theo kịp lượng ghi tăng vọt và tụt lại xa đến mức quá trình nhân bản coi như đã dừng.
Muốn dựng lại cơ chế nhân bản, nhóm xóa thư mục dữ liệu của server phụ để server này chép lại một bản mới từ server chính. Server phụ không chịu kết nối. Sau khi nhóm thay đổi cấu hình trên server chính, server phụ cứ thế treo cứng. “Đến lúc này, sự bực bội bắt đầu dâng lên”, bản báo cáo sự cố đầu tiên viết.
Khoảng 23 giờ UTC (Giờ Phối hợp Quốc tế), người kỹ sư nghi rằng pg_basebackup — công cụ của PostgreSQL dùng để chép một cơ sở dữ liệu đang chạy nhằm khởi tạo một bản sao — không chịu chạy vì thư mục dữ liệu trống vẫn còn đó. Anh quyết định xóa thư mục này trên db2.cluster.gitlab.com, tức server phụ. Nhưng anh lại chạy lệnh trên db1.cluster.gitlab.com, tức server chính.
Từng cơ chế sao lưu thực sự đã làm được gì
Bản postmortem mà GitLab công bố mười ngày sau đó lần lượt xem xét bốn quy trình.
- Bản dump cơ sở dữ liệu. Một tác vụ chạy theo lịch (cronjob) lẽ ra phải dùng pg_dump, công cụ xuất dữ liệu của PostgreSQL, để xuất cơ sở dữ liệu rồi tải lên dịch vụ lưu trữ S3 của Amazon. Tác vụ này dùng pg_dump 9.2 cho một cơ sở dữ liệu chạy PostgreSQL 9.6, và việc sao lưu thất bại. “Bucket S3 trống rỗng, và không tìm thấy bản sao lưu gần đây nào ở bất cứ đâu.” Email báo lỗi của tác vụ bị server nhận thư từ chối, vì DMARC — một chuẩn xác thực email — “không được bật cho các email của cronjob”, nên các cảnh báo không bao giờ đến được với nhóm.
- Snapshot ổ đĩa. GitLab có dùng tính năng snapshot ổ đĩa của Azure cho các server lưu file, nhưng “các snapshot này không được bật cho bất kỳ server cơ sở dữ liệu nào”, vì nhóm cho rằng các quy trình sao lưu khác là đủ.
- Nhân bản cơ sở dữ liệu. Dữ liệu trên server phụ đã bị xóa từ trước, trong lúc nhóm tìm cách sửa lỗi. Cơ chế nhân bản “chủ yếu được dùng cho mục đích chuyển đổi dự phòng (failover), chứ không dùng để khôi phục sau thảm họa”.
- Snapshot LVM hằng ngày. GitLab dùng LVM, công cụ quản lý ổ đĩa logic trên Linux, để mỗi ngày tạo một snapshot và chép dữ liệu production sang môi trường staging. Quy trình này chạy đúng như dự định, nhưng các snapshot ấy “không thực sự dành cho việc khôi phục sau thảm họa”, và bản snapshot định kỳ khi đó đã cũ gần 24 tiếng.
Bản sao mới nhất là snapshot LVM mà người kỹ sư tự tay tạo khoảng sáu tiếng trước đó, đang nằm trên môi trường staging. Việc chép ngược bản snapshot này về hệ thống thật (production) “mất khoảng 18 tiếng”. Điểm nghẽn nằm ở các ổ đĩa của môi trường staging: những ổ đĩa này chạy trên dịch vụ lưu trữ Azure classic không có Premium Storage, và bị giới hạn tốc độ ở mức “khoảng 60Mbps”. GitLab.com ngừng hoạt động khoảng 18 tiếng.
Những gì bị mất, những gì còn nguyên
Lần khôi phục đưa cơ sở dữ liệu về đúng trạng thái lúc snapshot được tạo. Những thay đổi trong khoảng sáu tiếng sau đó — dự án mới, bình luận, tài khoản người dùng, issue và snippet — đều bị mất. Theo GitLab, “ước tính sát nhất là sự cố đã ảnh hưởng đến khoảng 5.000 dự án, 5.000 bình luận và 700 tài khoản người dùng mới”. Các kho Git và wiki, vốn được lưu riêng, không bị đợt mất dữ liệu này ảnh hưởng.
Một số bản kể lại khiến thiệt hại nghe nặng nề hơn thực tế. Một bài đăng năm 2023 trên DEV Community, trang dành cho lập trình viên, viết rằng vụ xóa đã khiến “GitLab.com không còn chút dữ liệu nào”. Ghi chép của chính GitLab cho thấy phần bị mất là khoảng sáu tiếng thay đổi trong cơ sở dữ liệu, GitLab.com ngừng hoạt động khoảng 18 tiếng, còn các kho Git không bị ảnh hưởng.
GitLab xử lý sự cố công khai ra sao
GitLab ghi chép quá trình khắc phục sự cố trên một tài liệu Google Docs công khai, và phát trực tiếp việc khôi phục trên YouTube. Buổi phát trực tiếp này từng là “buổi livestream đứng thứ 2 trên YouTube trong vài tiếng”, với “lượng người xem cao nhất vào khoảng 5.000”.
Bản postmortem không nêu tên người kỹ sư. Còn tài liệu Google Docs cập nhật trực tiếp thì có nêu tên, và GitLab viết rằng công ty sẽ “ẩn tên trong những trường hợp sau này, vì các kỹ sư khác có thể không thoải mái khi tên mình bị công bố”. Vị CEO của GitLab viết: “Cá nhân tôi, với tư cách CEO của GitLab, và thay mặt mọi người tại GitLab, xin gửi lời xin lỗi.”
Những gì GitLab tìm ra và thay đổi
Phần phân tích nguyên nhân gốc rễ trong bản postmortem chỉ ra vấn đề nằm ở quy trình, chứ không nằm ở con người: “Vì không có ai phụ trách, nên kết quả là không ai chịu trách nhiệm kiểm thử quy trình này.” Sau sự cố, snapshot LVM được tạo mỗi giờ một lần thay vì mỗi ngày một lần. Bản postmortem liệt kê 15 đầu việc cần làm tiếp, trong đó có kiểm thử khôi phục tự động, một người phụ trách độ bền dữ liệu (data durability), và việc đổi dấu nhắc lệnh trên mọi máy chủ để dễ phân biệt các máy chủ và môi trường với nhau. GitLab cho biết trọng tâm chính là “cải thiện khả năng khôi phục sau thảm họa, và giúp bạn thấy rõ hơn mình đang dùng máy chủ nào; thay vì ngăn các kỹ sư vận hành production chạy một số lệnh nhất định”.
Vì sao các bản sao lưu hỏng mà không ai hay biết
Tấm lưới an toàn nào cũng thủng theo một kiểu riêng, nhưng các lỗ thủng có chung một điểm. Tác vụ dump không tạo ra được gì, còn email cảnh báo của tác vụ thì bị trả lại. Snapshot ổ đĩa chưa được bật cho các server cơ sở dữ liệu. Không ai phụ trách các bản sao lưu, nên cũng không ai có trách nhiệm kiểm thử chúng, và các lỗ thủng cứ thế nằm khuất cho đến cái đêm cần khôi phục.
Bản sao lưu không ai phụ trách là bản sao lưu không ai kiểm thử.
Rốt cuộc, GitLab.com hoạt động trở lại nhờ một bản sao mà chính người kỹ sư ấy tạo ra để kiểm thử tải, khoảng sáu tiếng trước cái lệnh anh đã dừng lại chỉ trong vài giây. Còn bucket S3, nơi lẽ ra phải chứa các bản sao lưu cơ sở dữ liệu, thì trống rỗng.
Bài liên quan
Đọc bằng ngôn ngữ khác: English
Nguồn
- GitLab, “Postmortem of database outage of January 31,” ngày 10 tháng 2 năm 2017
- GitLab, “GitLab.com Database Incident,” ngày 1 tháng 2 năm 2017
- Simon Sharwood, “GitLab.com melts down after wrong directory deleted, backups fail,” The Register, ngày 1 tháng 2 năm 2017
- Graham Cluley, “GitLab down after it deletes wrong directory and backups stumble,” ngày 1 tháng 2 năm 2017
- Kanani Nirav, “Dev Deletes Entire Production Database,” DEV Community, năm 2023
- Ảnh đại diện (ảnh minh họa: các server của Wikimedia Foundation, không phải của GitLab): “Wikimedia Foundation Servers-8055 35”, tác giả Victor Grigas, qua Wikimedia Commons, CC BY-SA 3.0
