V agentuře, kde jsem vedl vývoj, běží git server. Leží na něm firemní znalostní báze a další repozitáře. Zálohoval se denně, lokálně i do off-site kopie na jiném místě. Na začátku září jsem si udělal test obnovy. Byl součástí zavedení off-site záloh a vycházel z jednoduché úvahy: „záloha běží” a „záloha je obnovitelná” jsou dvě různá tvrzení a to druhé se dá ověřit jen jedním způsobem.
Proč čistý server a proč jen pro čtení
Kontext: v agentuře se zálohuje 21 serverů přes Borg a každá záloha má druhou, nezávislou off-site kopii. Nad tím běží 45 uptime monitorů a alerting, který jsem zredukoval z 200 až 300 zpráv denně na „jen průšvihy”. Na papíře je to slušná ochrana. Právě proto jsem chtěl vědět, jestli platí i mimo papír.
Test obnovy dělám na prázdném stroji. Pronajal jsem si na hodinu nový VPS vedle úložiště se zálohami a na něm postavil všechno od nuly: balíčky, aplikaci, databázi, data. Obnova na stroji, kde už něco běží, nic nedokazuje, protože se opře o to, co tam zbylo.
K zálohám přistupoval účet jen pro čtení. Obnova nesmí mít možnost poškodit to, co obnovuje. Stojí to jeden parametr navíc, protože Borg si i pro čtení bere zámek repozitáře a účet bez práva zápisu ho nezaloží. Vylučuje to ale, že test zálohu rozbije.
První běh: databáze ano, data ne
Rozbalení archivu trvalo dvě sekundy a vydalo 26 MB. Databáze byla v pořádku: 121 tabulek, 9 repozitářů, historie pull requestů, import bez jediné chyby. Jenže adresář s daty aplikace byl prázdný. V archivu nebyl žádný git obsah.
Příčina: aplikace drží veškerá data v pojmenovaném Docker volume, zatímco zálohovaly se jen cesty s konfigurací, tedy adresář s compose souborem, nginx a certifikáty. V záloze tak nebyly git repozitáře, LFS objekty, přílohy, avatary ani SSH klíče serveru. Devět obnovených repozitářů existovalo jen jako záznam v databázi. Obnovený server by naběhl bez jediného commitu.
Chyba byla ve zdrojových cestách, takže postihovala stejně lokální zálohu jako novou off-site kopii. Dvě kopie téže prázdnoty.
Záloha se přitom tvářila zdravě. Běžela denně. Hlásila úspěch. Měla rozumnou velikost, protože databáze a konfigurace něco váží. Hlídal ji monitoring, který kontroloval, že běh proběhl. Všechna místa, kam by se člověk podíval, říkala, že je všechno v pořádku. Rozdíl mezi „záloha běží” a „záloha je obnovitelná” neodhalí nic jiného než pokus o obnovu.
Druhý běh: pod pět minut
Opravil jsem zdrojové cesty, nechal proběhnout zálohu a test zopakoval. Rozbalení z off-site kopie trvalo 8 sekund a vydalo 267 MB. Postavení stacku, obnova databáze a start kontejnerů 24 sekund. Celá obnova z prázdného serveru včetně instalace balíčků trvala pod pět minut.
Tentokrát jsem nechtěl vědět, že server naběhl, ale že funguje:
- HTTP odpověď 200.
- Administrátorský příkaz vrací uživatele z aplikace, ne jen řádky z databáze.
- Jeden z repozitářů má na hlavní větvi 828 commitů a poslední z nich odpovídá poslednímu commitu na produkci.
git fsckbez chyby.git clonez obnoveného serveru vytvořil funkční pracovní strom.- Počet repozitářů sedí na všech třech místech: 9 na disku, 9 v databázi, 9 v archivu.
Po testu jsem VPS smazal a dočasný klíč z auditního účtu odebral. Produkční server běžel nepřetržitě po celou dobu, nic se na něm nemazalo.
Čtyři poučení
- Test obnovy je jediná kontrola, která odhalí chybějící data. Velikost archivu, návratový kód ani monitoring to nezachytí, protože všechny měří, že něco proběhlo, ne co v tom je.
- U aplikací v Dockeru se ptát, kde reálně leží data, ne kde leží compose soubor.
- Obnovu dělat účtem jen pro čtení. Jeden parametr navíc a test nemůže zálohu poškodit.
- Databázi obnovovat z dumpu, ne z kopie datového adresáře.
Co si z toho odnést
Záloha, kterou jste nikdy neobnovili, je hypotéza. Zelený monitoring vám říká, že skript doběhl, ne že v archivu je to, co potřebujete. Test obnovy na čistém stroji stojí hodinu práce a hodinový pronájem serveru. Bez něj se to dozvíte v den, kdy o data přijdete.