Облак и експлоатация15 мин

Пет техники за резервно копиране и нито една надеждна: нощта, в която GitLab изтри базата си данни

От · основател и главен изпълнителен директор на Hábil ·

През 2017 г. изтриване по грешка в GitLab.com разкри, че резервните копия не работят. Историята, какво промениха и как да видите дали вашите се възстановяват.

Да имате резервни копия не е същото като да можете да възстановите. Разликата се вижда едва в деня, в който потрябва, а тогава вече е късно да я откривате. През януари 2017 г. една облачна услуга за хостване на код го откри на живо, пред погледа на хиляди хора.

Едно уточнение, преди да започнем: Hábil не е участвала в този случай. Разказваме го с онова, което GitLab е публикувала в публичния си постмортем, и с онова, което е отразила специализираната преса.

Вторник, малко след единайсет вечерта

Датата е 31 януари 2017 г. GitLab.com, облачната услуга, в която софтуерните екипи пазят кода си, задачите си и прегледите си, от часове има проблеми. От следобеда основната база данни е под необичайно натоварване. Екипът подозира спам. Потребителите не могат да публикуват коментари [1][2].

Зад това натоварване стои съвпадение, което никой не е предвидил. Освен спама, по грешка е бил насрочен процес за изтриване на данните на служител на самата компания, задействан от сигнал за злоупотреба [1]. Двете неща заедно притискат базата.

Към единайсет вечерта (по UTC) натискът води до по-сериозна последица. Основната база има реплика: второ копие, което се поддържа актуално, като получава всяка промяна, готово да заеме мястото на първото, ако то откаже. При натоварването репликата изостава. А когато се опитва да навакса, промените, които са ѝ нужни, вече ги няма: основната база ги е изхвърлила, преди репликата да ги получи [1].

Автоматичен изход от това положение няма. Репликата трябва да се изгради наново на ръка [1].

Един инженер се захваща с това. Изтрива директорията с данни на репликата, за да я копира отново от основната. Пуска инструмента, който прави това копие, и инструментът не отговаря. Изглежда увиснал. Променя параметри. Базата отказва да се рестартира. Променя други [1].

Онова, което в този момент никой не знае, е, че инструментът не е увиснал: чака безмълвно основната база да започне да изпраща данни, нещо, което може да отнеме няколко минути. Това поведение го нямаше нито в процедурите на екипа, нито в официалната документация [1][2].

В Нидерландия, където работи инженерът, е нощ [4]. Проблемът продължава от часове. Той смята, че неуспешното копиране е оставило боклук в директорията на репликата, и решава да я почисти отново.

Написва командата за изтриване. Изпълнява я.

Секунда-две по-късно осъзнава: не е в репликата. В основната база е [1][2].

Спира я. Но командата за изтриване не пита и не може да бъде отменена. От около 300 GB данни остават около 4,5 GB [2][4].

Търсенето

В този момент всички си задават един и същ въпрос: от какво да възстановим?

GitLab не беше импровизирана компания. На хартия имаше няколко пласта защита. Екипът започва да ги проверява един по един и ги записва в документ на Google, който прави публичен, за да може всеки да следи напредъка [1][3].

Ежедневното резервно копие в облака. На всеки 24 часа една планирана задача трябваше да прави пълен дъмп на базата и да го съхранява в хранилище на Amazon (S3). Екипът отваря хранилището. Празно е [1][2][4].

Защо? Задачата пускаше инструмента за дъмп във версия 9.2 срещу база във версия 9.6. Инструментът избираше версията си според директорията с данни на сървъра, на който работеше, а тази задача работеше на сървър за приложения, който нямаше директория с данни. Затова вземаше старата версия и се проваляше [1].

Проваляше се всеки ден. И никой ли не разбираше? Задачата наистина изпращаше имейл, когато се провали. Но тези имейли биваха отхвърляни: получаващият сървър ги връщаше, защото за имейлите на планираните задачи не беше включен DMARC — механизъм, с който пощенските сървъри проверяват дали едно съобщение е легитимно [1][5]. Алармата съществуваше. Така и не стигна до никого.

Снимките на дисковете в облака. Тогава GitLab работеше върху Microsoft Azure, който може периодично да прави снимки на цял диск. Те бяха включени за файловите сървъри, но не и за сървърите на базата данни: екипът беше приел, че другите резервни копия са достатъчни [1].

Репликата. Тя е първото, за което всеки би се сетил. Но репликата не е резервно копие: копира всичко, включително грешките, и служи да поеме щафетата от паднал сървър, не да се върнете назад във времето. Освен това в този случай тя вече не съществуваше: директорията ѝ беше изтрита минути по-рано, като част от изграждането наново [1].

Снимките на сървъра. Оставаше един последен пласт: снимки на диска, правени с LVM, мениджъра на логически томове на системата. Правеха се на всеки 24 часа, и то не като резервно копие, а за да се копират реалните данни в тестова среда (staging). Последната планирана беше отпреди почти един ден [1].

Същата нощ публичният документ, който броеше поотделно ежедневните дъмпове и копието им в S3, обобщи положението с изречение, което обиколи интернет:

«От пет внедрени техники за резервно копиране и репликация нито една не работи надеждно или изобщо не е била настроена.» (собствен превод) [2][4]

Шест часа късмет

И тогава се появява единствената добра новина за нощта, и тя е почти случайност.

Същия ден, около 17:20 UTC, един инженер беше направил на ръка снимка на базата, за да я зареди в тестовата среда. Направил я беше, за да има свежи данни за тестовете на инструмент за разпределяне на натоварването на базата данни [1]. Това копие, направено за друго, сега беше единственото отпреди шест часа, а не отпреди двайсет и четири.

Екипът избира това копие. Алтернативата беше да се загуби почти цял ден [1].

Остава то да бъде върнато обратно. И тук излиза наяве друго решение, взето отдавна и по добри причини. Тестовата среда работеше на евтини дискове в Azure, без високопроизводително хранилище, за да се пестят разходи. Тези дискове бяха ограничени до около 60 Mbps. Копирането на данните от тестовата среда към основния сървър отне около 18 часа. Тясното място не беше нито мрежата, нито процесорът: бяха дисковете [1].

Осемнайсет часа копиране, с GitLab.com извън строя.

Възстановяването, на живо

Онова, което GitLab направи през тези часове, е другата половина на тази история, и именно тя я отличава.

Вместо да затвори вратата и накрая да публикува сухо съобщение, компанията разказваше публично какво се случва, докато се възстановяваше. Профилът ѝ за състоянието на услугата в Twitter го каза без заобикалки: «По погрешка изтрихме данни от продукционната среда и може да се наложи да възстановим от резервно копие» (собствен превод) [1][2]. Работният документ, с бележките на екипа и списъка на онова, което се беше провалило, остана пред очите на всички [1][3]. А възстановяването се излъчваше в YouTube. В един момент имаше около 5000 зрители едновременно и в продължение на няколко часа беше второто най-гледано предаване на живо в платформата [1].

На 1 февруари, около 17:00 UTC, базата беше възстановена, все още без webhooks (автоматичните известия, които GitLab изпраща към други системи, когато нещо се промени). Към шест вечерта услугата отново работеше, с приключени последни стъпки [1][2]. Общо GitLab.com беше недостъпен около 18 часа [1].

Екипът внимаваше за подробности, които се забелязват само когато някой вече е минал по този път. Възстанови webhooks, като вдигна отделна база от същата снимка, без стъпката, която ги изтрива при копирането на данните към тестовата среда, и оттам ги прехвърли в основната база. Увеличи с 100 000 всички броячи на идентификатори в базата, така че нито един номер, използван в изгубените часове, да не бъде даден отново на нещо друго. И тъй като кодът на хранилищата не живее в базата данни, а отделно, на файлови сървъри, които не бяха изтрити, пресъздаде оттам, в основния им вид, проектите, създадени след 17:20, макар и без задачите и прегледите им [1].

Колко се загуби

Загубиха се промените в базата, направени за около шест часа: между 17:20 UTC и полунощ на 31 януари, според постмортема, който на друго място посочва края около 23:30 [1][2]. Най-добрата им оценка: засегнати са около 5000 проекта, 5000 коментара и 700 нови потребителски акаунта [1].

Онова, което не се загуби, също има значение. Кодът и уикитата в GitLab.com бяха недостъпни по време на срива, но не се загубиха. Компаниите, които имаха GitLab, инсталиран на собствените им сървъри, не бяха засегнати [1][2][4].

Десет дни по-късно, на 10 февруари, GitLab публикува пълен постмортем: хронологията час по час, всеки механизъм, който се провали, и защо, и публичен списък със задачи за поправянето, всяка със свой номер за проследяване [1]. Започваше с пряко извинение: «На потребителите на GitLab.com, чиито данни загубихме, и на хората, засегнати от срива: съжаляваме» (собствен превод) [1].

Какво учи този случай

Лесно е тази история да се прочете като историята на инженер, който е сбъркал прозореца. Това би бил грешният прочит. Самият постмортем на GitLab не спира дотам: пита защо една-единствена грешка е могла да струва толкова, а отговорът има малко общо с този човек.

1. Резервно копие, което никой не е възстановявал, е предположение

GitLab имаше задачи за резервно копиране, облачно хранилище, снимки и реплика. На архитектурна диаграма това изглежда солидно. Липсваше му доказателството, че някой от тези механизми връща работеща база.

Постмортемът го казва в един ред, без украшения: «Тъй като нямаше собственик, никой не отговаряше за тестването на тази процедура» (собствен превод) [1].

Обърнете внимание какво означава това за едно ръководство. Никой не е изключвал резервните копия. Никой не е решавал да поема рискове. Ежедневното копие се проваляше безшумно заради разлика във версиите, която никой не виждаше, и предупреждаваше по канал, до който нищо не стигаше. Единственият начин това да се открие по-рано беше да се опита възстановяване. А тъй като тази задача не беше на никого, никой не я свърши.

2. Репликата пази от срив, не от грешка

Тази точка обърква дори опитни екипи. Репликата е предназначена услугата да продължи, ако някой сървър падне. В зависимост от настройката си тя може да изостава, както тази на GitLab онази нощ. А ако някой изтрие данни или някое приложение запише боклук, репликата копира и изтриването, и боклука със същото усърдие. За да се върнете към по-ранен момент, е нужно друго: резервно копие, което пази историята, или журнал на промените, който позволява базата да се възстанови до определена минута.

Постмортемът ги разграничава ясно: репликата беше, за да поеме щафетата от сървъра, не за възстановяване след бедствие [1].

3. Онова, което се прави на ръка, в неработно време, няма предпазна мрежа

Изграждането наново на репликата не беше нито автоматизирано, нито добре документирано. GitLab го признава: процедурата беше ръчна, опираше се на импровизирани скриптове, а документацията беше оскъдна [1][2]. Един инженер посред нощ, след часове инцидент, трябваше да помни всяка стъпка, да различава два сървъра с почти еднакви имена (db1 и db2) и да гадае дали един безмълвен инструмент е увиснал или работи.

При такива условия рискът от грешка расте много. Всъщност първата задача от списъка на GitLab беше да стане по-очевидно на кой сървър и в коя среда се намира всеки, когато пише команда [1].

4. Решенията за икономия се плащат в деня на бедствието

Снимките в Azure не бяха включени за базите, защото се смяташе, че другите резервни копия са достатъчни. Тестовата среда имаше бавни дискове, защото така излизаше по-евтино [1]. Всяко решение поотделно беше разумно. Заедно, и в добавка към изгубената реплика, към провалящото се ежедневно копие и към отхвърлените аларми, те допринесоха грешка от две секунди да завърши с възстановяване от около 18 часа.

Няма нищо лошо в това да се пести. Онова, което почти винаги липсва, е някой да запише последицата до решението: «с тези дискове възстановяването отнема толкова часа; приемаме ли го?». Ако този въпрос се зададе предварително, се взема решение. Ако се открие в деня на бедствието, само се изтърпява.

5. Онова, което GitLab направи добре, също е част от урока

Би било несправедливо тази история да се разкаже, без да се каже ясно и докрай: GitLab управлява кризата с прозрачност, каквато малко компании се осмеляват да имат. Разказваше публично по време на възстановяването, отвори работните си бележки, излъчи възстановяването, извини се без заобикалки и публикува анализ, който назовава всяка собствена грешка [1].

И се поучи от собствената си прозрачност. Публичният документ в един момент показваше името на замесения инженер; в постмортема GitLab обяви, че занапред ще пропуска имената, защото други инженери може да не се чувстват комфортно те да бъдат публикувани [1]. Анализът сочи процесите, не човека.

Тази нагласа не е само добър имидж. Компания, която може да каже публично «това се провали и ето защо», е компания, която може да го поправи. Прозрачността не премахва риска, но позволява грешките да се разгледат и да се възложат конкретни подобрения.

Какво планираха и какво вече бяха променили

Постмортемът публикува списък с отворени задачи, всяка с публичен номер. Сред тях [1]:

  • Да стане видимо в командния ред на кой сървър и в коя среда се работи.
  • Да се наблюдават резервните копия, така че провалено копие да не остане незабелязано.
  • Да се правят снимки на базата на всеки час вместо всеки ден и да се включат снимките на дисковете за базите.
  • Да се проучат възстановяването до момент във времето и непрекъснатото архивиране на промените в базата.
  • Да се тества автоматизирано, че резервните копия могат да бъдат възстановени.
  • Да се подобрят документацията и процедурите за репликацията.
  • Да се определи собственик на трайността на данните (човек, който отговаря те да се пазят цели и да могат да се възстановят).
  • Да се подготви възстановяване след бедствие и за всичко, което не е базата данни.
  • Изтриването на потребител заради спам да не го премахва окончателно.

Когато публикува постмортема, GitLab вече правеше снимките с LVM на всеки час и беше започнал да изгражда публично табло за състоянието на резервните копия; снимките на дисковете в Azure за базите още се оценяваха [1]. Според InfoQ, в двете седмици след инцидента GitLab започна да архивира в реално време промените в базата в хранилище на Amazon, а едно тестово възстановяване до момент във времето отне малко под два часа [5]. Месеци по-късно екипът организираше дни, посветени на възстановяването на резервните му копия — основната база, други бази и снимка на диск, — за да провери, че те наистина пазят данните [6][7]. През юни 2017 г. тези възстановявания все още бяха ръчни, а автоматизацията беше в списъка с предстоящи задачи [6]. Промяната на един навик отнема време, дори след такава уплаха.

Постмортемът обобщава духа на промяната в изречение, което важи за всяка операция: «Идеалната среда е тази, в която можете да правите грешки, но лесно и бързо да се възстановявате от тях, с минимално или никакво въздействие» (собствен превод) [1]. Не става дума да се забраняват команди. Става дума грешката да не струва 18 часа.

Какво означава това за вашата компания

Вие вероятно не управлявате глобална платформа като GitLab.com. Но моделът от тази история се появява в компании от всякакъв размер, и почти винаги със същите съставки:

  • Инфраструктура, сглобена на ръка. Сървъри, мрежи и планирани задачи, които някой е настроил веднъж, които работят и които никой не смее да пипне. Никой не знае със сигурност какво има в тях, защото не е записано никъде.
  • Резервни копия, които се планират, но не се възстановяват. Има задача, която «прави резервното копие», и отчет, който казва, че е минала. Никой не се е опитвал да вдигне цяла база от този файл.
  • Аларми, които не стигат до никого. Имейли към пощенски кутии, които никой не чете или които ги отхвърлят, както в GitLab.
  • Процедури, които живеят в паметта на един човек. Работят, докато този човек е тук, отпочинал и на разположение.
  • Икономии без записана последица. По-бавни дискове, по-редки копия, по-малко среди — всичко това, без някой да е изчислил колко би отнело възстановяването при тези решения.

Разликата между нощ като тази на GitLab и едночасова уплаха не е в повече инструменти. Тя е в три практики, които могат да се проверят:

Инфраструктурата, записана като код. Когато всеки сървър, мрежа, право на достъп и планирана задача е описан във файлове, които се съхраняват и преглеждат като всяка промяна в софтуера, конфигурациите остават видими и проверими. Ако задача за резервно копиране работи на грешния сървър, като тази на GitLab, грешката може да се забележи при преглед, вместо да остане скрита в някоя машина. А ако е съпроводено с преглед и тестове, това описание улеснява последователното възстановяване на онова, което се загуби.

Доказателствата за всяка промяна. Кой какво е променил, кога и защо, записано, без да зависи от ничия памет. Когато нещо се счупи, тази история е първото, което се проверява.

Отрепетираните възстановявания. Едно резервно копие струва толкова, колкото последното му успешно възстановяване. Репетира се по график, измерва се колко отнема и се сравнява с онова, което бизнесът е приел да загуби и да чака. Ако никой не е възстановявал от месеци, онова, което имате, не е проверено резервно копие: то е предположение.

Пет въпроса за следващия ви комитет

  1. Кога за последен път възстановихме цяла база от резервно копие в отделна среда и тя заработи? Ако отговорът е «никога» или «не знам», там е първият ви риск.
  2. Колко би отнело това възстановяване, измерено, а не оценено, и колко часа данни бихме загубили?
  3. Кой е собственикът на това резервните копия да работят? Име, не отдел.
  4. Ако утре задачата за резервно копиране се провали, кой ще разбере и как? Тази аларма тествана ли е вече?
  5. Бихме ли могли да вдигнем инфраструктурата си отново по същия начин, ако загубим сървъра, или това зависи от онова, което помни един човек?

Ако два или повече отговора са «не знам», резервните ви копия не са проверени.

Откъде да започнете тази седмица

Не е нужен проект, за да направите първата крачка. Изберете най-важната си база данни и поискайте от екипа си едно- единствено нещо: да възстанови най-новото резервно копие в отделна среда, да измери колко отнема и да провери, че приложението работи върху него. Запишете резултата, датата и кой го е направил. Ако проработи, вече имате първото си доказателство. Ако не проработи, току-що открихте в един спокоен вторник онова, което GitLab откри в полунощ.

Често задавани въпроси

Брои ли се репликата на базата данни за резервно копие?

Не непременно. Репликата може да помогне услугата да продължи, ако някой сървър падне, но копира и изтриванията, и грешките. За да се върнете към по-ранен момент, е нужно резервно копие, което пази историята, или механизъм за възстановяване до момент във времето.

Колко често е добре да се репетира възстановяване?

Зависи от това колко се променят данните ви и какво може да понесе бизнесът ви. Важното е да има дата в календара и собственик, и да се повтаря и след големи промени, като обновяване на версията на базата. В GitLab именно разлика във версиите счупи ежедневното резервно копие [1].

Какво е «инфраструктура като код» и защо помага за резервните копия?

Това е описването на сървъри, мрежи, права на достъп и планирани задачи във файлове, които се съхраняват и преглеждат като всеки софтуер, вместо да се настройват на ръка. Помага, защото записаното може да се прегледа, сравни и вдигне отново по същия начин. Данните не пътуват в този код: пътуват с резервните ви копия, които се репетират отделно.

Щяха ли повече резервни копия да ни защитят?

Не непременно. GitLab имаше няколко пласта и нито един не работеше надеждно онази нощ; базата се спаси с копие, направено на ръка за друго [1][2]. Редовните репетиции на възстановяване щяха да помогнат да се открие по-рано, че някои пластове не могат да бъдат възстановени и че алармите не стигат до никого.

Какво стана с инженера?

Постмортемът не го обвинява. Анализира защо една човешка грешка, която в някакъв момент щеше да се случи, е могла да има такава цена, и обявява, че при бъдещи инциденти ще пропуска имената на замесените хора [1].

Данни за колко време загуби GitLab?

Около шест часа промени в базата данни, според самия постмортем. Кодът и уикитата не се загубиха [1].

Какво прави Hábil

Hábil е мексиканска инженерна консултантска компания, основана през 2006 г. В Изграждане на инфраструктура проектираме заедно с вас основата, върху която работят системите ви, изграждаме я и ви я предаваме работеща, документирана и записана като код — във вашия облак, във вашия център за данни или и в двете. Когато случаят ви го изисква, това включва резервни копия, които се възстановяват, и план за възстановяване с договорени и тествани срокове. Екипът ви получава кода и документацията, за да я експлоатира и да я вдига отново по същия начин, без да зависи от нас. Вижте страницата Изграждане на инфраструктура.

Първият разговор е безплатен: започва от това какво имате изградено днес, как се прави резервното му копие и кога за последен път някой го е възстановил. Пишете ни в WhatsApp.

Фактите, часовете и цифрите са тези, които публикуваха GitLab и цитираната преса; не са наши измервания. Цитатите са преведени от английски (собствен превод). Часовете са по UTC, както ги публикува GitLab. Източниците са консултирани на 20 октомври 2026 г.

Източници

  1. GitLab, «Postmortem of database outage of January 31», блог на GitLab, 10 февруари 2017 г. https://about.gitlab.com/blog/2017/02/10/postmortem-of-database-outage-of-january-31/
  2. GitLab, «GitLab.com Database Incident», блог на GitLab, 1 февруари 2017 г. (съобщение за инцидента със списъка на проблемите от документа на живо и актуализацията от 18:14 UTC). https://about.gitlab.com/blog/2017/02/01/gitlab-dot-com-database-incident/
  3. GitLab, публичен документ за възстановяването, «GitLab.com Database Incident - 2017/01/31» (Google Docs, 31 януари и 1 февруари 2017 г.; днес е свален, съдържанието му е възпроизведено в [2] и цитирано в [4]). https://docs.google.com/document/d/1GCK53YDcBWQveod9kfzW-VCxIABGiryG7_z_6jHdVik/pub
  4. Simon Sharwood, «GitLab.com melts down after wrong directory deleted, backups fail», The Register, 1 февруари 2017 г. https://www.theregister.com/2017/02/01/gitlab_data_loss/
  5. David Iffland, «GitLab.com Postmortem Digs into Root Causes of 18 Hour Outage», InfoQ, 21 февруари 2017 г. https://www.infoq.com/news/2017/02/gitlab-outage-postmortem
  6. GitLab, issue #1916 «Backup Appreciation Day 2017-06-02», проект за продукционно инженерство, юни 2017 г. https://gitlab.com/gitlab-com/gl-infra/production-engineering/-/issues/1916
  7. GitLab, issue #2671 «Backup Appreciation Day 2017-08-31», проект за продукционно инженерство, август 2017 г. https://gitlab.com/gitlab-com/gl-infra/production-engineering/-/issues/2671