İçeriğe geç
Muhammet Şafak
en
Soran: Furkan Cevaplandı:

PostgreSQL tablo partitioning'e sıfır kesinti ile nasıl geçerim?


Soru

SaaS uygulamamızda kullanıcı hareket loglarını tuttuğumuz `audit_logs` tablosu aylık 50M satır büyüyor; tablo büyüdükçe basit `select`'ler bile yavaşladı. PostgreSQL'in declarative partitioning'iyle bu tabloyu `created_at`'e göre aylık partition'lara ayırmak istiyorum. Canlı veriyi sıfır kesinti ile bu yeni yapıya nasıl taşırım? İndeksler ve foreign key bağımlılıkları bundan nasıl etkilenir?

Cevap

Kısa cevap: Aylık 50M satır gerçekten büyük — partitioning burada doğru hamle. created_at üzerinden aylık RANGE declarative partitioning kullan; geçişi sıfır kesinti için aşamalı yap.

Önce şu sağlamayı yapmakta fayda var: 50M/ay gerçek bir hacim, “verim gerçekten büyük mü yoksa kötü mü modellenmiş” sorusunun cevabı burada net — gerçekten büyük. Partition mantıklı.

  1. Native declarative RANGE ile parçala. Yeni bir partitioned parent (PARTITION BY RANGE (created_at)) oluştur ve aylık partition’ları ATTACH et. Eski monolitik tablonun aksine, sorgu sadece ilgili aya değer; partition pruning sayesinde basit select’ler tekrar hızlanır.
  2. Geçişi sıfır kesinti ile yap. Yeni parent’ı kur, partition’ları bağla, sonra geçmiş veriyi batch’ler hâlinde (örn. 50k’lık dilimlerle, off-peak) partition’lara backfill et. Bu sırada uygulama yazmaya devam etsin: ya yeni yapıya yönlendiren bir trigger/view kullan ya da hem eskiye hem yeniye dual-write yap. Backfill bitince isimleri tek bir transaction içinde takasla — kesinti yok.
  3. İndeksler partition başına oluşur. Parent üstünde tanımladığın indeksi Postgres her partition’a otomatik yayar (propagate). Yani global tek bir B-tree değil, her ay için ayrı indeks; bu aslında işine yarar, eski ayların indeksi sıcak veriyi yormaz.
  4. UNIQUE ve FK kuralını unutma. Partitioned tabloda global bir UNIQUE/PK, partition anahtarını içermek zorundadır — yani PK’in (id, created_at) olur. Tabloya referans veren FK’ler de bundan etkilenir; modern PG’de partitioned tabloya FK kurmak çalışır ama sürümünü doğrula.
  5. Yaşam döngüsünü pg_partman’a bırak. Gelecek ayların partition’larını otomatik oluşturması için pg_partman kullan; retention için eski partition’ları DETACH + DROP ile sil — DELETE taramasından çok daha ucuz, anında.

Sonuç: created_at üzerinde declarative RANGE, batch’li backfill, her unique key’de partition anahtarı, yaşam döngüsü için pg_partman. Geçişi dual-write + tek transaction’lık isim takasıyla kurarsan canlı sistem hiç durmaz. Bu tür DB derinliklerine girmeden önce ölçeklenme ihtiyacının gerçekten “büyük veri” mi olduğunu netleştir; bu vakada öyle.

İlgili Yazılar

Etiketler: #veritabanı#postgresql#ölçekleme
Paylaş:

Yorumlar

Yorum yapmak için GitHub hesabınızla giriş yapmanız yeterli. Yorumlar GitHub Discussions üzerinde saklanır.

Diğer Sorular

Tüm sorular

Sitede Ara

Yazı, proje ve sayfalarda arama yapmak için yazmaya başlayın.

Esc ile kapat Pagefind ile güçlendirildi