Backup va Restore — mysqldump, mysqlpump

~20 daq · MySQL · Xavfsizlik va Boshqaruv

Muammodan boshlaylik

Uchta haqiqiy stsenariy:

  1. Dasturchi production bazada DELETE FROM buyurtmalar ni WHERE siz bajardi (12-dars)
  2. Server diski ishdan chiqdi
  3. Ransomware hujumi — barcha fayllar shifrlandi

Uchala holatda ham yagona qutqaruv — backup. Va eng og'ir xulosa: ko'p kompaniyalar backup ni bor deb o'ylaydi, lekin uni tiklashga urinib ko'rgandagina u ishlamasligini bilib qoladi.

Tiklab ko'rilmagan backup — backup emas.


Ikki xil backup

Mantiqiy (logical) Fizik (physical)
Nima SQL buyruqlar (CREATE TABLE, INSERT) Ma'lumot fayllarining nusxasi
Vositalar mysqldump, mysqlsh dump Percona XtraBackup, MySQL Enterprise Backup, disk snapshot
Tezlik Sekin (ayniqsa tiklash) Tez
Hajm Kichik va katta bazalar uchun Katta bazalar uchun
Ko'chirish Istalgan versiya, istalgan server Bir xil MySQL versiyasi
O'qish Matn — ko'rish, tahrirlash mumkin Ikkilik

Kichik va o'rta bazalar (o'nlab GB gacha) — mysqldump yetarli. Undan katta — fizik backup.


mysqldump

Bitta baza

mysqldump -u backup -p \
    --single-transaction \
    --routines --triggers --events \
    dokon > dokon_2026-11-04.sql
Parametr Ma'nosi
--single-transaction InnoDB uchun izchil "surat" — jadvallarni qulflamasdan (37-dars, MVCC)
--routines Procedure va function lar ham (standart holatda kirmaydi!)
--triggers Trigger lar (standart — kiradi)
--events Event lar (standart holatda kirmaydi!)

[!WARNING] --routines va --events siz backup dan tiklasangiz — ma'lumot bor, lekin barcha procedure, function va rejalashtirilgan vazifalar yo'q. Va buni hech kim darhol sezmaydi.

Variantlar

# Barcha bazalar (foydalanuvchilar va huquqlar bilan)
mysqldump -u root -p --single-transaction --routines --events --all-databases > hammasi.sql

# Faqat ba'zi jadvallar
mysqldump -u backup -p --single-transaction dokon mijozlar buyurtmalar > qisman.sql

# Faqat tuzilma, ma'lumotsiz
mysqldump -u backup -p --no-data dokon > sxema.sql

# Faqat ma'lumot
mysqldump -u backup -p --no-create-info dokon > malumot.sql

# Shart bilan
mysqldump -u backup -p dokon buyurtmalar --where="yaratilgan >= '2026-01-01'" > 2026.sql

# Darhol siqish
mysqldump -u backup -p --single-transaction --routines --events dokon | gzip > dokon.sql.gz

SQL fayl odatda 5-10 barobar siqiladi.

Fayl ichida

-- MySQL dump 10.13  Distrib 8.4.3
DROP TABLE IF EXISTS `mijozlar`;
CREATE TABLE `mijozlar` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  ...
);
LOCK TABLES `mijozlar` WRITE;
INSERT INTO `mijozlar` VALUES (1,'Aziz Karimov','aziz@mail.uz',...),(2,...);
UNLOCK TABLES;

Oddiy SQL — istalgan matn muharririda ochish mumkin.


Tiklash (restore)

# Baza mavjud bo'lishi kerak
mysql -u root -p -e "CREATE DATABASE dokon_tiklangan CHARACTER SET utf8mb4"
mysql -u root -p dokon_tiklangan < dokon_2026-11-04.sql

# Siqilgandan
gunzip < dokon.sql.gz | mysql -u root -p dokon_tiklangan

[!TIP] Avval boshqa nomdagi bazaga tiklang (dokon_tiklangan), tekshiring, keyin almashtiring. To'g'ridan-to'g'ri ishlab turgan bazaning ustiga tiklash — agar backup ham buzilgan bo'lsa, ikkala nusxani ham yo'qotasiz.

Bitta jadvalni tiklash

DELETE FROM buyurtmalar falokatidan keyin butun bazani emas, faqat bitta jadvalni:

# Butun backup ni vaqtinchalik bazaga tiklash
mysql -u root -p dokon_tiklangan < dokon_2026-11-04.sql
-- Kerakli qatorlarni asl bazaga qaytarish
INSERT INTO dokon.buyurtmalar
SELECT * FROM dokon_tiklangan.buyurtmalar
WHERE id NOT IN (SELECT id FROM dokon.buyurtmalar);

Point-in-time recovery — aniq lahzagacha tiklash

Backup tunda soat 03:00 da olindi. Falokat — kunduzi 14:37 da. Backup dan tiklasak — 03:00 dan 14:37 gacha bo'lgan barcha buyurtmalar yo'qoladi.

Yechim — binary log. MySQL har bir o'zgarishni ketma-ket yozib boradi:

SHOW VARIABLES LIKE 'log_bin';         -- ON (MySQL 8 da standart)
SHOW BINARY LOGS;

Tiklash:

  1. Tungi backup ni tiklash (03:00 holati)
  2. Binary log dan 03:00 dan 14:36 gacha bo'lgan o'zgarishlarni qayta o'ynatish:
mysqlbinlog --start-datetime="2026-11-04 03:00:00" \
            --stop-datetime="2026-11-04 14:36:59" \
            binlog.000042 binlog.000043 | mysql -u root -p dokon

Natija — falokatdan bir soniya oldingi holat. Faqat xato DELETE bajarilmadi.

Buning uchun backup paytidagi binlog pozitsiyasi kerak — mysqldump --source-data=2 uni fayl boshiga izoh sifatida yozadi.


Boshqa vositalar

mysqlpump — mysqldump ning parallel versiyasi edi. MySQL 8.0.34 da eskirgan deb e'lon qilindi va 8.4 da olib tashlandi. Yangi loyihalarda ishlatmang.

MySQL Shell dump utilities — zamonaviy almashtiruvchi: parallel, tez, siqilgan:

mysqlsh root@localhost -- util dump-schemas dokon --outputUrl=/backup/dokon_2026-11-04
mysqlsh root@localhost -- util load-dump /backup/dokon_2026-11-04

Percona XtraBackup — katta bazalar uchun bepul fizik backup, server ishlab turganda.

Bulut — AWS RDS, Google Cloud SQL, DigitalOcean: avtomatik kunlik backup va point-in-time recovery — bir tugma bilan. Lekin tiklashni baribir sinab ko'ring.


Avtomatlashtirish

Qo'lda backup — unutiladi. Kundalik cron skript:

#!/bin/bash
set -euo pipefail

SANA=$(date +%F_%H%M)
PAPKA=/backup/mysql
mkdir -p "$PAPKA"

mysqldump --defaults-extra-file=/etc/mysql/backup.cnf \
    --single-transaction --routines --triggers --events --source-data=2 \
    dokon | gzip > "$PAPKA/dokon_$SANA.sql.gz"

# 30 kundan eskilarini o'chirish
find "$PAPKA" -name "dokon_*.sql.gz" -mtime +30 -delete

# Boshqa joyga nusxa (masalan, S3)
aws s3 cp "$PAPKA/dokon_$SANA.sql.gz" s3://kompaniya-backup/mysql/
# crontab — har kuni soat 03:00 da
0 3 * * * /usr/local/bin/mysql_backup.sh >> /var/log/mysql_backup.log 2>&1

/etc/mysql/backup.cnf — parol fayli (buyruq qatorida parol yozmaslik uchun):

[client]
user=backup
password=...

chmod 600 — faqat egasi o'qiy olsin.


3-2-1 qoidasi

  • 3 ta nusxa (asl + 2 backup)
  • 2 xil saqlash vositasida (server diski + bulut)
  • 1 tasi boshqa joyda (boshqa ma'lumotlar markazi, boshqa provayder)

Ransomware hujumidan himoya uchun — kamida bitta nusxa o'zgartirib bo'lmaydigan (immutable) joyda: S3 Object Lock, yoki serverdan to'g'ridan-to'g'ri o'chirib bo'lmaydigan omborda.


Muntazam tiklash testi

Har oy (yoki har hafta):

  1. Eng oxirgi backup ni alohida serverga tiklang
  2. Asosiy jadvallardagi qatorlar sonini tekshiring
  3. Procedure lar, trigger lar, event lar bormi
  4. Tiklash qancha vaqt olganini yozib qo'ying — bu sizning haqiqiy "tiklanish vaqti" (RTO)

Nima uchun shunday?

Nima uchun backup bo'la turib, ko'p kompaniyalar ma'lumotni yo'qotadi?

Chunki backup olish — oson, uni tiklash — boshqa ish. Tipik muammolar: skript bir necha oy oldin jimgina ishlamay qolgan (disk to'lgan, parol o'zgargan); backup bir xil serverda turgan va server bilan birga yo'qolgan; procedure lar kirmagan; 500 GB ni tiklash 18 soat olishi falokat paytida bilib qolindi. Backup ning qiymati faqat tiklashda ko'rinadi — shuning uchun tiklash ham xuddi backup kabi muntazam va avtomatik bo'lishi kerak.


Xulosa

Eslab qoling:

  • Tiklab ko'rilmagan backup — backup emas
  • mysqldump --single-transaction --routines --triggers --events baza > fayl.sql
  • --routines va --events standart holatda kirmaydi!
  • Tiklash: mysql baza < fayl.sql — avval boshqa nomdagi bazaga
  • Binary log + backup = point-in-time recovery
  • mysqlpump — eskirgan; zamonaviy: MySQL Shell util.dumpSchemas, XtraBackup
  • Avtomatlashtiring (cron), boshqa joyga nusxa, 3-2-1 qoidasi
  • Har oy tiklash testi

Keyingi dars

53-dars: Replication — Master-Slave, asoslar