Replication — Master-Slave, asoslar

~20 daq · MySQL · Xavfsizlik va Boshqaruv

Muammodan boshlaylik

Do'kon o'sdi. Ikki muammo:

  1. Yuklama: sekundiga 2000 so'rov, ularning 90% i — o'qish (katalog, qidiruv, mahsulot sahifalari). Bitta MySQL server bardosh bermayapti. Kuchliroq server sotib olish — chegarasi bor va juda qimmat
  2. Ishonchlilik: server ishdan chiqsa — sayt to'liq to'xtaydi. Backup dan tiklash — soatlar (52-dars)

Yechim — ma'lumotning jonli nusxalari boshqa serverlarda. Bu — replication.


Asosiy g'oya

                    ┌────────────────┐
  Yozish (INSERT,   │    SOURCE      │
  UPDATE, DELETE) → │   (master)     │
                    └───────┬────────┘
                            │ binary log
              ┌─────────────┼─────────────┐
              ▼             ▼             ▼
       ┌───────────┐  ┌───────────┐  ┌───────────┐
       │ REPLICA 1 │  │ REPLICA 2 │  │ REPLICA 3 │  ← O'qish (SELECT)
       │  (slave)  │  │  (slave)  │  │  (slave)  │
       └───────────┘  └───────────┘  └───────────┘
  • Source (eski nomi — master) — barcha yozishlar shu yerga
  • Replica (eski nomi — slave) — source dagi o'zgarishlarni avtomatik qabul qilib, o'zida qaytaradi. Undan o'qiladi

[!INFO] MySQL 8.0.22 dan boshlab rasmiy atamalar — source va replica. Buyruqlar ham o'zgardi: START SLAVE → START REPLICA, SHOW SLAVE STATUS → SHOW REPLICA STATUS. Eski hujjat va maqolalarda master/slave ni ko'rasiz — ma'nosi bir xil.


Qanday ishlaydi

SOURCE:
  1. INSERT INTO buyurtmalar ...
  2. O'zgarish binary log ga yoziladi
                │
                │ (tarmoq)
                ▼
REPLICA:
  3. I/O thread: binary log yozuvlarini oladi → relay log ga yozadi
  4. SQL thread: relay log dagi o'zgarishlarni o'z bazasida bajaradi

Binary log — o'sha point-in-time recovery dagi jurnal (52-dars). Replication shu jurnalni boshqa serverga uzatish va qaytadan o'ynatish.


Sozlash — asosiy qadamlar

Source da (my.cnf)

[mysqld]
server-id = 1
log_bin = mysql-bin
binlog_format = ROW
gtid_mode = ON
enforce_gtid_consistency = ON
CREATE USER 'repl'@'10.0.0.%' IDENTIFIED BY 'Repl_Parol!';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'10.0.0.%';

Replica da (my.cnf)

[mysqld]
server-id = 2                 # har bir server — noyob
read_only = ON
super_read_only = ON
gtid_mode = ON
enforce_gtid_consistency = ON

read_only — ilova tasodifan replica ga yozib qo'ymasligi uchun.

Boshlang'ich ma'lumot va ulanish

Replica bo'sh holatda boshlanmaydi — avval source ning nusxasi yuklanadi (mysqldump --source-data yoki MySQL Shell clone), keyin:

CHANGE REPLICATION SOURCE TO
    SOURCE_HOST = '10.0.0.10',
    SOURCE_USER = 'repl',
    SOURCE_PASSWORD = 'Repl_Parol!',
    SOURCE_AUTO_POSITION = 1;      -- GTID — pozitsiyani avtomatik aniqlash

START REPLICA;

GTID (Global Transaction ID) — har bir tranzaksiyaning noyob ID si. Replica qaysi tranzaksiyalarni allaqachon bajarganini o'zi biladi — fayl nomi va pozitsiyani qo'lda kuzatish shart emas.


Holatni tekshirish

SHOW REPLICA STATUS\G

Eng muhim maydonlar:

Replica_IO_Running: Yes          ← ma'lumot olinyapti
Replica_SQL_Running: Yes         ← qo'llanilyapti
Seconds_Behind_Source: 0         ← kechikish (soniyalarda)
Last_Error:                      ← bo'sh bo'lishi kerak

Ikkalasi Yes bo'lmasa yoki Last_Error da biror narsa bo'lsa — replication to'xtagan. Monitoring shu uch maydonni kuzatishi kerak.


Replication kechikishi (lag)

Replication asinxron: source COMMIT qiladi va mijozga darhol javob beradi. Replica o'zgarishni biroz keyin oladi — odatda millisekundlar, yuklama ostida — soniyalar yoki daqiqalar.

Bu klassik xatoga olib keladi:

1. Foydalanuvchi profil ismini o'zgartirdi     → SOURCE ga UPDATE
2. Sahifa qayta yuklandi                        → REPLICA dan SELECT
3. Eski ism ko'rinmoqda! 😕                     ← replica hali yangilanmagan

Yechimlar:

  • "O'z yozganini o'qish": foydalanuvchi yaqinda (masalan, 5 soniya ichida) biror narsa yozgan bo'lsa — uning so'rovlarini source dan o'qish
  • Muhim o'qishlar (to'lovdan keyin balans, buyurtma holati) — doim source dan
  • Kechikishni monitoring qilish: Seconds_Behind_Source > 10 — ogohlantirish

Laravel da 'sticky' => true sozlamasi aynan birinchi yechimni avtomatik qiladi.


Ilovada o'qish/yozishni ajratish

<?php
// Laravel — config/database.php
'mysql' => [
    'read' => [
        'host' => ['10.0.0.11', '10.0.0.12'],   // replica lar
    ],
    'write' => [
        'host' => ['10.0.0.10'],                // source
    ],
    'sticky' => true,
    // ...
],

Laravel SELECT larni replica larga, qolganlarini source ga avtomatik yuboradi. Node.js da — ikkita alohida pool yoki ORM ning replication sozlamasi (Sequelize replication, Prisma read replicas extension).


Replication nima uchun ishlatiladi

Maqsad Qanday
O'qishni kengaytirish SELECT lar replica lar o'rtasida taqsimlanadi
Yuqori mavjudlik (HA) Source ishdan chiqsa — replica source ga aylantiriladi (failover)
Og'ir hisobotlar Analitika alohida replica da — asosiy saytga ta'sir qilmaydi
Backup Backup replica dan olinadi — source yuklanmaydi
Geografik yaqinlik Boshqa mamlakatdagi foydalanuvchilar uchun yaqin replica

[!WARNING] Replication — backup emas. Source da DROP TABLE buyurtmalar bajarilsa — u bir soniyadan keyin barcha replica larda ham bajariladi. Xato, buzilgan ma'lumot ham replikatsiya qilinadi. Backup (52-dars) baribir kerak.


Failover — source ishdan chiqsa

Qo'lda:

  1. Eng yangi replica ni tanlash (eng kam kechikish)
  2. Unda STOP REPLICA; RESET REPLICA ALL; va read_only = OFF
  3. Qolgan replica larni yangi source ga yo'naltirish
  4. Ilova sozlamalarini yangi source ga o'zgartirish

Bu qo'lda qilinsa — daqiqalar va xato xavfi. Avtomatlashtiruvchi vositalar:

  • MySQL InnoDB Cluster / Group Replication — rasmiy, avtomatik failover
  • Orchestrator — topologiyani boshqarish
  • ProxySQL — ilova va baza orasidagi proksi: o'qish/yozishni ajratadi, failover da yo'naltirishni o'zgartiradi
  • Bulut (RDS Multi-AZ, Cloud SQL HA) — hammasi avtomatik

Sinxron variantlar

Asinxron replication da source COMMIT qilgan, lekin replica ga hali yetib bormagan tranzaksiya — source ishdan chiqsa yo'qoladi.

  • Semi-synchronous replication — source kamida bitta replica "oldim" deguncha COMMIT ni tasdiqlamaydi. Biroz sekinroq, lekin ma'lumot yo'qolmaydi
  • Group Replication — bir nechta server konsensus orqali kelishadi

Moliyaviy tizimlar uchun — kamida semi-sync.


Nima uchun shunday?

Nima uchun yozishlar faqat bitta serverga boradi — barcha serverlarga yozsa yuklama taqsimlanmasmidi?

Chunki ikkita server bir vaqtda bitta qatorni turlicha o'zgartirsa — ziddiyat paydo bo'ladi: qaysi biri to'g'ri? iPhone ning oxirgi donasi ikkala serverda ham bir vaqtda sotildi — endi nima? Bitta source — yagona haqiqat manbai, barcha yozishlar ketma-ket tartiblangan. Ko'p source li tizimlar (multi-primary) mavjud, lekin ular ziddiyatlarni hal qilish uchun murakkab mexanizmlar talab qiladi. Ko'pchilik ilovalar uchun "bitta yozuvchi, ko'p o'quvchi" — eng sodda va ishonchli model.


Xulosa

Eslab qoling:

  • Replication — ma'lumotning jonli nusxalari; source (master) → replica (slave)
  • Yozish — faqat source ga; o'qish — replica lardan
  • Binary log orqali ishlaydi; GTID — pozitsiyani avtomatik kuzatish
  • SHOW REPLICA STATUS: IO_Running, SQL_Running, Seconds_Behind_Source
  • Asinxron — kechikish bor: "o'z yozganini o'qish" source dan
  • Foydalari: o'qishni kengaytirish, failover, hisobotlar, backup manbai
  • Replication — backup emas: xatolar ham nusxalanadi

Keyingi dars

54-dars: Connection Pool — nima uchun kerak, sozlash