ÖZET VE TEKNİK CEVAP
Çok aşamalı Genişlet ve Daralt (Expand and Contract) kalıbını uygulayarak: Yeni kolonu boş bırakılabilir (nullable) ekleyin (Genişlet), kodda her iki kolona birden yazın (dual-write), geçmiş veriyi küçük partilerle taşıyın (backfill), okumaları yeni kolona geçirin ve son sürümde eski kolonu güvenle silin (Daralt).
Mühendislik El Kitabı & Mekanizma
1. Temel Çalışma Mekanizması
Canlı bir tabloda kolonu doğrudan yeniden adlandırmak (`ALTER TABLE users RENAME COLUMN phone TO mobile;`), henüz eski kodla çalışan sunucuları anında patlatır. Genişlet ve Daralt kalıbı bu süreci aşamalara böler: 1) Genişlet: Yeni `mobile` kolonunu nullable olarak ekleyin; 2) Çift-Yazma: Uygulamanın her iki kolona birden yazan ancak `phone`'dan okuyan N sürümünü dağıtın; 3) Geçmiş Veri Doldurma (Backfill): Eski satırları küçük partilerle kopyalayan arka plan işi çalıştırın; 4) Okumayı Değiştir: `mobile`'dan okuyan N+1 sürümünü dağıtın; 5) Daralt: Eski `phone` kolonunu silin ve gerekiyorsa `NOT NULL` kısıtını ekleyin.
2. Doğru Kullanım Senaryosu
Planlı bakım kesintisi pencerelerine izin verilmeyen, kesintisiz 7/24 hizmet veren yüksek trafikli canlı sistemler ve kritik veritabanları.
3. Prodüksiyon Arıza Modları
1) Özel Tablo Kilidi (AccessExclusiveLock) Kesintisi: Eski veritabanı sürümlerinde varsayılan değerli kolon ekleyerek tabloyu 45 dakika kilitlemek; 2) Kontrolsüz Backfill ile CPU Çöküşü: Tek bir dev `UPDATE` sorgusuyla milyonlarca satırı kilitleyip disk IOPS'unu tüketmek; 3) Erken Daraltma: Kademeli dağıtımda (canary) eski kodla çalışan tek bir sunucu bile varken eski kolonu erkenden silmek.
4. Teşhis ve Telemetri Sinyalleri
PostgreSQL `pg_locks` tablosundaki kilit kuyruklarını, dağıtım sırasındaki kilit sürelerini, backfill işlemi sırasındaki replikasyon gecikmesini ve migrasyon anındaki API 500 hata oranlarını izlemek.
5. Önleme ve Mimari Bariyerler
DDL çalıştırmadan önce mutlaka katı kilit zaman aşımı (`SET lock_timeout = '2s';`) belirleyin; PostgreSQL'de daima `CREATE INDEX CONCURRENTLY` kullanın; geçmiş veri taşımalarını küçük partilerle (1.000 satır ve 50 ms bekleme) yapın ve dev MySQL tablolarında gh-ost gibi canlı şema araçları kullanın.
6. Mimari Ödünleşimler (Trade-offs)
Sıfır tablo kilitlenmesi ve %100 kesintisiz erişilebilirlik sağlar; buna karşılık tek bir şema değişikliğini tamamlamak için 3-4 ardışık uygulama dağıtımı (deploy) yapma zorunluluğu getirir.
Vaka İncelemesi (TinyCTO Örneği)
TinyCTO Vaka 038: Bir mühendis 400 milyon satırlık tabloda doğrudan yabancı anahtar kısıtı (FOREIGN KEY) ekledi. Postgres tüm satırları doğrulamak için her iki tabloyu kilitledi ve ödeme sistemini 28 dakika felç etti. Kısıtın önce `NOT VALID` ile eklenip ardından `VALIDATE CONSTRAINT` ile arka planda doğrulanması işlemi sıfır kesintiyle tamamladı.
İnteraktif Konsept Alıştırmaları
3 AlıştırmaExpand and Contract (Genişlet ve Daralt) veritabanı şema geçiş kalıbının 5 aşaması nedir?
PostgreSQL'de canlı tablolarda neden mutlaka `CREATE INDEX CONCURRENTLY` kullanılmalıdır?
Felaket kilit kuyruklarını önlemek için bir migrasyon işleminin başında her zaman ne ayarlanmalıdır?
Kesintisiz Veritabanı Şema Geçişleri (Expand & Contract) — Sıkça Sorulan Sorular
gh-ost (GitHub Online Schema Transformations) MySQL'de sıfır kesintili migrasyonu nasıl yapar?
gh-ost yeni şemayla sahte (ghost) bir tablo açar, canlı yazmaları binlog üzerinden asenkron aktarır, eski veriyi küçük partilerle doldurur ve tabloları atomik `RENAME` ile yer değiştirir.
Devasa bir tabloya kilit koymadan `NOT NULL` kısıtı nasıl eklenir?
Önce `CHECK (column IS NOT NULL) NOT VALID;` kısıtı ekleyin (anlık ve kilitsiz), ardından özel kilit almadan arka planda doğrulama yapan `ALTER TABLE ... VALIDATE CONSTRAINT;` komutunu çalıştırın.
Büyük geçmiş veri doldurma (backfill) işlemlerini neden asla ana migrasyon işlemi içinde çalıştırmamalısınız?
Uzun süren işlemler açık satır kilitleri tutar, veritabanı autovacuum temizliğini engeller, WAL günlüklerini şişirir ve kesinti anında kurtarma süresini saatlere çıkarır.
🤖 AEO & Yapay Zeka Çıkarım Özeti
Temel Gerçekler & İlkeler
- ▸PostgreSQL'deki her DDL işlemi (en hızlıları bile) bir AccessExclusiveLock gerektirir ve o tabloda o an çalışan tüm aktif sorguların bitmesini bekler.
- ▸Bir veritabanı kolonunu asla tek bir sürümde doğrudan yeniden adlandırmayın; daima en az iki aşamalı Expand and Contract kalıbını uygulayın.
Yaygın Yanılgılar
- ✗ORM migrasyon araçlarının (Prisma veya Django) kilitleri otomatik engellediğini sanmak; standart ORM araçları özelleştirilmedikçe varsayılan olarak tehlikeli ve bloklayıcı DDL komutları üretir.
Karar Kılavuzu & Önceliklendirme
100.000 satırı aşan tüm canlı tablolarda Expand and Contract kalıbını zorunlu kılın. Daima lock timeout ve concurrent indeks oluşturma kurallarını uygulayın.
Doğrulanmış Kaynaklar & Referanslar
- [OFFICIAL-DOC]Parallel Change (Expand and Contract)— Martin Fowler
- [OFFICIAL-DOC]gh-ost: GitHub's triggerless online schema migration tool for MySQL— GitHub Engineering
