MySQL duomenų bazės strategijos

Kodėl backup strategija nėra tik IT skyriaus reikalas

Kažkada dirbau projekte, kur klientas buvo įsitikinęs, kad jų duomenys saugūs, nes „serveris stovi patikimame duomenų centre”. Kol vieną gražią dieną po nesėkmingo atnaujinimo neteko pusės metų duomenų. Backup’ų nebuvo. Įmonė bankrutavo per tris mėnesius. Skamba dramatiškai? Galbūt, bet tai tikra istorija, kuri puikiai iliustruoja, kodėl MySQL duomenų bazės atsarginės kopijos – tai ne tik techninė procedūra, o verslo išlikimo klausimas.

Daugelis programuotojų ir sistemų administratorių mano, kad backup strategija – tai paprasčiausias cronjob su mysqldump komanda. Realybė kur kas sudėtingesnė. Gera backup strategija turi atsakyti į kelis esminius klausimus: kaip greitai galite atkurti duomenis, kiek duomenų galite sau leisti prarasti, kur tie duomenys saugomi ir ar tikrai galite juos atkurti, kai prireikia.

Pagrindiniai backup metodai ir kada juos naudoti

MySQL duomenų bazių atsarginių kopijų pasaulyje egzistuoja keletas fundamentalių metodų, ir kiekvienas turi savo vietą bei laiką. Pradėkime nuo klasikos.

Logical backup’ai su mysqldump – tai tarsi duomenų bazės eksportas į SQL komandų rinkinį. Įrankis mysqldump yra įtrauktas į kiekvieną MySQL instaliaciją ir veikia paprastai: jis ištraukia duomenų bazės struktūrą ir duomenis į tekstinį failą, kurį vėliau galite importuoti atgal. Šis metodas puikiai tinka mažesnėms ir vidutinėms duomenų bazėms (iki kelių dešimčių gigabaitų), kai galite sau leisti sustabdyti rašymo operacijas arba dirbti su šiek tiek nekonzistentiškais duomenimis.

Praktinis pavyzdys atrodytų taip:

mysqldump --single-transaction --routines --triggers --events -u root -p duomenu_baze > backup_$(date +%Y%m%d_%H%M%S).sql

Parametras --single-transaction čia kritiškai svarbus, nes jis užtikrina, kad InnoDB lentelės bus nukopijuotos konsistentiškai, nenaudojant lentelių užrakinimo. Tai reiškia, kad jūsų aplikacija gali toliau veikti backup’o metu.

Physical backup’ai – tai tiesioginis duomenų failų kopijavimas. Galite naudoti įrankius kaip Percona XtraBackup arba MySQL Enterprise Backup. Šie sprendimai leidžia daryti „hot backup” – kopijuoti duomenis, kol serveris veikia normaliu režimu. Didžiulis privalumas – greitis. Jei turite 500GB duomenų bazę, logical backup gali užtrukti valandas, o physical – gerokai trumpiau.

XtraBackup naudojimas atrodo taip:

xtrabackup --backup --target-dir=/backup/full --user=root --password=slaptazodis

Incremental ir differential backup’ai – čia pradeda darytis įdomu. Vietoj to, kad kas kartą kopijuotumėte visą duomenų bazę, galite daryti pilną kopiją retai (pavyzdžiui, kas savaitę), o tarp jų – tik pokyčius. Tai sutaupo vietos ir laiko, bet atkūrimas tampa sudėtingesnis, nes reikia atkurti pilną kopiją ir vėliau pritaikyti visus pokyčius.

Binary log’ai – jūsų laiko mašina

Štai ko dauguma pradedančiųjų neįvertina: MySQL binary log’ai yra ne tik replikacijos įrankis, bet ir neįkainojama backup strategijos dalis. Binary log’ai įrašo kiekvieną duomenų bazės pakeitimą, todėl galite atkurti duomenis iki konkretaus momento laike (point-in-time recovery).

Įsivaizduokite situaciją: darote pilną backup kas naktį 2 val. Penktadienį 14:30 kažkas atsitiktinai ištryna svarbią lentelę. Jei turite tik naktinį backup, prarandate visos dienos darbą. Bet jei turite binary log’us, galite atkurti nakties backup’ą ir „perleisti” visus pakeitimus iki 14:29, prieš tą lemtingą DELETE komandą.

Binary log’ų įjungimas my.cnf faile:


[mysqld]
server-id = 1
log-bin = /var/log/mysql/mysql-bin.log
expire_logs_days = 7
max_binlog_size = 100M

Svarbu suprasti, kad binary log’ai auga labai greitai intensyviai naudojamose sistemose. Mačiau atvejų, kai per dieną susikaupdavo 50GB log’ų. Todėl būtina nustatyti rotaciją ir reguliariai archyvuoti senus log’us.

Kaip dažnai daryti backup’us ir kiek jų saugoti

Čia nėra vieno teisingo atsakymo, bet yra gera metodika, kaip jį rasti. Turite išsiaiškinti du dalykus: RPO (Recovery Point Objective) ir RTO (Recovery Time Objective).

RPO – tai kiek duomenų galite sau leisti prarasti. Jei atsakymas „nė vieno įrašo”, turite daryti continuous backup arba naudoti replikaciją su binary log’ais. Jei galite prarasti dienos duomenis – pakanka naktinių backup’ų.

RTO – tai per kiek laiko turite atkurti sistemą. Jei atsakymas „per 15 minučių”, logical backup’ai iš 200GB duomenų bazės tikrai netiks. Reikės physical backup’ų arba net hot standby serverio.

Praktiškai daugelis projektų naudoja tokią schemą:
– Pilnas backup kas naktį
– Incremental backup’ai kas 6 valandas
– Binary log’ų archyvavimas kas valandą
– Retention: 7 dienos pilnų backup’ų, 30 dienų savaitinių, 12 mėnesių mėnesinių

Šis modelis leidžia atkurti duomenis praktiškai į bet kurį momentą per pastarąsias 7 dienas, o senesnių duomenų atkūrimui turite bent savaitinę granuliarumą.

Kur saugoti backup’us ir kaip juos apsaugoti

Geriausias backup yra tas, kurio niekada nenaudojate. Blogiausias – tas, kurio negalite panaudoti, kai reikia. Ir čia prasideda tikroji drama.

Pirmoji taisyklė: 3-2-1 principas. Trys kopijos (originalo duomenys + 2 backup’ai), dviejose skirtingose laikmenose (pavyzdžiui, diskas ir tape), viena kopija offsite (ne tame pačiame fiziniame lokacijoje). Gaisras duomenų centre, potvynis, ransomware ataka – visa tai nutinka dažniau nei manote.

Praktiškai tai gali atrodyti taip:
– Pirminiai backup’ai lokaliam diske (greitas priėjimas)
– Kopija NAS įrenginyje tame pačiame duomenų centre
– Trečia kopija AWS S3 arba kituose cloud storage

Šiuolaikinis požiūris – naudoti object storage kaip AWS S3, Google Cloud Storage ar Azure Blob. Jie pigūs, patikimi ir turi built-in versioning. Galite net naudoti S3 Glacier Deep Archive ilgalaikiam saugojimui – kainuoja tik $1 už TB per mėnesį.

Pavyzdys, kaip automatiškai kelti backup’us į S3:


#!/bin/bash
BACKUP_FILE="backup_$(date +%Y%m%d_%H%M%S).sql.gz"
mysqldump --single-transaction --all-databases | gzip > /tmp/$BACKUP_FILE
aws s3 cp /tmp/$BACKUP_FILE s3://mano-backup-bucket/mysql/
rm /tmp/$BACKUP_FILE

Šifravimas – dar vienas aspektas, kurį dažnai pamiršta. Jūsų backup’uose gali būti slaptažodžiai, asmens duomenys, verslo paslaptys. Jei kas nors gautų prieigą prie jūsų S3 bucket, kas nutiktų? Naudokite šifravimą tiek transit, tiek rest būsenoje.

Šifruotas backup su OpenSSL:


mysqldump --single-transaction --all-databases | gzip | openssl enc -aes-256-cbc -salt -out backup.sql.gz.enc -pass file:/path/to/keyfile

Testavimas – labiausiai ignoruojama backup strategijos dalis

Turiu prisipažinti – mačiau daugybę įmonių, kurios religingai darė backup’us, bet nė karto jų netestavo. Kol atėjo diena X ir paaiškėjo, kad backup’ai korumpti, neišsiarchyvuoja arba tiesiog neveikia dėl pasikeitusios MySQL versijos.

Backup testavimas turi būti reguliarus ir automatizuotas. Idealiu atveju – kas savaitę. Minimali testavimo procedūra:

1. Paimti atsitiktinį backup’ą
2. Atkurti jį į test aplinką
3. Patikrinti duomenų integralumą (įrašų skaičius, checksum’ai)
4. Paleisti kritinius query
5. Užfiksuoti rezultatus

Galite sukurti paprastą scriptą, kuris tai darytų automatiškai:


#!/bin/bash
# Restore test
mysql -u root -p test_restore_db < latest_backup.sql ORIGINAL_COUNT=$(mysql -u root -p production_db -e "SELECT COUNT(*) FROM users" -sN) RESTORED_COUNT=$(mysql -u root -p test_restore_db -e "SELECT COUNT(*) FROM users" -sN) if [ "$ORIGINAL_COUNT" -eq "$RESTORED_COUNT" ]; then echo "Backup validation: SUCCESS" else echo "Backup validation: FAILED" # Send alert fi

Dar geriau – naudokite test restore rezultatus kaip monitoringo metriką. Jei restore nepavyksta, turite žinoti apie tai iš karto, ne po trijų mėnesių, kai tikrai prireiks.

Automatizavimas ir monitoringas

Rankinis backup'ų darymas – tai kelias į katastrofą. Žmogus pamiršta, suserga, išeina atostogų. Automatizavimas turi būti ne "nice to have", o absoliuti būtinybė.

Paprasčiausias variantas – cron job'ai. Bet čia slypi pavojus: jei backup scriptas klaidos kodu grąžina 0 (success), net jei iš tikrųjų nepavyko, jūs niekada nesužinosite apie problemą.

Geresnis būdas – naudoti specialius backup įrankius kaip MySQL Enterprise Backup, Percona XtraBackup arba net komercinius sprendimus kaip Veeam, Commvault. Jie turi built-in monitoringą, alertus, retention policies.

Bet jei kuriate savo sprendimą, būtinai įtraukite:

Logging – kiekvienas backup turi turėti log'ą su timestamp, dydžiu, trukme, rezultatu:


#!/bin/bash
LOG_FILE="/var/log/mysql_backup.log"
echo "$(date '+%Y-%m-%d %H:%M:%S') - Starting backup" >> $LOG_FILE

if mysqldump --single-transaction --all-databases > backup.sql 2>> $LOG_FILE; then
SIZE=$(du -h backup.sql | cut -f1)
echo "$(date '+%Y-%m-%d %H:%M:%S') - Backup completed successfully. Size: $SIZE" >> $LOG_FILE
else
echo "$(date '+%Y-%m-%d %H:%M:%S') - Backup FAILED" >> $LOG_FILE
# Send alert
exit 1
fi

Alerting – integruokite su Slack, PagerDuty, email arba kuo naudojate. Backup'as nepavyko? Turite žinoti per 5 minutes, ne kitą dieną.

Metrikos – sekite backup dydį, trukmę, sėkmės rate. Jei backup staiga tapo dvigubai didesnis arba užtrunka tris kartus ilgiau – tai signalas, kad kažkas negerai.

Replikacija kaip backup strategijos dalis

Daug kas mano, kad MySQL replikacija – tai backup sprendimas. Tai tik iš dalies tiesa. Replikacija puikiai apsaugo nuo hardware gedimų, bet visiškai neapsaugo nuo logical klaidų.

Jei kažkas paleidžia DROP TABLE users; production aplinkoje, ši komanda replikuojasi į visus slave serverius per sekundes. Visi jūsų "backup'ai" dabar neturi users lentelės. Todėl replikacija turi būti papildoma priemonė, ne pagrindinis backup metodas.

Tačiau replikacija turi vieną puikų panaudojimą backup strategijoje: galite daryti backup'us iš slave serverio, neapkraudami master. Tai ypač svarbu didelėms, apkrautoms sistemoms.

Dar vienas įdomus variantas – delayed replication. Galite sukonfigūruoti slave serverį, kuris replikuoja duomenis su 1-2 valandų vėlavimu:


CHANGE MASTER TO MASTER_DELAY = 3600;

Tai suteikia jums laiko lango: jei pastebite klaidą per valandą, galite sustabdyti delayed slave ir atkurti duomenis iš jo prieš klaidos replikavimą.

Cloud-native backup strategijos

Jei naudojate managed MySQL servisus kaip AWS RDS, Google Cloud SQL ar Azure Database, backup situacija šiek tiek skiriasi. Šie servisai daro automatinius backup'us už jus, bet turite suprasti jų limitacijas.

AWS RDS pavyzdžiui:
- Automatiniai daily snapshots (retention iki 35 dienų)
- Point-in-time recovery per pastarąsias 5 minutes
- Manual snapshots (neribota retention)

Skamba puikiai, bet yra niuansų. Restore operacija sukuria NAUJĄ RDS instance, ne atkuria egzistuojančio. Tai reiškia, kad turite pakeisti connection strings, DNS įrašus ir t.t. RTO gali būti ilgesnis nei tikitės.

Todėl net su managed servisais verta turėti papildomus logical backup'us. Jie suteikia lankstumą: galite atkurti tik vieną lentelę, migruoti į kitą platformą, testavimui ir t.t.

Kai viskas eina ne pagal planą – disaster recovery

Galiausiai, pats svarbiausias testas jūsų backup strategijai – tikras disaster. Serveris sudegė, duomenų centras užlietas, ransomware užšifravo viską. Ar žinote tiksliai, ką daryti?

Disaster recovery planas turi būti dokumentuotas, testuotas ir prieinamas ne tik IT skyriui. Jame turi būti:

1. Kontaktai – kas už ką atsakingas, kaip susisiekti
2. Prioritetai – kokius servisus atkurti pirmus
3. Procedūros – žingsnis po žingsnio instrukcijos
4. Credentials – prieigos prie backup'ų (saugiai!)
5. Testing rezultatai – kada paskutinį kartą testavo, kiek užtruko

Praktinis patarimas: sukurkite "runbook" – dokumentą su konkrečiomis komandomis, kurias reikia vykdyti. Pavyzdžiui:


# Disaster Recovery Runbook - MySQL Production

## Step 1: Assess the situation
- Check server status: ping db.production.com
- Check backup availability: ls -lh /backup/mysql/

## Step 2: Prepare new server
- Launch new EC2 instance
- Install MySQL: sudo apt-get install mysql-server
- Configure: sudo vim /etc/mysql/my.cnf

## Step 3: Restore data
- Get latest backup: aws s3 cp s3://backup-bucket/latest.sql.gz /tmp/
- Decompress: gunzip /tmp/latest.sql.gz
- Import: mysql -u root -p < /tmp/latest.sql ## Step 4: Apply binary logs - Get binary logs: aws s3 sync s3://backup-bucket/binlogs/ /tmp/binlogs/ - Apply: mysqlbinlog /tmp/binlogs/mysql-bin.* | mysql -u root -p ## Step 5: Verify - Check record counts: SELECT COUNT(*) FROM critical_table; - Test application connectivity - Update DNS records

Disaster recovery pratybos turėtų vykti bent kartą per metus. Taip, tai brangu laiko prasme, bet kai ateina tikras disaster, tie pratybų investuoti valandos atsipirksta šimteriopai.

Kaip tai viskas sujungti į veikiančią sistemą

Gerai, aptarėme daug teorijos ir pavyzdžių. Kaip tai visą sujungti į realią, veikiančią backup strategiją? Pateikiu konkretų planą vidutiniam projektui (10-100GB duomenų bazė, kritinis verslo servisas):

Daily rutina:
- 02:00 - Pilnas physical backup su XtraBackup į lokalų RAID array
- 08:00, 14:00, 20:00 - Incremental backup'ai
- Kas valandą - Binary log flush ir archyvavimas
- 03:00 - Pilno backup'o kopijavimas į S3 (šifruotas)
- 04:00 - Automatinis restore testas į test aplinką

Weekly rutina:
- Sekmadienį 01:00 - Pilnas logical backup su mysqldump (papildoma kopija)
- Pirmadienį 09:00 - Manual restore testas su komandos nariu

Monthly rutina:Monitoring ir alerting:
- Backup size anomalijos (>20% pokytis)
- Backup failure (bet koks)
- Restore test failure
- Disk space backup lokacijose (<20% laisvo) - Binary log lag (>1 valanda)

Retention policy:
- Daily backups: 7 dienos lokaliai, 30 dienų S3
- Weekly backups: 12 savaičių S3
- Monthly backups: 12 mėnesių S3 Standard, vėliau Glacier
- Binary logs: 7 dienos lokaliai, 30 dienų S3

Tokia sistema kainuoja (storage, compute, laikas), bet ji veikia. Ir kai ateina tas momentas – o jis ateis – kai reikia atkurti duomenis, jūs būsite pasiruošę.

Paskutinis patarimas: backup strategija nėra "set and forget". Duomenų bazė auga, keičiasi reikalavimai, atsiranda naujos technologijos. Peržiūrėkite ir atnaujinkite savo strategiją bent kas ketvirtį. Testuokite reguliariai. Dokumentuokite viską. Ir nepamirškite – geriausias backup yra tas, kurio niekada nenaudojate, bet visada galite.

Daugiau

Kuo profesionali krovinių pervežimo įmonė skiriasi nuo pavienių vežėjų