Database Engineering

Şemalandırma Kesintisi Olmadan Eski Monolitik Uygulamalar İçin Şema Göçü: Şemalandırma Olmayan Bir Strateji

Veri Mühendisliği dünyasında, devasa ve eski bir monolitik uygulamanın şemasını geliştirmek kadar zorlu bir meydan okuma yoktur. Tablo silme, sütun ekleme veya kısıtlama değiştirme gibi geleneksel yaklaşımlar genellikle veritabanını dakikalar veya hatta saatler boyunca kilitleyerek, iş paydaşlarının onaylamaktan çekindiği bir bakım penceresine yol açar. Ayrıca, birçok kuruluş mikro hizmetlere veya veritabanı şemalandırmasına hazır olmadığı kısıtlamaları altında çalışmaktadır.

Bu kılavuz, eski monolitik sistemler için kesintisiz şema göçlerini uygulamak için sağlam bir stratejiyi detaylandırmaktadır. Aşamalı yayınlamalar, çift yazma desenleri ve bloklamayan DDL işlemlerinden yararlanarak, şemalandırma yapmadan ve canlı trafiği kesintiye uğratmadan veri modelinizi güvenle geliştirebilirsiniz.

Üç Aşamalı Göç Stratejisi

Kesintisiz göçlerin temel felsefesi, kodun dağıtımını şema değişikliklerinin dağıtımından ayırmaktır. Sütun eklemek, sütun adını değiştirmek veya bir indeks değiştirmek gibi önemli herhangi bir şema değişikliği için genellikle üç aşamalı bir yaklaşım izlenir: Genişlet, Göç ve Söndür.

Genişlet aşamasında, mevcut uygulama kodu ile geriye uyumluluğu koruyarak gelecekteki durumu karşılayacak şekilde şema üzerinde değişiklik yapılır. Göç aşaması, yeni veri gereksinimlerini yazmaları engellemeden doldurmayı içerir. Son olarak, Söndür aşaması, tüm trafiğin yeni yapıyı kullandığından emin olduktan sonra eski desenleri temizler.

Null Olamayan Sütunlar Ekleme

Null olamayan bir sütun eklemek klasik bir tuzaktır. Eğer sadece ALTER TABLE users ADD COLUMN status VARCHAR(20) NOT NULL; komutunu çalıştırırsanız, çoğu veritabanı mevcut tüm satırları taramaya ve varsayılan bir değerle doldurmaya çalışarak tabloyu kilitleyebilir ve zaman aşımına neden olabilir.

Bunun yerine, başlangıçta null değerlere izin verin, mevcut satırları arka planda güncelleyin ve ardından kısıtlamayı uygulayın. İşte aşamalı yaklaşımın SQL'deki görünümü:

-- Aşama 1: Genişlet
-- Hemen kilitleme veya geri doldurma işlemi yaşamamak için sütunu null olarak ekleyin
ALTER TABLE users ADD COLUMN status VARCHAR(20) NULL;

-- Uygulama kodunu hem 'eski_status' hem de 'yeni_status' sütunlarına yazacak şekilde güncelleyin
-- veya uygulama kayıtları doğal olarak güncelledikçe 'status' sütununu doldurun.

Uygulama mantığınızda, bir kullanıcı kaydı güncellendiğinde yeni sütuna yazılmasını sağlayın. Dokunulmamış eski veriler için bir arka plan işi çalıştırarak verileri geri doldurabilirsiniz:

-- Aşama 2: Göç (Arka Plan Görevi)
-- Uzun işlemlerden kaçınmak için mevcut null değerleri parçalar halinde güncelleyin
UPDATE users 
SET status = 'aktif' 
WHERE status IS NULL 
AND id > 10000 
AND id <= 20000; -- Döngülerle ve toplu işleme ile tekrarlayın

Arka plan görevi sütunun tamamen doldurulduğunu onayladığında, kısıtlamayı güvenle uygulayabilirsiniz:

-- Aşama 3: Söndür
ALTER TABLE users ALTER COLUMN status SET NOT NULL;
-- Eğer çift yazma sütununuz varsa, şimdi eskisini silin
ALTER TABLE users DROP COLUMN eski_status;

Tabloları ve Sütunları Yeniden Adlandırma

Yeniden adlandırma genellikle yüksek riskli kabul edilir çünkü mevcut sorguları hemen bozar. Bunu hafifletmek için görünümleri (views) soyutlama katmanı olarak kullanın. Bir sütunu veya tabloyu yeniden adlandırırken, eskisini koruyarak yeni bir ad oluşturun. Veritabanı şemasını, görünümün yeni fiziksel tabloya işaret etmesi için veya yeni sorgularda yeni sütun adını kullanmak için güncelleyin.

Örneğin, user_id'yi account_id olarak yeniden adlandırıyorsanız:

-- Adım 1: Yeni sütunu ekleyin
ALTER TABLE orders ADD COLUMN account_id BIGINT;

Kod tabanınızı account_id ile okuma/yazma yapacak şekilde güncelleyin. Kod dağıtımı doğrulandıktan sonra verileri geri doldurabilir ve sonunda eski sütunu silebilirsiniz. Bu, yeni kod başarısız olursa veritabanının eski kodla uyumlu bir durumda kalmasını sağlar.

Veritabanına Özgü Özelliklerden Yararlanma

Modern veritabanı sistemleri, bu göçlerde yardımcı olmak için özel özellikler sunar. Örneğin, PostgreSQL indeksler ve benzersiz kısıtlamalar için tam tablo kilidi gerektirmeyen CONCURRENTLY işlemlerine izin verir. Mümkün olduğunda bunlardan her zaman yararlanın.

-- PostgreSQL'de bu, yazmaları engellemeden indeks oluşturulmasına olanak tanır
CREATE INDEX CONCURRENTLY idx_orders_account ON orders(account_id);

Göç betiklerinizi, üretim verisi hacmini yansıtan bir ön test (staging) ortamında her zaman test edin. Küçük bir veri setinde 10 dakikalık bir göç ile terabayt ölçeğinde bir veri setinde 6 saatlik bir göç arasındaki fark büyüktür.

Sonuç

Eski monolitik sistemleri göç ettirmek, şemalandırma veya karmaşık mikro hizmet mimarileri gibi aşırı çözümler gerektirmez. Genişlet-Göç-Söndür desenine bağlı kalarak ve kilitleme mekanizmalarına dikkat ederek, veri mühendisleri sürekli bir gelişimi sürdürebilir. Bu yaklaşım riski azaltır, yüksek kullanılabilirliği korur ve ekibinizin uygulama kodu ile aynı hızda veri modelinde değişiklik yapmasına olanak tanır. Unutmayın, amaç sadece şemayı değiştirmek değil, müşterilerinizi asla bekletmeden bunu yapmaktır.

Share: