dataiotech Labs
Runbook #63
mysql
AvailabilitySEV1 · KRİTİK KESİNTİ15-30 dakika / 15-30 minsmysql administrator / CLUSTER_ADMIN / GROUP_REPLICATION_ADMIN

MySQL Group Replication / InnoDB Cluster: Node Unreachable ve Split-Brain (NO_QUORUM) Kurtarma

MySQL Group Replication veya InnoDB Cluster'da düğümlerin OFFLINE/ERROR düşmesi, çoğunluk (quorum) kaybı ve split-brain durumlarında MySQL Shell veya SQL ile veri kaybı olmadan küme ayağa kaldırma.

İlişkili Metrik:M14M15
#mysql#innodb-cluster#group-replication#split-brain#no-quorum#mysql-shell#high-availability

Operasyonel Güvenlik ve Risk Uyarısı

Bu runbook müdahale adımları içerir; birçok adım yazma etkilidir (KILL, terminate, DROP, RESIZE). Önce test ortamında deneyin, üretimde adımları sırayla ve doğrulayarak uygulayın.

🟢 Salt Okunur (Read-Only)·🟡 Geri Alınabilir (Reversible)·🔴 Yüksek Etkili / Geri Alınamaz (High Impact)

1. Belirti / Symptom

- `performance_schema.replication_group_members` tablosunda düğüm durumu `UNREACHABLE`, `ERROR` veya `OFFLINE`.

- MySQL Shell `dba.getCluster().status()` çıktısında küme durumu `NO_QUORUM` veya `OK_PARTIAL`.

- MySQL Router 503 döndürür; yazma istekleri `The group is unable to process write transactions` hatasıyla reddedilir.

2. Etki / Impact

P1 Kritik Kesinti. Çoğunluk oyu (quorum) kaybolduğunda InnoDB Cluster yazma işlemlerini dondurur. Yanlış müdahale (geride kalmış bir düğümden bootstrap yapılması) asenkron verilerin üzerine yazılmasına ve split-brain veri kaybına neden olur.

3. Teşhis / Diagnosis

🟢 Salt Okunur1. **Canlı herhangi bir düğüm üzerinden küme üyelerinin durumunu kontrol edin:**
sql
SELECT member_id, member_host, member_port, member_state, member_role, member_version
FROM performance_schema.replication_group_members;
-- STATE: ONLINE, OFFLINE, ERROR, UNREACHABLE
-- MEMBER_ROLE: PRIMARY / SECONDARY
🟢 Salt Okunur2. **MySQL Shell ile küme topolojisini ve quorum durumunu inceleyin:**
bash
mysqlsh root@mysql-node1:3306
javascript
dba.getCluster().status();
// Cluster status: OK, OK_PARTIAL, NO_QUORUM
🟢 Salt Okunur3. **Errorlog'da neden düştüğünü araştırın:**
bash
grep -i "group_replication" /var/log/mysql/error.log | tail -n 100
# Yaygın sebepler: network partition, disk doluluğu, OOM killer, flow control.
🟢 Salt Okunur4. **Karar Matrisi:**

- **1 node OFFLINE, cluster OK_PARTIAL:** Quorum sağlamdır; sadece o node'u güvenle rejoin edin.

- **2 node OFFLINE, NO_QUORUM (Split-Brain):** Quorum yoktur; en güncel GTID'li düğüm üzerinden reboot/force quorum yapılmalıdır.

- **Tüm node'lar UNREACHABLE:** Network / Firewall / DNS izolasyon kontrolü yapın.

4. Müdahale / Response

### Müdahale A: Tek Node OFFLINE — Güvenli Rejoin

javascript
// MySQL Shell ile OFFLINE node üzerinde:
var cluster = dba.getCluster();
cluster.rejoinInstance('root@mysql-node2:3306', {recoveryMethod: 'clone'});
cluster.status();

SQL ile manuel müdahale (MySQL Shell yoksa):

sql
-- OFFLINE düğüm üzerinde:
STOP GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group = OFF;
START GROUP_REPLICATION;
-- 60 saniye içinde performance_schema tablosunda ONLINE görünmelidir.

---

### Müdahale B: Quorum Kaybı — NO_QUORUM (Split-Brain Kurtarma)

En kritik senaryo: 3 düğümlü kümede 2 düğüm düşmüş, kalan 1 düğüm tek başına yazamaz.

⚠️ **ALTIN KURAL: EN GÜNCEL GTID'E SAHİP DÜĞÜMÜ PRIMARY YAPIN!**

sql
-- Kalan canlı düğümlerde en son GTID'yi karşılaştırın:
SELECT @@GLOBAL.gtid_executed;
javascript
// En güncel görünen düğüme bağlanın:
// mysqlsh root@mysql-node1:3306

// 1. Quorum'u zorla geri getirin
dba.rebootClusterFromCompleteOutage();
// MySQL Shell size en güncel instance'ı teyit ettirecektir; en yüksek GTID'li olanı seçin.

// 2. Diğer düğümler fiziksel olarak geldikçe kümeye ekleyin:
var cluster = dba.getCluster();
cluster.rejoinInstance('root@mysql-node2:3306', {recoveryMethod: 'clone'});
cluster.rejoinInstance('root@mysql-node3:3306', {recoveryMethod: 'clone'});

Eğer `rebootClusterFromCompleteOutage()` çalışmazsa, son çare SQL manuel bootstrap:

sql
-- YALNIZCA EN GÜNCEL GTID'Lİ DÜĞÜMDE ÇALIŞTIRIN:
SET GLOBAL group_replication_bootstrap_group = ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group = OFF;

-- İkincil düğümlerde sadece:
START GROUP_REPLICATION;

5. Doğrulama / Verification

- `SELECT * FROM performance_schema.replication_group_members;` -> Tüm üyeler `ONLINE`.

- `cluster.status()` -> Durum `OK` ve `cluster.checkInstanceState()` temiz.

- MySQL Router yönlendirme kontrolü:

bash
mysql -h mycluster-router -P 6446 -u app_user -p -e "SELECT @@hostname, @@global.group_replication_group_name;"

6. Geri Alma / Rollback

- `rebootClusterFromCompleteOutage` sonrası yanlış bir düğümden ayağa kalkıldıysa, diğer düğümlere `clone` ile ezilmeden önce hemen binlog yedeği alınmalı ve `incremental recovery` denenmelidir.

- **Önleme Standartları — dbaguide Standardı:**

- [ ] `group_replication_unreachable_majority_timeout = 30` (varsayılan 0 yerine).

- [ ] `group_replication_autorejoin_tries = 3`.

- [ ] Network: Tüm düğümler arası 3306 ve 33061 (GR haberleşme portu) firewall açık mı?

- [ ] Disk: `innodb_cluster` metadata ve data dizinleri için ayrı izole depolama.

- [ ] PMM / Prometheus Alert: `MySQL Group Replication NOT ONLINE` alarmı aktif mi?

- [ ] Çeyreklik Chaos Engineering testi: 1 node kapatıldığında cluster kesintisiz yazmaya devam ediyor mu?

Mühendislik Triadı: Doğrudan Teşhis Scriptleri

Bu runbook kriz müdahalesinde darboğazı tespit etmek için önerilen hazır SQL / Shell scriptleri:

Tüm Scriptler (100)
#26 · SQLReplication

MySQL Replikasyon Durumu ve Gecikme Kontrolü

IO/SQL thread durumunu, Seconds_Behind_Source değerini ve son hataları kontrol eder. Replica sağlığını hızlıca doğrulamak için kullanılır.

#27 · SQLMonitoring

MySQL InnoDB Buffer Pool İsabet Oranı

Buffer pool okuma isteklerine karşı diskten yapılan okumaları karşılaştırarak isabet oranını hesaplar. Bellek ayarının yeterli olup olmadığını gösterir.

Diğer MYSQL Runbook'ları