dataiotech Labs
Runbook #58
mysql
BackupSEV1 · CRITICAL OUTAGE20-45 dakika / 20-45 minsSUPER / BACKUP_ADMIN / SYSTEM_VARIABLES_ADMIN

MySQL Accidental DELETE / DROP PITR: Emergency Point-in-Time Recovery

Point-in-Time Recovery procedure following accidental DELETE, UPDATE, or DROP statements: surgical recovery via staging instance, binlog flashback replay up to error timestamp, and zero-loss table restoration.

Related Metrics:M23M15
#mysql#pitr#point-in-time-recovery#backup#binlog#flashback#incident#data-loss

Operational Safety & Risk Notice

This runbook contains operational intervention steps; several are write-impacting (KILL, terminate, DROP, RESIZE). Verify in a staging environment first, and apply sequentially in production with verification.

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

1. Symptom & Signals

- Yanlışlıkla `DELETE FROM table;` (WHERE koşulsuz) veya hatalı `DROP TABLE / TRUNCATE` çalıştırıldı.

- Müşteri veya uygulama verisi eksik; canlı veri kaybı alarmı geldi.

- Hata zaman damgası yaklaşık olarak biliniyor (örnek: `2026-11-05 10:15:23`).

2. Business & Technical Impact

P1 Kritik Kesinti (SEV1). Veri kaybı iş operasyonlarını durdurur; yeni yazmalar devam ederse veri tabanındaki bozulma derinleşir ve üzerine yazılan verilerin kurtarılması imkansızlaşır.

3. Diagnosis & Root-Cause Analysis

🔴 HIGH RISK / IRREVERSIBLE1. **ALTIN KURAL: PANİK YOK, PRIMARY'Yİ KÖRLEMESE KAPATMAYIN!**

- Uygulama yazma trafiğini durdurun veya ilgili tabloyu kilitleyin:

sql
LOCK TABLES mydb.orders WRITE;
🟢 Read-Only2. **Binlog ve GTID Konumunu Derhal Kaydedin:**
sql
SHOW MASTER STATUS; -- File ve Position bilgisini not edin
SELECT @@GLOBAL.gtid_executed;
🟢 Read-Only3. **Kurtarma Yöntemi Seçim Matrisi:**
Mevcut Yedek DurumuÖnerilen Kurtarma YöntemiRPO / Kesinti Beklentisi
**MySQL Enterprise Backup (MEB) var**MEB restore -> temp instance -> binlog replayEn hızlı, minimum veri kaybı
**mysqldump / Logical backup var**Full restore -> temp instance -> binlog replayKüçük/orta ölçekte güvenli
**Sadece binlog var (Yedek eski)**Binlog flashback (`my2sql` / `binlog2sql`)Çok hızlı, sadece DML hatalarında geçerli

4. Remediation & Action Plan

### En Hızlı Yöntem: İzole Temp Instance ile Cerrahi PITR

#### Adım 1: Son Tam Yedeği (Full Backup) Temp Sunucuya Restore Edin

bash
# MEB (MySQL Enterprise Backup) örneği
mysqlbackup --backup-dir=/backups/full --datadir=/data/temp_restore copy-back-and-apply-log

# veya mysqldump yedeği örneği
mysql -h temp_instance -u root -p < /backups/full_2026-11-04.sql

#### Adım 2: Binlog'ları Hata Anından 1 Saniye Öncesine Kadar Uygulayın

Hata anı: `2026-11-05 10:15:23` ise stop zamanı: `2026-11-05 10:15:22`

bash
# Yöntem A: GTID tabanlı point-in-time replay
mysqlbinlog --skip-gtids --stop-datetime="2026-11-05 10:15:22" \
  /var/log/mysql/binlog.000145 /var/log/mysql/binlog.000146 | mysql -h temp_instance -u root -p

# Yöntem B: binlog2sql ile tek tablo için ters DML (Flashback)
python binlog2sql.py -h primary -u dba -p --start-datetime "2026-11-05 09:00:00" \
  --stop-datetime "2026-11-05 10:15:22" -d mydb -t orders --flashback > rollback.sql

#### Adım 3: Kurtarılan Veriyi Temp Sunucuda Doğrulayın

sql
-- temp_instance üzerinde
SELECT COUNT(*) FROM mydb.orders;
SELECT * FROM mydb.orders ORDER BY id DESC LIMIT 5;

#### Adım 4: Kurtarılan Tabloyu Production'a Güvenle Geri Yazın

bash
# Yöntem 1: Cerrahi dump alıp sadece eksik satırları aktarma
mysqldump -h temp_instance mydb orders --no-create-info --where="id IN (...)" > recovery.sql
mysql -h primary mydb < recovery.sql

# Yöntem 2: Tablo seviyesinde import
mysqldump -h temp_instance mydb orders > orders_recovered.sql
mysql -h primary mydb < orders_recovered.sql

5. Verification & Health Checks

- Satır sayısı ve veri bütünlüğünü doğrulayın:

sql
SELECT @@GLOBAL.gtid_executed;
CHECKSUM TABLE mydb.orders;

- İlgili tablonun en son işlem kimliği (Max ID) ve zaman damgasını kontrol edin.

- Uygulama servislerini kontrollü başlatarak smoke test yapın.

6. Rollback & Contingency Plan

- Geri yüklenen veride tutarsızlık görülürse, aktarılan geçici tabloyu kaldırın ve temp instance üzerindeki ham veriyi tekrar inceleyin.

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

- [ ] Tüm uygulama kullanıcılarında `sql_safe_updates = 1` zorunlu mu?

- [ ] `binlog_expire_logs_seconds = 604800` (en az 7 günlük binlog saklama)?

- [ ] Günlük tam yedek + saatlik binlog arşivleme harici S3/GCS depolamasına aktarılıyor mu?

- [ ] Production ortamında fiziksel `DELETE` yerine `SOFT DELETE` (`deleted_at`) + 7 günlük arşiv politikası uygulandı mı?

- [ ] `my2sql` / `binlog2sql` triyaj aracı tüm DBA yönetim sunucularında hazır mı?

- **İletişim & Post-Mortem:**

- P1 incident masasını açın (`#incident-response`).

- Olaydan sonraki 24 saat içinde post-mortem hazırlayın: Hangi kullanıcı, hangi servis hesabı, neden WHERE koşulu yoktu?

Engineering Triad: Diagnostic Scripts

Diagnostic scripts recommended during this runbook triage to pinpoint the root cause:

All Scripts (100)
#26 · SQLReplication

MySQL Replication Status and Lag Check

Checks IO/SQL thread state, Seconds_Behind_Source and the latest errors. Quickly verifies replica health.

#38 · SQLBackup

MySQL Binary Log Size and Retention

Shows binary log files, their total size and the retention setting. Important for disk-full prevention and the point-in-time recovery window.

More MYSQL Runbooks