Doküman menüsü

Sürüm 3.0.0

Yinelenen Satırları Temizleme

Her anahtar için birincil anahtarı en küçük olan satırı koruyarak yinelenen satırları tek bir GoArchive göreviyle temizleyin.

GoArchive bir tablodaki yinelenen satırları temizleyebilir: Her iş anahtarı (business key) için tek bir satır korunur, diğer tüm satırlar arşivlenir veya kalıcı olarak silinir. Bunun için yardımcı tablo, betik veya saklı yordam (stored procedure) gerekmez. Tek bir where koşulu içeren tek bir görev yeterlidir ve normal bir çalıştırmanın tüm güvenlik önlemleri geçerli olur.

Kural: En Küçük Birincil Anahtar Korunur

Yinelenen anahtarın her değeri için birincil anahtarı en küçük olan satır muhafaza edilen / korunan kayıttır (keeper). Birincil anahtarı, aynı anahtar değerine ait korunan satırdan büyük olan her satır bir yinelemedir. Korunan satırın birincil anahtarı kendisinden büyük olamayacağı için bu satır hiçbir zaman koşulla eşleşmez.

Görev

Satırları base_payment_id kolonuna göre yinelenen ve bu kolon üzerinde idx_base_payment_id indeksi bulunan bir payment tablosu için:

jobs:
  payment_dedup:
    job_type: archive
    root_table: payment
    primary_key: id
    where: >-
      payment.base_payment_id IS NOT NULL
      AND payment.id > (
        SELECT keeper.id
        FROM payment AS keeper FORCE INDEX (idx_base_payment_id)
        WHERE keeper.base_payment_id = payment.base_payment_id
        ORDER BY keeper.id
        LIMIT 1
      )
  • Dış tabloyu tablo adıyla belirtin (payment.id, payment.base_payment_id) ve iç tabloya bir takma ad (alias) verin (keeper). Kök tablo takma ad kullanılmadan sorgulanır.
  • IS NOT NULL koşulu, anahtarı olmayan satırları dışarıda bırakır. NULL hiçbir zaman NULL değerine eşit olmadığı için bu satırlar birbirinin yinelemesi sayılmaz.
  • Anahtar kolonunu indeksleyin. Alt sorgu her aday satır için bir kez çalışır. base_payment_id üzerinde bir indeks yoksa alt sorgunun her çalışması tabloyu baştan sona tarar. FORCE INDEX, sorgu iyileştiricinin (optimizer) daha kötü bir plan seçme ihtimaline karşı bu indeksi sabitler; sorgunun anlamı FORCE INDEX olmadan da aynıdır.
  • Tek bir ifade. where koşulu alt sorgular içerebilir ancak ikinci bir SQL ifadesi (statement) içeremez.

Arşivleme mi, Kalıcı Silme mi?

job_typeYinelenen Satırlara Ne Olur?
archiveHedefe kopyalanır, doğrulanır ve ardından kaynaktan silinir. Yinelenen satırlar hedefte geri alınabilir şekilde kalır
purgeKopyalanmadan kaynaktan silinir

İlk temizlik için archive türünü tercih edin: Hedef veritabanı, tam olarak hangi satırların kaldırıldığının kaydını tutar. archive türü, tablonun hedef şemada uyumlu bir yapıyla bulunmasını gerektirir ve bu koşul ön kontrollerde denetlenir. Kalıcı silme (purge) görevi ise goarchive purge komutuyla çalıştırılır.

Görevi Çalıştırın

goarchive validate -c archiver.yaml --job payment_dedup
goarchive dry-run  -c archiver.yaml --job payment_dedup
goarchive archive  -c archiver.yaml --job payment_dedup

Gerçek çalıştırmadan önce where koşulunun tam olarak yinelenen satırları seçtiğini doğrulayın. dry-run koşulla eşleşen satır sayısını yazdırır; bu sayıyı kendi yaptığınız yineleme sayımıyla karşılaştırın:

SELECT COALESCE(SUM(n - 1), 0) FROM (
  SELECT COUNT(*) AS n FROM payment
  WHERE base_payment_id IS NOT NULL
  GROUP BY base_payment_id
) AS g;

Tablonun tamamını kapsayan bir görevde iki sayı birbirine eşit olmalıdır. Eşit değilse where koşulu amaçladığınız şeyi ifade etmiyordur: Çalıştırmadan önce koşulu düzeltin. dry-run kök kayıtların okunmasına ait sorgu planını da gösterir; böylece alt sorgunun indeksi kullandığını teyit edebilirsiniz.

Yığınlarla İşleme Burada Neden Güvenlidir?

Çalıştırma, yinelenen satırları birincil anahtar sırasına göre ve her seferinde bir yığın olarak okur. Sonraki yığınlar henüz işlenmemişken önceki yığınları siler. Bu işlem korunan satırı hiçbir zaman değiştirmez: Bir yinelemenin silinmesi, o anahtar değerinde birincil anahtarı en küçük olan satırın hangisi olduğunu değiştirmez. Bu nedenle her yığının where koşulu, çalıştırmanın başında seçeceği satırların aynısını seçer.

Büyük Tablolar

Büyük bir tabloda where koşuluna bir birincil anahtar aralığı ekleyin ve bu aralığı her çalıştırmada ileri kaydırın (AND payment.id BETWEEN 1 AND 10000000). Böylece her çalıştırma kısa sürer, sayım maliyeti düşük kalır ve aralıklar arasında işlemi durdurabilirsiniz.

Aralık kullanıldığında sayım sonucu, yukarıdaki tablo geneli sayının o aralığa düşen payıdır. Tüm aralıkların payları toplandığında tablo geneli sayıya ulaşılır. Bir aralığın sayımını, aynı aralıkla sınırlandırılmış bir GROUP BY sorgusuyla karşılaştırmayın. Alt sorgu her anahtarın korunan satırını tablonun herhangi bir yerinde bulur. Dolayısıyla, bir aralıktaki anahtarların asıl korunan kaydı (keeper) daha önceki bir aralıkta bulunuyorsa, o aralık, aralık filtreli bir GROUP BY sorgusunun bildirdiğinden daha fazla yineleme içerir.

Replikalarda gecikme oluşursa silme hızını batch_delete_size ve delete_sleep_seconds ayarlarıyla düzenleyin (Yığın İşleme ).

Geçerli Sınırlar

  • Soğuk veri (cold data). Görev çalışırken uygulamanın yeni yinelemeler yazmasına veya korunan satırları silmesine izin vermeyin (Sınırlar ve Kısıtlamalar ).
  • Alt tablolar. Başka tablolar yinelenen satırları içeren tabloya yabancıl anahtar (foreign key) ile başvuruyorsa, bu tabloları relations altında tanımlayın. Böylece bu tablolardaki satırlar her yinelemeyle birlikte taşınır. Ön kontroller, gelen yabancıl anahtarları kapsanmayan bir görevi reddeder.
  • Birincil anahtar. Yukarıdaki where koşulu tek kolonlu bir anahtarı karşılaştırır. Bileşik anahtar (composite key) kullanan tablolarda karşılaştırmanın anahtarın tüm kolonlarını kapsaması gerekir.