Ugrás a tartalomhoz
← Blog'a dön

Kesintisiz migration'lar — PostgreSQL'de online DDL kalıbı

4 saatlik bakım penceresi 2010'lardan kalma bir alışkanlık. Büyük şema değişikliklerini sıfır kesintiyle nasıl yaptığımızı anlatıyoruz.

“Bakım penceresi”, müşterinizin ilk kez daha iyi bir sağlayıcı olup olmadığını merak ettiği andır.

Hiçbir Nortinia ürünü bir şema değişikliği yüzünden kesinti yaşamadı. Bu şans değil — her Nortinia ekibinin ezbere bildiği bir kalıp. Aşağıdaki tarif, 1 GB'tan 500 GB'a kadar her büyük şema değişikliğinde işe yarar.

1. Asla tek seferde “ALTER TABLE ... DROP COLUMN” yapmayın

Klasik migration: ALTER TABLE users DROP COLUMN legacy_field. Production'da 50 GB'lık bir tabloda bu 2 dakika sürer ve sonrasındaki her sorgu bloklanır. Önerilen 4 adım: (1) kodu, sütunu hiçbir şey okumayacak şekilde güncelleyin, (2) deploy edin, (3) sonraki sürüm DROP COLUMN IF EXISTS çalıştırır — artık kimse ona dokunmuyordur, (4) yine de bir şey bozulursa geri alma kolaydır.

2. CREATE INDEX CONCURRENTLY

Düz CREATE INDEX bloklar — tablodaki yazma işlemleri indeks oluşturulana kadar bekler. CREATE INDEX CONCURRENTLY bloklamaz ama 2-3 kat uzun sürer. Biz her zaman CONCURRENTLY varyantını kullanıyoruz. Bedeli: CONCURRENTLY oluşturma kesintiye uğrarsa (örneğin bir deploy geri alınırsa) indeks geçersiz durumda kalır ve elle silinip yeniden oluşturulması gerekir.

3. Yeni sütunlar — NOT NULL tuzağı

  • ALTER TABLE users ADD COLUMN age INT NOT NULL DEFAULT 0 — PG < 11'de 100 GB'lık bir tabloda 20 dakikalık kesintiye yol açar
  • PG 11+: ADD COLUMN ... DEFAULT tabloyu yeniden yazmaz, yalnızca metadata'yı değiştirir
  • Ama: NOT NULL + CHECK kısıtı yine de yeniden yazar — kaçının
  • Doğru sıra: ADD COLUMN (nullable) → arka plan işinde backfill → ALTER COLUMN SET NOT NULL
  • Backfill: UPDATE ... WHERE id IN (SELECT id FROM users WHERE age IS NULL LIMIT 1000), döngüyle

4. Yeniden adlandırma — asla doğrudan değil

RENAME COLUMN tek bir PG ifadesidir, ancak eski adı kullanan deploy edilmiş her kod tabanı anında bozulur. Doğru kalıp: (1) yeni bir sütun ekleyin, (2) iki sütunu senkron tutan bir trigger, (3) backfill, (4) kod geçişi, (5) eski sütunu silin. Dört deploy, toplam iki hafta, sıfır kesinti. Beş dakikalık “hızlı yeniden adlandırma”, iki haftalık plandan elli kat kötüdür.

Nortinia'daki her backend mühendisi bu dört kalıbı bilir. Her migration PR'ında ilk soru şudur: “Bu online DDL mi?”. Değilse PR bloklanır. Can sıkıcı, ama 38 sunucuda sıfır kesintiyi korumanın tek yolu bu.

Bir konuyu ele almamızı ister misiniz?

Bize yazın — bu konuda gerçek deneyimimiz varsa yayımlarız.