Arşivleme İşlemlerinde Zaman Damgalarını Koruma ve Yönetme: tar, zip ve touch ile Metadata Kontrolü

Dosyaları arşivlerken çoğu zaman aklımıza gelmeyen ama sonradan başımızı ağrıtan bir konu var: zaman damgaları. Bir backup aldınız, dosyaları restore ettiniz, ama ls -la çıktısında gördüğünüz tarihler tamamen yanlış. Ya da production’dan aldığınız bir arşivi audit sürecinde açıyorsunuz ve “bu dosya ne zaman değiştirildi?” sorusuna cevap veremiyorsunuz. Bu yazıda tar, zip ve touch komutlarıyla zaman damgalarını nasıl koruyacağınızı, manipüle edeceğinizi ve denetleyeceğinizi ele alacağız.

Zaman Damgaları Neden Önemli?

Linux üzerinde her dosyanın aslında üç farklı zaman damgası vardır:

  • atime (access time): Dosyaya en son ne zaman erişildiği
  • mtime (modification time): Dosyanın içeriğinin en son ne zaman değiştirildiği
  • ctime (change time): Dosyanın metadata’sının (izinler, sahiplik vb.) en son ne zaman değiştirildiği

stat komutuyla bunları kolayca görebilirsiniz:

stat /etc/passwd

Çıktıda şuna benzer bir şey görürsünüz:

  File: /etc/passwd
  Size: 2847
Access: 2024-01-15 09:23:11.000000000 +0300
Modify: 2024-01-10 14:05:33.000000000 +0300
Change: 2024-01-10 14:05:33.000000000 +0300

Şimdi şunu düşünün: Bir uygulama sunucusunda config dosyalarını arşivleyip başka bir sunucuya taşıdınız. Restore sonrasında tüm mtime değerleri restore işleminin yapıldığı an oldu. Monitoring sisteminiz bu dosyaların “yeni değiştirildiğini” düşünüp alarm üretiyor, ya da uygulamanız cache invalidation için mtime’a bakıyorsa gereksiz yere cache’i temizliyor. Küçük detay gibi görünür, büyük sorunlara yol açar.

tar ile Zaman Damgalarını Koruma

tar, metadata koruma konusunda oldukça yeteneklidir. Varsayılan davranışına bakalım önce.

Varsayılan Davranış

Normal bir tar arşivi oluşturduğunuzda ve açtığınızda mtime bilgisi korunur, ancak ctime güncellenir (bu kaçınılmazdır, dosya yeni oluşturuluyor sonuçta). atime ise açma işlemiyle birlikte güncellenir.

# Arşiv oluşturma
tar -czf yedek.tar.gz /var/www/html/

# İçeriği listele, mtime bilgilerini gör
tar -tzvf yedek.tar.gz

Bu çıktıda her dosyanın mtime’ını görebilirsiniz. Şimdi asıl konuya gelelim.

–preserve-permissions ile Tam Koruma

# İzinleri ve sahipliği de koru
tar -czpf yedek.tar.gz /var/www/html/

Buradaki -p bayrağı (--preserve-permissions) çok kritik. Özellikle root olarak çalışırken bu bayrak olmadan sahiplik bilgileri kaybolabilir.

atime’ı Bozmadan Arşivleme

Büyük log dizinlerini arşivlerken karşılaşılan klasik sorun: arşivleme sırasında tar dosyalara eriştiği için atime güncellenir. Bu da “bu log dosyasına en son ne zaman bakıldı?” bilgisini bozar. Çözüm:

# --atime-preserve ile mevcut atime'ı koru
tar --atime-preserve=system -czf loglar.tar.gz /var/log/nginx/

# Alternatif: noatime mount option'ı olmayan sistemlerde
tar --atime-preserve=replace -czf loglar.tar.gz /var/log/nginx/

--atime-preserve=system seçeneği, arşivleme tamamlandıktan sonra atime değerlerini eski haline döndürür. replace seçeneği ise dosyaları okuduktan sonra atime’ı geri yazar. İkisi arasındaki fark ince ama race condition açısından system daha güvenlidir.

Restore Sırasında Zaman Damgalarını Koruma

# Standart restore - mtime korunur
tar -xzf yedek.tar.gz -C /restore/dizin/

# Tam koruma: izinler ve sahiplik dahil
tar -xzpf yedek.tar.gz -C /restore/dizin/

# Mevcut dosyaların üzerine yazmadan, sadece daha yeni olanları güncelle
tar -xzf yedek.tar.gz -C /restore/dizin/ --keep-newer-files

--keep-newer-files bayrağını production restore senaryolarında sık kullanıyorum. Örneğin kısmi bir restore yapıyorsunuz ve bazı dosyalar arşiv alındıktan sonra güncellenmiş. Bu bayrak sayesinde daha yeni olan dosyaların üzerine yazılmıyor.

Belirli Bir Zaman Damgasını Arşive Zorla

Bazen tüm arşivin içindeki dosyaların tek bir zaman damgasına sahip olmasını istersiniz. CI/CD pipeline’larında reproducible build için bunu yapmanız gerekebilir:

# Tüm dosyaların mtime'ını belirli bir değere ayarlayarak arşivle
tar --mtime="2024-01-15 00:00:00" -czf release-v1.2.tar.gz /opt/uygulama/

# Unix timestamp kullanarak
tar --mtime="@1705276800" -czf release-v1.2.tar.gz /opt/uygulama/

Bu özellikle Docker image build süreçlerinde veya paket yönetimi sistemlerinde “aynı kaynak koddan aynı arşiv üretilmeli” gereksiniminiz varsa hayat kurtarır.

zip ile Zaman Damgası Yönetimi

zip komutu tar‘dan biraz farklı çalışır ve zaman damgası davranışı konusunda bazı sürprizler içerir.

Temel Davranış ve Sorunlar

zip varsayılan olarak dosyaların mtime bilgisini saklar. Ancak burada önemli bir detay var: ZIP formatı zaman damgasını 2 saniyelik çözünürlükte saklar. Yani 14:05:33 olan bir mtime, ZIP’ten çıkarınca 14:05:32 olabilir. Küçük bir fark ama checksum karşılaştırması yapıyorsanız sorun yaratır.

# Temel zip arşivi - mtime korunur (2sn çözünürlükle)
zip -r yedek.zip /var/www/html/

# İçeriği ve zaman bilgilerini listele
unzip -l yedek.zip

# Daha detaylı metadata bilgisi
unzip -v yedek.zip

zip ile atime ve ctime Saklamak

Standart ZIP formatı yalnızca mtime’ı saklar. Fakat Info-ZIP extended timestamp extension ile daha fazlasını yapabilirsiniz:

# Extended timestamp bilgisi ile arşivle (atime ve mtime dahil)
zip -r --filesync yedek.zip /var/www/html/

# Zaman bilgisini UTC olarak sakla (timezone sorunlarını önler)
zip -r yedek.zip /var/www/html/
unzip -D yedek.zip -d /restore/dizin/

unzip ile restore ederken dikkat etmeniz gereken -D bayrağı: bu bayrak zaman damgalarının restore edilmesini engeller, yani tüm dosyalar restore anının tarihini alır. Eğer zaman damgalarını korumak istiyorsanız bu bayrağı kullanmayın.

# Zaman damgalarını KORUYARAK restore et
unzip yedek.zip -d /restore/dizin/

# Zaman damgalarını YOKSAYARAK restore et (tüm dosyalar bugünün tarihini alır)
unzip -D yedek.zip -d /restore/dizin/

zipinfo ile Arşiv Metadata’sını İnceleme

# Detaylı metadata bilgisi
zipinfo yedek.zip

# Belirli bir dosyanın bilgileri
zipinfo yedek.zip config/settings.conf

Bu komutun çıktısı oldukça zengindir ve arşiv içindeki her dosyanın izinleri, boyutu ve zaman damgası hakkında bilgi verir.

touch ile Zaman Damgalarını Manipüle Etme

touch komutunu çoğu kişi “boş dosya oluşturmak için” bilir. Ama asıl gücü zaman damgası manipülasyonunda. Restore sonrası düzeltme işlemlerinde ve test senaryolarında vazgeçilmez.

Temel Kullanım

# Mevcut zamanı mtime olarak ayarla
touch dosya.conf

# Hem atime hem mtime'ı belirli bir tarihe ayarla
touch -t 202401150935.30 dosya.conf
# Format: YYYYMMDDhhmm.ss

# Sadece mtime'ı değiştir
touch -m -t 202401150935 dosya.conf

# Sadece atime'ı değiştir
touch -a -t 202401150935 dosya.conf

Başka Bir Dosyanın Zaman Damgasını Referans Alma

Bu özellik gerçekten çok kullanışlı. Bir dosyanın zaman damgasını başka bir dosyayla eşitlemek istiyorsanız:

# dosya_b'nin zaman damgasını dosya_a ile aynı yap
touch -r /etc/nginx/nginx.conf /etc/nginx/conf.d/default.conf

# Bir dizindeki tüm .conf dosyalarına aynı referans zamanını uygula
find /etc/nginx/ -name "*.conf" -exec touch -r /etc/nginx/nginx.conf {} ;

Restore Sonrası Toplu Düzeltme

Diyelim ki bir restore yaptınız ve bazı dosyaların zaman damgaları bozuldu. Arşiv listenizde doğru tarihler var ama filesystem’de yanlış. Şöyle bir yaklaşım işe yarar:

# tar arşivinden mtime bilgisini okuyup dosyalara uygula
tar -tzvf yedek.tar.gz | while read perm links owner group size date time filename; do
    # Tarih formatını touch için düzenle
    timestamp=$(date -d "$date $time" "+%Y%m%d%H%M.%S" 2>/dev/null)
    if [ -n "$timestamp" ] && [ -e "/restore/$filename" ]; then
        touch -m -t "$timestamp" "/restore/$filename"
    fi
done

Bu script ham ve gerçek senaryoda biraz daha hata kontrolü gerektirir, ama mantığı anlatıyor: arşiv içindeki metadata’yı referans alarak filesystem’i düzeltiyoruz.

find ile Kombinasyon: Zaman Bazlı İşlemler

# Son 7 günde değiştirilmiş dosyaları arşivle
find /var/www -mtime -7 -type f | tar -czf degisen_dosyalar.tar.gz -T -

# 30 günden eski log dosyalarını arşivleyip sil
find /var/log/uygulama -name "*.log" -mtime +30 -print0 | 
    tar --null -czf eski_loglar_$(date +%Y%m).tar.gz -T - && 
    find /var/log/uygulama -name "*.log" -mtime +30 -delete

İkinci komutta dikkat edin: önce arşivleme başarılı olursa (&&) silme işlemi yapılıyor. Bu önemli bir güvenlik önlemi.

Gerçek Dünya Senaryoları

Senaryo 1: Audit Uyumlu Backup Sistemi

Bir fintech şirketinde çalıştığınızı düşünün. Düzenleyici kurumlar dosyaların ne zaman oluşturulduğunu ve değiştirildiğini ispat etmenizi istiyor. Backup sisteminiz bu bilgileri korumalı:

#!/bin/bash
# audit_backup.sh

KAYNAK="/opt/fintek/data"
HEDEF="/backup/audit"
TARIH=$(date +%Y%m%d_%H%M%S)
ARSIV="$HEDEF/audit_backup_$TARIH.tar.gz"

# p bayrağı: izin ve sahiplik koru
# --atime-preserve: erişim zamanını bozma
# --selinux: SELinux context'ini de koru (RHEL/CentOS için)
tar -czp 
    --atime-preserve=system 
    --xattrs 
    --selinux 
    -f "$ARSIV" 
    "$KAYNAK"

# Arşiv integrity check
tar -tzf "$ARSIV" > /dev/null 2>&1
if [ $? -eq 0 ]; then
    echo "$(date): Backup basarili - $ARSIV" >> /var/log/audit_backup.log
    # SHA256 checksum al ve sakla
    sha256sum "$ARSIV" > "$ARSIV.sha256"
else
    echo "$(date): HATA - Backup dogrulanamadi" >> /var/log/audit_backup.log
    exit 1
fi

Senaryo 2: Reproducible Build Pipeline

CI/CD sistemlerinde aynı kaynak koddan her seferinde aynı arşivi üretmek istiyorsunuz. Zaman damgaları arşiv hash’ini etkiler, bu yüzden normalize etmeniz gerekir:

#!/bin/bash
# reproducible_package.sh

KAYNAK_DIR="/build/uygulama"
SURUM="$1"
CIKTI="dist/uygulama-$SURUM.tar.gz"

# Git'in son commit zamanını al
SOURCE_DATE=$(git -C "$KAYNAK_DIR" log -1 --format="%ct")

# Tüm dosyaları bu tarihe ayarla, sonra arşivle
find "$KAYNAK_DIR" -type f -exec touch -m -t $(date -d "@$SOURCE_DATE" "+%Y%m%d%H%M.%S") {} ;

tar --mtime="@$SOURCE_DATE" 
    --owner=0 --group=0 
    --numeric-owner 
    -czf "$CIKTI" 
    -C "$(dirname $KAYNAK_DIR)" 
    "$(basename $KAYNAK_DIR)"

echo "Paket olusturuldu: $CIKTI"
echo "Source date: $(date -d @$SOURCE_DATE)"

Senaryo 3: Timezone Sorunlarının Giderilmesi

Farklı timezone’lardaki sunucular arasında dosya transferi yapıyorsunuz ve zaman damgaları karışıyor. Bu durumda şu yaklaşım işe yarar:

# Kaynak sunucuda: UTC timestamp ile arşivle
TZ=UTC tar -czf transfer.tar.gz --mtime="$(TZ=UTC date -r /kaynak/dosya)" /kaynak/

# Hedef sunucuda: timezone farkını hesaba kat
# Önce arşivin içeriğini incele
TZ=UTC tar -tzvf transfer.tar.gz

# Restore et
tar -xzf transfer.tar.gz -C /hedef/

# Eğer timezone düzeltmesi gerekiyorsa touch ile uygula
# +3 saat farkı için (UTC -> TZ+3)
find /hedef -type f -newer /hedef/referans_dosya -exec 
    touch -m -d "$(stat -c %y {} | awk '{print $1, $2}') +3 hours" {} ;

rsync ile tar’ı Birlikte Kullanma

Büyük veri transferlerinde sadece değişen dosyaları arşivlemek istediğinizde rsync’in --only-write-batch özelliğini veya şu yaklaşımı kullanabilirsiniz:

# rsync ile kopyala, zaman damgalarını koru, sonra arşivle
rsync -av --archive 
    --numeric-ids 
    /kaynak/dizin/ /gecici/staging/

# Staging'den arşiv oluştur
tar -czp 
    --atime-preserve 
    -f son_yedek.tar.gz 
    /gecici/staging/

# Staging'i temizle
rm -rf /gecici/staging/

Burada rsync’in -a (archive) bayrağı zaman damgaları dahil tüm metadata’yı kopyalar, sonra tar bu korunan metadata’yla arşiv oluşturur.

Metadata Doğrulama ve Test

Tüm bu işlemlerin doğru çalışıp çalışmadığını nasıl test edersiniz?

#!/bin/bash
# metadata_test.sh
# Arşivleme öncesi ve sonrası metadata karşılaştırması

DOSYA="/etc/nginx/nginx.conf"
ARSIV="/tmp/test_arsiv.tar.gz"
RESTORE_DIR="/tmp/test_restore"

# Orijinal metadata'yı kaydet
ORIJINAL_MTIME=$(stat -c %Y "$DOSYA")
echo "Orijinal mtime: $(stat -c %y $DOSYA)"

# Arşivle
tar -czp -f "$ARSIV" "$DOSYA"

# Restore et
mkdir -p "$RESTORE_DIR"
tar -xzp -f "$ARSIV" -C "$RESTORE_DIR"

# Restore edilen metadata'yı kontrol et
RESTORE_DOSYA="$RESTORE_DIR$DOSYA"
RESTORED_MTIME=$(stat -c %Y "$RESTORE_DOSYA")
echo "Restore mtime: $(stat -c %y $RESTORE_DOSYA)"

# Karşılaştır
if [ "$ORIJINAL_MTIME" -eq "$RESTORED_MTIME" ]; then
    echo "BASARILI: mtime korundu"
else
    echo "HATA: mtime farkli! Fark: $((RESTORED_MTIME - ORIJINAL_MTIME)) saniye"
fi

# Temizlik
rm -f "$ARSIV"
rm -rf "$RESTORE_DIR"

Önemli Parametrelerin Özeti

Yazıda geçen en kritik parametreleri şöyle özetleyebilirim:

tar parametreleri:

  • -p / –preserve-permissions: Dosya izinleri ve sahipliği korur
  • –atime-preserve=system: Arşivleme sırasında atime’ı bozmaz
  • –mtime=”tarih”: Arşivdeki tüm dosyalara belirtilen mtime’ı atar
  • –xattrs: Extended attribute’ları korur
  • –keep-newer-files: Mevcut daha yeni dosyaların üzerine yazmaz

unzip parametreleri:

  • -D: Zaman damgalarını yok sayar, dosyalar güncel tarihi alır
  • -v: Verbose, detaylı metadata bilgisi gösterir

touch parametreleri:

  • -m: Sadece mtime’ı değiştirir
  • -a: Sadece atime’ı değiştirir
  • -t: Belirtilen zaman damgasını uygular, format: YYYYMMDDhhmm.ss
  • -r dosya: Belirtilen dosyanın zaman damgasını referans alır

Sonuç

Zaman damgası yönetimi, sysadmin işlerinin “görünmez” ama kritik boyutlarından biri. Bir sorun yaşanana kadar kimse umursamıyor, sorun yaşandığında ise çözümü bulmak saatler alabiliyor.

Bu yazıda anlattıklarımı üç ana başlıkta toparlayabilirim: tar kullanıyorsanız -p ve --atime-preserve alışkanlık haline getirin, arşiv sonrası mutlaka stat ile doğrulama yapın. zip kullanıyorsanız timezone farkındalığı kritik, özellikle farklı işletim sistemleri arasında dosya taşıyorsanız. touch ise restore sonrası düzeltme ve test senaryolarında güçlü bir araç, sadece “dosya oluşturma komutu” olarak bakmayın.

Reproducible build veya audit uyumluluğu gibi ciddi gereksinimleriniz varsa, bir kez sağlam bir test script’i yazın ve her backup stratejisi değişikliğinde çalıştırın. Zaman damgaları sessizce bozulur, sesli alarm vermez.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir