Categories
Database Backup

** Discover how DevOps engineers and DBAs can detect corrupted database backups before disaster strikes. Learn advanced techniques for PostgreSQL, SQL Server, and MySQL, including automated restore testing and checksum validation.

Во светот на администрацијата на бази на податоци и инженерството за доверливост на сајтови, постои добро позната аксиома: Шредингерова резервна копија (Schrödinger’s Backup). Состојбата на која било резервна копија е непозната сè додека не се обидете да ја вратите. До тој момент, таа постои во квантна состојба на тоа да биде истовремено совршено функционална и целосно оштетена.

За DevOps инженерите и администраторите на бази на податоци (DBA), откривањето дека критичната резервна копија на базата на податоци е оштетена за време на активен инцидент е сценарио од најлош кошмар. Тоа ја претвора рутинската операција за обновување во катастрофален настан на губење на податоци. Овој „тивок убиец“ на интегритетот на податоците често поминува незабележано бидејќи задачите за правење резервни копии честопати пријавуваат успешно Exit Code 0 дури и кога основниот товар е компромитиран.

Во овој сеопфатен водич, ќе ја анализираме анатомијата на оштетувањето на резервните копии, ќе истражиме техники за валидација специфични за базите на податоци и ќе покажеме како да изградите автоматизирани, „непробојни“ цевководи за обновување во продукциски средини.

Анатомија на оштетувањето на резервните копии

За да откриете оштетување, прво мора да разберете како тоа се случува. Оштетувањето на резервните копии генерално спаѓа во две категории: физичко (на ниво на инфраструктура) и логичко (на ниво на апликација).

Физичко оштетување

Физичкото оштетување се случува кога самите битови на медиумот за складирање се изменети. Ова може да се случи за време на процесот на читање од изворниот диск, за време на преносот преку мрежата или додека податоците мируваат на целното складиште.
* Bit Rot (Распаѓање на битови): Постепената деградација на медиумите за складирање може тивко да ги преврти битовите.
* Грешки при пренос: Иако TCP има контролни суми (checksums), тие се познати по тоа што се слаби (16-битни). Средините со голем проток на податоци можат да доживеат тивко оштетување на податоците преку жица што TCP не успева да го фати.
* Дефекти на контролорот за складирање: Хардверските грешки во RAID контролорите или SAN ткаенините можат да запишат „ѓубре“ податоци додека пријавуваат успех на оперативниот систем.

Логичко оштетување

Логичкото оштетување е веројатно поопасно бидејќи самата датотека на резервната копија е совршено недопрена, но податоците во неа се расипани.
* Ѓубре внатре, ѓубре надвор (GIGO): Ако вашата база на податоци во живо има оштетен индекс или скината страница, вашата алатка за резервна копија може верно да ја копира таа оштетена страница. Задачата за резервна копија успева, но обновувањето ќе пропадне или ќе резултира со расипана база на податоци.
* Нецелосни трансакции: Снимките (snapshots) на ниво на датотечен систем направени без соодветно замрзнување на I/O на базата на податоци (на пр., без користење на FLUSH TABLES WITH READ LOCK во MySQL) резултираат со скинати страници и состојби што не можат да се вратат.

Проактивно откривање: Контролни суми и криптографско хеширање

Првата линија на одбрана против физичко оштетување е криптографската валидација. Потпирањето на големината на датотеката или датумите на измена е недоволно.

Овозможување на контролни суми на ниво на база на податоци

Модерните системи за управување со релациони бази на податоци (RDBMS) поддржуваат контролни суми на ниво на страница. Кога се овозможени, базата на податоци пресметува контролна сума за секоја страница пред да ја запише на дискот. Кога страницата се чита (било со барање или со процес на резервна копија), контролната сума се верификува.

За PostgreSQL, можете да овозможите контролни суми на податоци за време на иницијализацијата на кластерот:

# Иницијализирајте нов PostgreSQL кластер со овозможени контролни суми
initdb --data-checksums -D /var/lib/postgresql/data

Забелешка: Ако веќе имате постоечки PostgreSQL кластер, можете да ја користите алатката pg_checksums за да ги овозможите офлајн.

За Microsoft SQL Server, осигурете се дека PAGE_VERIFY е поставено на CHECKSUM (стандардно во модерните верзии, но вреди да се провери на постарите системи):

ALTER DATABASE [ProductionDB] SET PAGE_VERIFY CHECKSUM;
GO

Валидација на резервни копии во мирување

Откако резервната копија ќе стигне до вашата цел за складирање, нејзиниот интегритет мора да биде криптографски верификуван. Платформите за резервни копии на претпријатијата како CloudSave автоматски пресметуваат и верификуваат SHA-256 хешови на блоковите од резервната копија за време на преносот и додека мируваат. Ако управувате со сопствени скрипти, мора да го спроведете ова рачно:

# Генерирајте SHA-256 хеш по креирањето на резервната копија
sha256sum prod_db_backup.tar.gz > prod_db_backup.tar.gz.sha256

# Верификувајте го хешот на серверот за складирање
sha256sum -c prod_db_backup.tar.gz.sha256

Техники за валидација специфични за бази на податоци

Различни мотори на бази на податоци нудат вградени алатки за верификација на интегритетот на нивните артефакти за резервни копии.

PostgreSQL: pg_verifybackup

Воведен во PostgreSQL 13, pg_verifybackup е вистинска промена за физичките резервни копии направени со pg_basebackup. Таа ја чита датотеката backup_manifest генерирана за време на резервната копија и верификува дека сите датотеки се присутни и дека нивните контролни суми се совпаѓаат.

# Стартувајте верификација против директориум со физичка основна резервна копија
pg_verifybackup /mnt/backups/postgres/base_backup_20231025/

Ако еден бит е превртен во која било од датотеките со податоци, pg_verifybackup ќе исфрли фатална грешка, овозможувајќи им на вашите системи за мониторинг веднаш да го алармираат DBA тимот.

Microsoft SQL Server: RESTORE VERIFYONLY

SQL Server обезбедува вградена команда за верификација на физичкиот интегритет на датотеката на резервната копија без всушност да ја враќа. Таа ги проверува заглавијата на резервната копија и ги валидира контролните суми на страниците (ако биле овозможени за време на правењето на резервната копија).

RESTORE VERIFYONLY 
FROM DISK = 'Z:BackupsProdDB_Full.bak' 
WITH CHECKSUM;

Предупредување: RESTORE VERIFYONLY само потврдува дека датотеката на резервната копија е читлива и дека физичките контролни суми се совпаѓаат. Таа не гарантира логички интегритет. За да обезбедите логички интегритет, мора да извршите целосно обновување и да ја стартувате DBCC CHECKDB.

MySQL / InnoDB: Percona XtraBackup

За MySQL средини, физичките резервни копии често се ракуваат со Percona XtraBackup. Процесот на резервна копија се состои од копирање датотеки, но резервната копија не е конзистентна сè додека не се применат дневниците на трансакции (redo logs). Фазата --prepare делува како вградена проверка на интегритетот.

# Подготовката на резервната копија ги применува redo logs. 
# Ако резервната копија е оштетена, овој чекор ќе пропадне.
xtrabackup --prepare --target-dir=/data/backups/mysql/

Златниот стандард: Автоматизирано тестирање на обновување

Контролните суми и командите за верификација се неопходни, но не се доволни. Единствениот начин дефинитивно да се докаже дека резервната копија е функционална е да се врати. Во модерните DevOps средини, овој процес мора да биде целосно автоматизиран.

Со третирање на резервните копии како код, можете да изградите CI/CD цевковод за обновување на вашите бази на податоци. Овој цевковод треба да обезбеди ефемерна инфраструктура, да го изврши обновувањето, да изврши барања за валидација и да ја отстрани средината.

Изградба на автоматизиран цевковод за обновување

Подолу е пример за Bash скрипта што може да се активира секојдневно од cron задача или CI runner (како GitLab CI или GitHub Actions) за да се валидира логички dump на PostgreSQL.

#!/bin/bash
set -e

BACKUP_FILE="/mnt/storage/prod_db_latest.dump"
DB_NAME="prod_db"
CONTAINER_NAME="pg_restore_test"

echo "[INFO] Започнување на автоматизиран тест за обновување..."

# 1. Стартувајте ефемерна PostgreSQL контејнер
docker run --name $CONTAINER_NAME 
  -e POSTGRES_PASSWORD=testpass 
  -d postgres:15

# Почекајте PostgreSQL да биде подготвен
echo "[INFO] Се чека иницијализација на базата на податоци..."
until docker exec $CONTAINER_NAME pg_isready -U postgres; do
  sleep 2
done

# 2. Креирајте ја целната база на податоци
docker exec $CONTAINER_NAME psql -U postgres -c "CREATE DATABASE $DB_NAME;"

# 3. Извршете го обновувањето
echo "[INFO] Враќање на резервната копија..."
docker cp $BACKUP_FILE $CONTAINER_NAME:/tmp/backup.dump
docker exec $CONTAINER_NAME pg_restore -U postgres -d $DB_NAME -1 /tmp/backup.dump

# 4. Извршете барања за логичка валидација
echo "[INFO] Извршување на барања за валидација..."
# Проверете дали табелата со корисници има повеќе од 10.000 записи
USER_COUNT=$(docker exec $CONTAINER_NAME psql -U postgres -d $DB_NAME -t -c "SELECT COUNT(*) FROM users;")

if [ "$USER_COUNT" -lt 10000 ]; then
    echo "[ERROR] Логичката валидација не успеа. Се очекуваа >10000 корисници, пронајдени се $USER_COUNT"
    # Активирајте PagerDuty / Slack аларм овде
    exit 1
else
    echo "[SUCCESS] Логичката валидација е успешна. Број на корисници: $USER_COUNT"
fi

# 5. Отстранете ја ефемерната средина
echo "[INFO] Чистење..."
docker rm -f $CONTAINER_NAME

echo "[INFO] Автоматизираниот тест за обновување е успешно завршен."

Што треба да валидирате?

Кога вршите автоматизирано тестирање на обновување, не проверувајте само дали базата на податоци се стартува. Извршете барања за валидација специфични за апликацијата:
1. Број на редови: Осигурете се дека основните табели имаат очекуван број на редови (на пр., табелата users не треба да биде празна).
2. Неодамнешни податоци: Пребарајте записи креирани во последните 24 часа за да се осигурате дека резервната копија не е застарена.
3. Референцијален интегритет: Стартувајте скрипти за проверка на „сирачки“ надворешни клучеви (orphaned foreign keys), кои укажуваат на логичко оштетување.

Мониторинг и алармирање за аномалии во резервните копии

Откривањето на оштетување пред да се случи катастрофа бара робусна опсервабилност. Покрај бинарните состојби на успех/неуспех, треба да ги следите метаподатоците на вашите задачи за резервни копии за да откриете аномалии.

Хеуристички мониторинг

Интегрирајте ги метаподатоците од вашите резервни копии во Prometheus и визуелизирајте ги со Grafana. Поставете аларми за следниве хеуристики:
* Нагло намалување на големината: Ако вашата дневна резервна копија е постојано 500GB, а денешната е 50MB, задачата можеби е завршена успешно (Exit Code 0), но веројатно направила резервна копија само на празна шема.
* Аномалии во времетраењето: Ако резервната копија што нормално трае 2 часа заврши за 5 минути, нешто е прескокнато. Спротивно на тоа, ако трае 10 часа, можеби имате деградација на I/O на дискот што може да доведе до оштетување.
* Акумулација на WAL/Archive Log: Ако вашата база на податоци генерира Write-Ahead Logs (WAL), но системот за резервни копии не ги архивира доволно брзо, ризикувате празнина во вашиот синџир за Point-in-Time Recovery (PITR).

Имплементација на правилото 3-2-1 со проверки на интегритетот

Индустрискиот стандард за правилото за резервни копии 3-2-1 (3 копии од податоци, 2 различни медиуми, 1 надвор од локацијата) е ефикасен само ако сите копии се верификувани.

Тука искористувањето на претпријатиско решение како CloudSave драстично ги намалува оперативните трошоци. Наместо да пишувате и одржувате сложени bash скрипти за секој јазол на база на податоци, CloudSave се интегрира директно со вашата инфраструктура за да го автоматизира животниот циклус 3-2-1. Обезбедува непроменливо складирање (immutable storage) — заштита од рансомвер — и вклучува вградени, автоматизирани распореди за верификација на обновувањето. CloudSave може автоматски да стартува изолирани песочни средини (sandbox), да ја монтира резервната копија, да ги изврши вашите сопствени SQL скрипти за валидација и да го пријави статусот на здравјето назад до вашата централна контролна табла.

Заклучок

Оштетените резервни копии на бази на податоци се тивок убиец што може да ги уништи бизнисите. Потпирањето исклучиво на Exit Code 0 од скрипта за резервна копија е опасен коцкарски потег.

За навистина да ги заштитите вашите продукциски средини, мора да усвоите стратегија за длабинска одбрана:
1. Овозможете контролни суми на ниво на страница во вашиот мотор за база на податоци.
2. Користете вградени алатки за верификација (pg_verifybackup, RESTORE VERIFYONLY) веднаш по креирањето на резервната копија.
3. Следете ги метаподатоците на резервните копии (големина, времетраење) за хеуристички аномалии.
4. Имплементирајте автоматизирано, ефемерно тестирање на обновување како дел од вашиот дневен оперативен цевковод.

Со преминување од пасивен менталитет „направи и заборави“ кон активен модел на „континуирана валидација на обновувањето“, се осигурувате дека кога неизбежно ќе се случи катастрофа, вашите податоци се подготвени, доверливи и целосно обновливи.