MySQL'de Eski Verileri Arşivleme
GoArchive ile Sakila veri tabanı üzerinde uçtan uca uygulama: kurulum, ön uçuş kontrolleri, tekil ve ilişkisel senaryolar, doğrulama

Giriş ve problem tanımı
Büyük ölçekli kurumsal veri tabanı (database) yönetiminde en kritik operasyonel zorluklardan biri, zamanla devasa boyutlara ulaşan hareket (transactional) tablolarının yönetimidir. Kontrolsüz büyüyen veri tabanları, yedekleme (backup) ve geri yükleme (restore) sürelerinin uzamasına, bellek ve disk kaynaklarının tükenmesine, dizin (index) verimsizliklerine ve replikasyon gecikmelerine (replication lag) yol açar.
Bu tür tabloların temizlenmesinde geleneksel yaklaşımlar (örneğin kontrolsüz DELETE sorguları veya geçici kabuk / shell betikleri) üretim ortamlarında ciddi riskler barındırır:
- Kilitlenme (Locking) Problemleri: Milyonlarca satırlık büyük silme işlemleri tabloları kilitler ve canlı işlemleri tıkar.
- Replikasyon Gecikmesi (Replication Lag): Üretilen yoğun işlem günlükleri (binary logs), replikasyon düğümlerinin (read replicas) ana sunucunun (source/primary) çok gerisinde kalmasına sebep olur.
- Veri Bütünlüğü (Data Integrity) Kaybı: Doğrulama adımı olmadan yapılan işlemler, silinen verinin hedefe eksik veya hatalı aktarılmasına yol açabilir.
GoArchive , kurumsal MySQL ve Percona Server ortamlarında veri arşivleme (archiving), temizleme (purge) ve yalnızca kopyalama (copy-only) süreçlerini sıfır veri kaybı ve minimum üretim etkisi prensibiyle otomatikleştiren, Go diliyle geliştirilmiş modern bir arşivleme aracıdır.
Bu blog yazısında, GoArchive’ın mimari yaklaşımını, E2E test ortamındaki docker compose topolojisini ve endüstri standardı örnek Sakila veri tabanını (database) kullanarak adım adım inceleyeceğiz.
Mimari ve test topolojisi: Docker Compose altyapısı
GoArchive, test ve doğrulama süreçlerinde gerçekçi bir küme (cluster) topolojisi kullanır. Projenin tests/compose.yml dosyasında tanımlanan mimari, gerçek bir üretim ortamının minyatür bir modelini sunar:
| Düğüm | Rol | Port | Veri tabanı |
|---|---|---|---|
db1 | Kaynak (source) | 3305 | sakila |
db2 | Hedef (destination) | 3307 | sakila_archive |
db3 | Replika (replica), GTID ile db1‘i izler | 3308 | — |
GoArchive db1 üzerinden okur, db2 üzerine kopyalar, db2 üzerinde doğrular ve db1 üzerinden parçalar hâlinde siler. Silme sırasında db3 üzerindeki replikasyon gecikmesini izler.
Düğüm tanımları ve görevleri
- Kaynak Düğüm (Source -
db1, Port 3305): Aktif Sakila veri kümesinin bulunduğu ana veri tabanı (source database). Arşivlenecek veriler buradan okunur ve doğrulandıktan sonra silinir. - Hedef Düğüm (Destination -
db2, Port 3307): Arşiv verilerinin taşındığı hedef veri tabanı (destination database:sakila_archive).Önemli Not:
db2konteyneri kasten+03:00saat diliminde (time zone) çalıştırılır. Kaynak (db1) iseUTC‘dedir. Bu durum, GoArchive’ın oturum bazlıtime_zone='+00:00'sabitlemesini ve zaman damgası (timestamp) değerlerini bölgesel saat dönüşümlerinden bağımsız olarak birebir doğrulayabilme kabiliyetini sınar. - Replika Düğümü (Replica -
db3, Port 3308):db1sunucusunu GTID (Global Transaction Identifier) üzerinden takip eden canlı kopya (replica). GoArchive, silme işlemleri sırasında replikasyon gecikmesini (replication lag) izleyerek gecikme belirli bir eşiğin üzerine çıktığında silme işlemlerini otomatik olarak duraklatır (throttling / pacing).
İsimlendirilmiş birimler (Named Volumes)
tests/compose.yml yapılandırmasında veri dizinleri için ana makine bağlama noktaları (bind mounts) yerine Docker isimlendirilmiş birimleri (named volumes: db1_data, db2_data, db3_data) tercih edilmiştir. Bu sayede işletim sistemi uyumsuzlukları (özellikle macOS altındaki büyük/küçük harf duyarlılığı ve dosya sistemi eşzamanlama kısıtları) engellenmiş, gerçekçi Linux POSIX dosya sistemi performansı garanti altına alınmıştır.
Ortamın hazırlanması ve ilk kurulum
Uygulamalı adımlara geçmeden önce test ortamını ayağa kaldırmak ve Sakila şemasını oluşturmak için aşağıdaki adımları izliyoruz:
# 1. Ortam değişkenleri dosyasını (.env) hazırlayın
cp tests/dot.env tests/.env
# 2. Docker konteynerlerini (db1, db2, db3) başlatın ve Sakila veri tabanını yükleyin
./scripts/run-tests.sh --setup
# 3. GoArchive ikili dosyasını (binary) derleyin
go build -o bin/goarchive ./cmd/goarchive
Kurulum tamamlandığında kaynak (3305), hedef (3307) ve replika (3308) servisleri hazır hâle gelir.
GoArchive güvenlik döngüsü ve ön uçuş kontrolleri (Preflight Checks)
GoArchive, hiçbir veri işlemine başlamadan önce veri tabanı şemasını ve yapılandırma dosyasını (configuration file) çok sıkı bir ön uçuş denetiminden (preflight check) geçirir. Hatalı yapılandırmalar daha ilk saniyede tespit edilerek operasyon durdurulur (fail-fast prensibi).
Öne çıkan kritik denetimler şunlardır:
- Depolama Motoru Denetimi (
STORAGE_ENGINE_CHECK): Arşivlenecek tüm tablolarınInnoDBmotoruna sahip olması zorunludur. İşlemsel (transactional) bütünlük sağlamayan motorlar reddedilir. - Bileşik Birincil Anahtar Kısıtı (
COMPOSITE_PK_CHECK): GoArchive, satırları tekil bir birincil anahtar (single-column primary key) üzerinden izler ve siler. Bileşik anahtara (composite primary key) sahip tablolar (örneğin Sakila’dakifilm_actorveyafilm_categorytabloları) doğrudan silme aşamasında hedef dışı satırların silinmesi riskini doğurabileceğinden koruma amacıyla reddedilir. - Yabancı Anahtar Kapsam Denetimi (
FK_COVERAGE_CHECK): Arşivlenen bir tabloya, arşiv grafiği dışındaki başka bir tablodan yabancı anahtar (foreign key) referansı varsa ve bu ilişki yapılandırmada çözülmemişse operasyon durdurulur. Aksi hâlde kaynakta yetim kayıtlar (orphan records) veya kısıt ihlalleri oluşacaktır. - İç Yabancı Anahtar Kapsamı (
INTERNAL_FK_COVERAGE): Arşiv grafiğinde yer alan iki tablo arasındaki tüm yabancı anahtar (foreign key) ilişkileri açıkça ebeveyn-çocuk (parent-child) ağaç yapısı olarak tanımlanmalıdır.- Örnek (GDPR Elması Kısıtı): Sakila’da
customer -> rental -> paymentilişkisinde,paymenttablosu hemrentalhem decustomertablosuna bağlıdır (elmas topolojisi). GoArchive katı bir ağaç hiyerarşisini şart koştuğu için bu elmas yapıtest11örneğinde görüleceği üzereINTERNAL_FK_COVERAGEhatası ile güvenle engellenir. En doğru çalışan modelrental -> paymenthiyerarşik modelidir.
- Örnek (GDPR Elması Kısıtı): Sakila’da
- Silme Tetikleyicisi Uyarısı (
DELETE_TRIGGER_CHECK): Kaynak tablolardaBEFORE/AFTER DELETEtetikleyicileri (triggers) varsa, GoArchive beklenmeyen yan etkileri önlemek için işlemi durdurur. Operatörün bilerek devam etmesi için--force-triggersbayrağı (flag) gereklidir.
Senaryo 1: Tekil tablo ve yüksek hacimli arşivleme (payment)
İlk senaryomuzda Sakila veri tabanındaki en yoğun hareket tablosu olan payment (ödeme) tablosunun arşivlenmesini ele alacağız. Bu senaryoda yığın (batch) mekanizmasını, hız sınırlandırmayı (throttling/pacing) ve iki farklı doğrulama (verification) yöntemini inceleyeceğiz.
1. Yapılandırma dosyası: test03_payment_batch.yaml
Aşağıdaki yapılandırma, payment_id <= 2000 koşulunu sağlayan satırları 100’lük yığınlar (batch size) hâlinde kopyalayıp 20’şerlik alt parçalar (batch delete size / chunks) hâlinde siler:
source:
host: 127.0.0.1
port: 3305
user: root
password: ${MYSQL_ROOT_PASSWORD}
database: sakila
destination:
host: 127.0.0.1
port: 3307
user: root
password: ${MYSQL_ROOT_PASSWORD}
database: sakila_archive
safety:
disable_foreign_key_checks: true
jobs:
archive-payment-rows:
root_table: payment
primary_key: payment_id
where: "payment_id <= 2000"
processing:
batch_size: 100 # Her çevrimde aktarılacak satır adedi
batch_delete_size: 20 # Kaynakta silinirken kullanılacak alt parça boyutu
sleep_seconds: 0.2 # Yığınlar arası bekleme süresi
delete_sleep_seconds: 0.2 # Silme parçaları arası bekleme süresi
2. Adım adım komut satırı iş akışı
Adım 2.1: Tanımlı işleri listeleme (list-jobs)
Yapılandırma dosyasındaki geçerli iş emirlerini (jobs) listeler:
goarchive list-jobs --config test03_payment_batch.yaml
Adım 2.2: Çalışma planını çıkarma (plan)
Hangi tabloların hangi sırada işleneceğini, ebeveyn-çocuk bağımlılıklarını ve yaklaşık satır sayılarını gösterir:
goarchive plan --job archive-payment-rows --config test03_payment_batch.yaml
Kopyalama sırası her zaman ebeveynden çocuğa, silme sırası ise daima çocuktan ebeveyne doğru planlanır. Ayrıntılar arşivleme rehberinde yer alır.
Adım 2.3: Yapılandırma doğrulama (validate)
Veri tabanlarına bağlanır, şema, dizinler, motor tipleri ve tetikleyicileri denetler:
goarchive validate --config test03_payment_batch.yaml
Kaynak tabloda silme tetikleyicisi bulunduğunda komut --force-triggers bayrağı olmadan durur. Sakila’nın tek silme tetikleyicisi film tablosundadır, bu iki senaryoda bayrağa gerek kalmaz.
Adım 2.4: Kuru çalıştırma (dry-run)
Hiçbir veriyi değiştirmeden, where koşuluna uyan satırları sorgular ve operasyonun olası etkisini simüle eder:
goarchive dry-run --job archive-payment-rows --config test03_payment_batch.yaml
Adım 2.5: Arşivlemeyi başlatma (archive)
Tam döngü çalıştırılır: kopyala, doğrula, sil.
goarchive archive --job archive-payment-rows --config test03_payment_batch.yaml
3. Doğrulama yöntemleri: satır sayısı (count) ve sha256 sağlama toplamı
GoArchive, kaynak veriyi silmeden önce hedefte verinin eksiksiz olduğunu doğrulamak zorundadır. İki ana doğrulama yöntemi sunulur:
Satır Sayısı Doğrulaması (
count): Varsayılan yöntemdir. İlgili yığındaki birincil anahtar (primary key) satır sayılarının kaynak ve hedefte birebir eşit olduğunu kontrol eder.Kriptografik Sağlama Toplamı (
sha256):test05_payment_verify_sha256.yamlyapılandırmasında kullanıldığı gibi:verification: method: sha256Bu yöntemde GoArchive, kopyalanan satırların tüm sütun değerlerini birleştirerek bir SHA-256 sağlama toplamı (checksum hash) üretir ve hedefteki satırların hash değeriyle kıyaslar.
- Ek Güvenlik Davranışı:
sha256modu devredeyken ve hedef tabloda birincil anahtar haricinde tekil dizin (unique index) yoksa, kopyalama işlemiINSERT IGNOREmantığıyla çalıştırılarak olası mükerrerliklerde hata yerine satır uyumsuzluğu üretilip doğrulama aşamasında güvenle yakalanır.
- Ek Güvenlik Davranışı:
Senaryo 2: İlişkisel ve hiyerarşik arşivleme (rental -> payment)
Gerçek hayat senaryolarında nadiren tek bir tablo arşivlenir. Çoğunlukla ebeveyn-çocuk ilişkisi olan tabloların birlikte taşınması gerekir. Sakila veri tabanındaki kiralama (rental) ve buna bağlı ödeme (payment) tabloları bu model için mükemmel bir örnektir.
1. Yapılandırma: test04_rental_payment.yaml
Bu senaryoda rental tablosu kök (root), payment tablosu ise yabancı anahtarla (rental_id) bağlı bir alt ilişkidir (1-N child relation):
jobs:
archive-rental-payments:
root_table: rental
primary_key: rental_id
where: "rental_id <= 200"
relations:
- table: payment
primary_key: payment_id
foreign_key: rental_id
dependency_type: "1-N"
2. Kritik mimari prensipler
- Hiyerarşik İşlem Sırası:
- Kopyalama Aşaması (Ebeveynden Çocuğa): Önce
rentalsatırları hedefe kopyalanır, ardından bu kayıtlara bağlıpaymentsatırları kopyalanır. - Silme Aşaması (Çocuktan Ebeveyne): Silme işlemi tam ters sırada yapılır, önce alt tablodaki
paymentsatırları silinir, ardından anarentalsatırları silinir. Bu kural yabancı anahtar kısıt ihlallerini (foreign key constraint violations) tamamen önler.
- Kopyalama Aşaması (Ebeveynden Çocuğa): Önce
- Yetim Kayıt (Orphan Row) Kontrolü: Hedefe aktarılan tüm
paymentkayıtlarının geçerli birrentalebeveynine bağlı olduğu doğrulanır. Hedefte hiçbir yetim kayıt kalmasına izin verilmez. - Yabancı Anahtar Denetimlerinin Geçici Kapatılması (
disable_foreign_key_checks: true): Hedef veri tabanında (destination database) müşteri (customer) veya personel (staff) tabloları bulunmayabilir. Yalnızca ilgili alt grafik taşındığından, aktarım sırasında hedefte yabancı anahtar denetimleri güvenle devre dışı bırakılır, veri bütünlüğü ise GoArchive’ın yazılımsal denetimleriyle sağlanır.
3. Çalıştırma
goarchive validate --config test04_rental_payment.yaml
goarchive archive --job archive-rental-payments --config test04_rental_payment.yaml
İlişkili veri taşımayan senaryolar için yalnızca kopyalama ve temizleme rehberleri ayrıca hazırlanmıştır.
İzleme, iş takibi ve kesinti toleransı
GoArchive, uzun süren arşivleme operasyonlarında hata toleransını garanti altına almak için hedef veri tabanı üzerinde izleme tabloları (archiver_job ve archiver_job_log_<id>) tutar.
| İzleme tablosu | Görevi |
|---|---|
archiver_job | İş emrinin genel durumu (job_status), başlangıç ve bitiş zamanları, son işlenen birincil anahtar (last_processed_root_pk_id). |
archiver_job_log_<id> | Her bir yığının anlık durumu: kopyalandı, doğrulandı, silindi. |
İki senaryo tamamlandıktan sonra iş tablosu şu hâli alır:
Kesinti durumlarında davranış biçimi
- Zarif Durdurma (Graceful Stop -
SIGTERM): İşlem sonlandırıldığında GoArchive mevcut yığını tamamlar ve kontrol noktasını (last_processed_root_pk_id) günceller. Süreç yeniden başlatıldığında doğrudan bu anahtardan sonraki satırlardan devam eder (checkpoint resume). - Beklenmeyen Çökme (Crash /
SIGKILL): Bir elektrik kesintisi veya sistem çökmesi durumunda silme aşamasında kalan satırlararchiver_job_log_<id>tablosunda tespit edilir. Bir sonraki çalıştırmada kurtarma mekanizması devreye girer, kopyalanmış ancak silinmesi yarım kalmış satırlar güvenle temizlenir ve akış kaldığı yerden devam eder (crash replay).
Sonuçların doğrulanması
Arşivleme tamamlandıktan sonra satır sayıları doğrudan MySQL sorgularıyla teyit edilebilir:
tests/scripts/mysql-query.sh 3307 "SELECT COUNT(*) FROM sakila_archive.payment;"
tests/scripts/mysql-query.sh 3305 "SELECT COUNT(*) FROM sakila.payment WHERE payment_id <= 2000;"
Hedefteki 2.169 ödeme kaydı iki senaryonun toplamıdır: birinci senaryodan 1.999, ikinci senaryodaki kiralamalara bağlı 170 kayıt. Kaynakta her iki koşul için de sonuç sıfırdır.
Kurumsal en iyi uygulamalar
Canlı üretim ortamlarında GoArchive kullanırken aşağıdaki kontrol listesini uygulamanız önerilir:
- Önce Kuru Çalıştırma (
dry-run): Üretim ortamında hiçbir işi doğrudan başlatmayın, öncevalidatevedry-runçıktılarını inceleyin. - Küçük Yığınlarla Başlayın:
batch_size(örn: 500-1000) vebatch_delete_size(örn: 50-100) değerlerini donanım ve işlem hacmine göre belirleyin. - Hız Sınırlandırmayı (Pacing/Throttling) İhmal Etmeyin:
sleep_secondsvedelete_sleep_secondsparametreleriyle disk I/O ve replikasyon kuyruklarının rahatlamasına fırsat tanıyın. - Replikasyon Gecikmesini İzleyin: Hedefte replikasyon izleme parametrelerini aktif tutarak canlı okuma trafiğini koruyun.
- Kritik Verilerde SHA-256 Kullanın: Finansal veya yasal düzenlemeye tabi verilerde
verification.method: sha256seçeneğini tercih edin.
Özet
GoArchive, MySQL ortamlarında veri arşivleme süreçlerini bir komut dosyası karmaşasından çıkarıp kurumsal düzeyde yönetilebilir, izlenebilir ve güvenli bir operasyona dönüştürür. Ön uçuş kontrolleri, kriptografik doğrulaması, hız sınırlandırması ve kesinti toleransı ile büyük veri tabanlarında sıfır kesinti ve sıfır veri kaybı hedefine ulaşmanızı sağlar.
Ürünün tamamı ve çalışma kapsamı GoArchive ile MySQL veri arşivleme çözümü sayfasında, kurulum ve komut ayrıntıları ise ürün dokümantasyonunda yer alır.
