Postgres'ta sık yapılan DB şeması değişikliği hataları
(postgres.ai)Here is a summary of the common database schema change mistakes, translated and structured in Korean:
Eşzamanlılıkla ilgili hatalar
- Kilit alınamaması
- Tek seferde çok fazla satırı güncellemek
- Münhasır kilit aldıktan sonra işlemi uzun süre açık tutmak
Adımların doğruluğuyla ilgili hatalar - mantıksal sorunlar
- Beklenmeyen şema sapmaları
- Şema ile uygulama kodunun uyumsuzluğu
- Beklenmeyen veriler
Diğer hatalar
statement_timeoutsüresine ulaşılması- Büyüyebilecek bir tabloda 4 baytlık tamsayı birincil anahtar kullanmak
VACUUMdavranışını ve bloat riskini göz ardı etmek
Case 1. Şema uyuşmazlığı
- Geliştirme/test ortamında çalıştı ama QA/Staging/Production'da başarısız oldu
- Neden belirlendikten sonra iş akışı iyileştirilerek çözülmeli
Case 2. IF [NOT] EXISTS yanlış kullanımı
- Şema uyuşmazlığı hatalarını
IF NOT EXISTSile görmezden gelmeye çalışmayın - Sorunun kök nedenini bulup çözmek gerekir
Case 3. statement_timeout süresine ulaşılması
- Tüm değişiklikleri büyük veri hacmiyle test ederek bunu önceden tespit edin
Case 4. Sınırsız büyük ölçekli değişiklikler
- Çok fazla satırı tek bir transaction içinde değiştirmek diğer transaction'ları etkiler
- Checkpointer ayarlı değilse aşırı WAL verisi üretilebilir
- Disk yazma doygunluğu nedeniyle genel performans düşüşü yaşanabilir
VACUUM/bloat sorunları oluşabilir- İşlemleri batch'lere bölün ve
VACUUMyönetimini yapın
Case 5. Münhasır kilit aldıktan sonra transaction içinde beklemek
BEGIN/ALTER TABLE/COMMITarasında başka işler yapılırsa kilit uzun süre tutulur- Münhasır kilit alındıktan sonra transaction mümkün olduğunca hızlı bitirilmeli
Case 6. DDL + büyük hacimli DML içeren transaction
- DDL aşamasında alınan kilit, DML aşamasına kadar uzun süre tutulur
- DDL ve DML'yi ayrı transaction/migration adımlarına bölün
Case 7. Münhasır kilit alma bekleyişi nedeniyle diğer oturumların bloklanması
- Autovacuum, wraparound önleme modundayken DDL'e yield etmez
- Kilit alma bekleyişi sırasında
SELECTbile bloklanabilir lock_timeoutdeğerini düşük tutun ve retry mantığı kurun
Case 8. FK oluştururken dikkat edilmesi gerekenler
- Büyük tabloda FK oluştururken referenced tablonun taranması zaman alır
not validseçeneğiyle FK'yi tanımlayıp ayrı bir transaction'da validate edin
Case 9. FK silerken dikkat edilmesi gerekenler
- İki tablonun da kilitlenmesi gerektiğinden
lock_timeoutretry mantığı gerekir
Case 10. CHECK kısıtı eklerken dikkat edilmesi gerekenler
- Tüm tablo taranacağı için FK'ye benzer 2 aşamalı yaklaşım kullanın
Case 11. NOT NULL eklerken dikkat edilmesi gerekenler
- Postgres 11 öncesinde yeni kolona
NOT NULLeklenince tablo taraması olur - Postgres 11'den itibaren
NOT NULL DEFAULTkolon ekleyerek bu çözülebilir - Postgres 12'den itibaren
CHECKkısıtı eklenerekNOT NULLayarlanabilir
Case 12. Kolon veri türünü değiştirirken dikkat edilmesi gerekenler
- Tüm tablonun yeniden yazılması gerekebilir
- Yeni kolon ekleyip trigger ile veriyi kopyalayan bir yaklaşım gerekebilir
Case 13. CREATE INDEX yaparken dikkat edilmesi gerekenler
- OLTP'de
CREATE INDEX CONCURRENTLYkullanılmalı - Benzersiz indeks oluşturma başarısız olursa invalid indeksi temizlemek gerekir
Case 14. DROP INDEX yaparken dikkat edilmesi gerekenler
- Kilit alma sorunları nedeniyle
DROP INDEX CONCURRENTLYkullanın
Case 15. Nesne adını değiştirirken dikkat edilmesi gerekenler
- Uygulama kodu ile DB şeması arasında uyumsuzluk olmaması için dağıtım sırası ayarlanmalı
Case 16. DEFAULT değeri olan kolon eklemek
- PG 11 öncesinde tüm tablo yeniden yazılır
- PG 11'den itibaren DEFAULT değeri olan kolon eklemek hızlandı
Case 17. CREATE INDEX CONCURRENTLY başarısız olduğunda kalıntıların temizlenmesi
- Başarısız olursa invalid indeks kalır; yeniden denemeden önce temizlenmeli
Case 18. Büyük tabloda 4 baytlık tamsayı birincil anahtar kullanmak
int8kullanılmalı. Çoğu framework zatenint8kullanıyor.
Öneriler
- Gerçekçi veri boyutlarıyla test yapın
- Münhasır kilitlerin ne kadar süre tutulduğunu kontrol edin
- Dağıtım otomasyonunu iyileştirin
- Başkalarından öğrenin ve bilgiyi paylaşın
GN⁺'nin görüşü
Bu yazı, gerçek DB şeması değişiklikleri sırasında karşılaşılabilecek çeşitli hataları ve dikkat edilmesi gereken noktaları iyi derliyor. Özellikle münhasır kilitle ilgili sorunlardan sıkça bahsediliyor; bu da büyük veri tabanlarında çok daha ciddi problemlere yol açabilir.
Geliştiricilerin kolayca gözden kaçırabildiği FK, NOT NULL, indeksler gibi konulardaki dikkat noktaları da somut biçimde anlatılıyor. Postgres'in sürümlere göre gelen iyileştirmelerini anlamak ve kullanmak da faydalı görünüyor.
En önemlisi, gerçekçi veri boyutlarıyla kapsamlı test yapmak ve dağıtım otomasyonunu geliştirmek, şema değişikliği riskini en aza indirmenin anahtarı. Test ve dağıtım otomasyonu için Database Lab Engine gibi araçlardan yararlanmak da iyi bir fikir olabilir.
Bu tür faydalı ipuçlarını paylaşan teknik blog yazılarının daha da çoğalması güzel olur. Bu bilgiler ne kadar yaygınlaşırsa, veritabanı ile çalışan geliştiricilerin yetkinliklerinin artmasına o kadar yardımcı olur.
Henüz yorum yok.