Gece yarısı göç çalıştırmak, çoğu ekibin ritüel korkusudur: ya geri dönülemezse? Korkunun kaynağı genelde göçün kendisi değil, tek adımda her şeyi yapmaya kalkışmasıdır. Sütun ekleyip hemen eskisini silen, tip değiştirmeyi tek komutta yapan göçler, geri dönüşü imkânsızlaştırır. Geriye dönülebilir şema değişikliği ise bir disiplin işidir: her adım küçük, her adım geri alınabilir, veri taşınması ayrı bir adım.
Bu disiplinin ödülü, göçü artık korkunç olmaktan çıkarmaktır. Küçük adımlar, kod incelemesinde de kolay okunur; yüz satırlık bir göç dosyasını kimse ciddiye incelemez, beş satırlık her adımı herkes okur. Aşağıdaki desen, bu disiplinin en bilinen hâlidir.
Genişlet, taşı, daralt
Desen üç fazlıdır. Genişletme fazında yeni yapıyı eskisinin yanına eklersiniz; eski kod bundan etkilenmez. Taşıma fazında veriyi çift yazar, kademeli geri doldurursunuz. Daraltma fazında ise eski yapıyı yalnızca yeni kod tamamen geçtikten sonra kaldırırsınız. Örnek, eposta kolonunu e_posta'ya taşımak:
-- 1. Genişlet: yeni kolon, eski davranış korunur
ALTER TABLE kullanicilar ADD COLUMN e_posta text;
-- 2. Geri doldurma: parçalı, tek sorguda değil
UPDATE kullanicilar SET e_posta = eposta
WHERE e_posta IS NULL AND id BETWEEN 1 AND 10000;
-- 3. Kısıtı en son ekle: veri temizken
ALTER TABLE kullanicilar
ALTER COLUMN e_posta SET NOT NULL;
-- 4. Daralt: yalnız yeni kod yayındayken
ALTER TABLE kullanicilar DROP COLUMN eposta;
Kritik ayrıntı: yeni kolonu NOT NULL ile doğrudan eklemek, büyük tablolarda saniyeler süren kilitlemelere neden olur; hatta bazı sürümlerde tabloyu yeniden yazar. Kısıtları veri dolduktan sonra eklemek, süreci hem güvenli hem hızlı yapar.
Geri alınabilirlik bir komut değil bir plandır
Her göçle birlikte down göçü yazın; çalışmadığını prod'da keşfetmek pahalıdır. Ama daha önemlisi, bazı adımların geri alınmasının veri kaybı demek olduğunu kabul etmektir. Kolon sildikten sonra down göçü kolonu geri getirir, içeriği geri getiremez. Bu yüzden daraltmadan önce en az bir sürüm boyunca eski kolon yazılmaya devam etmeli ve yedek alınmalıdır. Yayın sonrası penceresi, geri dönüş penceresidir.
-- down göçü örneği: kolon varsa geri getir, veriyi yedekten doldur
ALTER TABLE kullanicilar ADD COLUMN eposta text;
UPDATE kullanicilar SET eposta = e_posta WHERE eposta IS NULL;
Uygulama tarafında çift yazarlık
Şema göçü yalnız değildir; kod da iki sürüm yaşamalıdır. Yeni kolon eklendiğinde uygulama önce iki kolona da yazar, sonra okumayı yavaşça yeniye kaydırır, en son eski kolonu bırakır. Bu, dağıtım ile göçün birbirinden bağımsız ilerlemesini sağlar: göç sırasında eski sürüm çalışıyorsa bile veri kaybolmaz. Takım olarak üç kural yeter: göçler küçük ve atomik, her göçün down göçü var, dağıtımdan önce staging'de hem up hem down denenmiş.
Bir de takvime yazılması gereken bir kural var: daraltma adımını, genişletme adımından en az bir sürüm sonraya planlayın. Kullanıcılar yeni sürüme geçmek için haftalar bekleyebilir; eski kolonu erkenden silen göç, o kullanıcıların verisini sessizce yok eder. Sabırlı şema değişikliği, hızlı şema değişikliğinden daha ucuzdur. Bu kurallar oturduğunda gece yarısı göçü ritüel değil, salı öğleden sonrası işi olur.
Okur Yorumları (0)