Senaryo net: 400 hesap, kabaca 120 GB posta, eski bir Dovecot sunucusundan yenisine taşınacak. Naif plan şudur — "MX kaydını değiştir, sonra maili kopyala". Bu plan sizi tam olarak yeni sunucunun ilk gününde vurur. MX değiştiği an DNS yayılımı başlar: dünyanın bir kısmı yeni sunucuya teslim ederken, cache'lediği eski A kaydına tutunan önemli bir kısmı hâlâ eskiye teslim eder. O pencerede mail iki sunucu arasında bölünür. Kullanıcının masaüstü istemcisi eskiye bağlı kalır, telefonu yeniye bağlanır; gelen ve giden mail iki ayrı kutuya dağılır. Kimse tek bir mesaj silmese bile sonuç kayıpla aynı görünür.
Kesintisiz taşımanın gerçek tanımı budur: kullanıcı oturumu hiçbir anda düşmez ve hiçbir mail iki sunucu arasında kaybolmaz. Posta kutusunu kopyalamak bu işin en kolay parçası. imapsync sihirli bir kutu değil — durumsuz, tekrar tekrar çalıştırılabilen, tek yönlü bir IMAP kopyalayıcı. Marifet aracın kendisinde değil, onu içine oturttuğunuz koreografide: TTL düşür, önden senkronla, delta döngüsüne al, MX'i geçir ve çift teslimatı aç, son deltayı çek, doğrula.
Taşımanın anatomisi: iki aşamalı senkron
Bütün mantık tek bir fikre dayanır: 120 GB'ı canlı trafiği kesmeden, arka planda taşırsınız. Geçiş anına geldiğinizde kopyalanacak veri artık 120 GB değil, yalnızca son birkaç saatin farkıdır — birkaç yüz megabayt, dakikalar süren bir delta. Bu yüzden süreç "önden toplu senkron + tekrarlı delta" olarak kurgulanır.
imapsync bir mesajın iki tarafta aynı olup olmadığını Message-Id, Internal Date ve RFC822 boyutunun bileşiminden belirler. Pratik sonucu şu: aynı komutu istediğiniz kadar tekrar çalıştırın, zaten taşınmış mailleri yeniden kopyalamaz. Bu idempotentlik, delta döngüsünün tüm temeli — onsuz her tekrar tur çift mesaj üretirdi.
Hazırlık: TTL, hesap provizyonu, kimlik doğrulama
Geçişten 48 saat önce DNS'te MX ve autoconfig kayıtlarının TTL'ini 300 saniyeye indirin. Geçiş günü DNS değişikliğinizin dakikalar içinde yayılmasını istiyorsanız, o değişikliğin cache'lerde ne kadar takılı kalacağını bugünden düşürmeniz gerekir; TTL'i geçiş anında indirmek işe yaramaz, çünkü resolver'lar zaten eski uzun değeri tutmaktadır.
evilmail.pro. 300 IN MX 10 mx1.evilmail.pro.
mx1.evilmail.pro. 300 IN A 203.0.113.10
_autodiscover._tcp.evilmail.pro. 300 IN SRV 0 0 443 mx1.evilmail.pro.Yeni sunucuda 400 hesabı önceden açın: Dovecot'ta virtual_users kayıtları hazır, mail dizinleri doğru sahiplikle (5000:5000) oluşturulmuş olmalı. imapsync var olmayan bir hedef kutuya yazamaz; ilk komutta hata verip durur.
Sonra en can sıkıcı problem: 400 kullanıcının parolasını bilmiyorsunuz ve tek tek toplayamazsınız. İki temiz çözüm var. Birincisi Dovecot master user — tek bir yönetici kimliğiyle tüm sanal kutulara giriş yaparsınız. imapsync tarafında login --user2 '[email protected]*master' biçimindedir; buradaki * ayracı Dovecot'ta auth_master_user_separator = * ile tanımlıdır ve parola alanına master kullanıcının parolası yazılır, hedef kullanıcının değil. İkinci seçenek, OAuth2 sağlayan sistemler için XOAUTH2. Kaynak eski Dovecot ise onun da kendi master mekanizmasını aynı şekilde kullanabilirsiniz.
Her hesabı ayrı bir çalışma dizininde, ayrı log ve pidfile ile çalıştırın — 400 paralel işi ancak böyle izleyebilir, birinde patlayan bir tanesini diğerlerinden ayırabilirsiniz.
İlk toplu senkron: komut ve kritik bayraklar
İşin kalbi tek bir komutta. Her bayrağın neden orada olduğunu bilmeden çalıştırmayın:
imapsync \
--host1 eski.example.com --user1 '[email protected]*master' --password1 'ESKI_MASTERPASS' \
--host2 mx1.evilmail.pro --user2 '[email protected]*master' --password2 'YENI_MASTERPASS' \
--ssl1 --port1 993 --ssl2 --port2 993 \
--automap --addheader --useheader "Message-Id" \
--nofoldersizes --skipsize --allowsizemismatch \
--exclude '^Junk$' --logfile /var/log/imapsync/ali.log--automapklasörleri iki taraf arasında otomatik eşler; INBOX, Sent, Drafts, Trash gibi özel klasörleri IMAP özel-kullanım bayraklarından tanır.--addheaderher taşınan mesaja birX-IMAPsyncbaşlığı ekler;--useheader "Message-Id"ile birlikte, tekrar turlarında çift kaydı önleyen ikinci bir güvence.--nofoldersizesklasör boyutlarını önden hesaplamayı atlar — büyük kutularda ciddi hız kazancı.--skipsizeve--allowsizemismatch, iki sunucu aynı maili birkaç bayt farkla sakladığında (Dovecot ile Courier arasında sık olur) senkronun durmasını engeller.--exclude '^Junk$'spam klasörünü taşımaz; taşımanın anlamı yok, hem zaman hem disk israfı.
Her zaman önce `--dry` ile çalıştırın. Deneme turunda hiçbir şey yazılmaz; çıktıda ++++ Calculating differences bloğunu ve kaç mesajın transfer edileceğini gösteren satırı görürsünüz. Sayı beklediğinize yakınsa gerçek tura geçin. Başarı ölçütünüz iki şey: exit code 0 ve özet satırı — Msgs total ... transferred ... skipped ... errors 0. errors sıfır değilse log'u okumadan bir sonraki hesaba geçmeyin.
Klasör eşleme ve gerçek tuzaklar
En çok zaman kaybettiren yer klasör ayraçlarıdır. Dovecot hiyerarşi ayracı olarak / kullanır; eski Courier veya UW-IMAP . kullanır. Eşlemezseniz INBOX.Arsiv.2024 yeni tarafta hiyerarşisi olmayan tek bir düz klasör adına dönüşür. Çözüm:
--sep1 '.' --sep2 '/' --regextrans2 's,^INBOX\.,,'Bu, kaynak ayracını noktadan slash'a çevirir ve Courier'in her klasörün başına koyduğu INBOX. önekini kırpar.
Kaynak Gmail ise ayrı bir dünya: --gmail1 bayrağı etiketleri (labels) klasör gibi ele alır ve "All Mail" çoğaltmasını yönetir — yoksa her mail birden fazla kez taşınmış gibi görünür. Gmail için 993/SSL ve bir App Password kullanın.
Bir başka klasik şikâyet: "taşıdım ama kullanıcının bütün mailleri okunmamış göründü." Kaynağı neredeyse her zaman yanlış namespace yüzünden \Seen, \Answered gibi bayrakların taşınmamasıdır. --automap doğru namespace'i yakaladığında imapsync bayrakları olduğu gibi taşır. Abonelik durumunu da atlamayın — --subscribeall tüm klasörleri hedefte abone eder, aksi halde kullanıcının istemcisinde bazı klasörler hiç görünmez.
Delta senkronları ve paralelleştirme
İlk tur bitince komutu bir döngüye veya cron'a alın. Aynı komut her turda yalnızca yeni gelen maili taşır — idempotentlik sayesinde çift üretmez. Delta turlarını hızlandırmak için taramayı son mailerle sınırlayın:
--maxage 2 # yalnızca son 2 günün mailine bak400 hesabı sırayla işlemek saatler alır; paralelleştirin. GNU parallel ile 8 eşzamanlı imapsync makul bir başlangıç:
cat hesaplar.txt | parallel -j 8 imapsync \
--host1 eski.example.com --user1 '{}*master' --password1 'ESKI_MASTERPASS' \
--host2 mx1.evilmail.pro --user2 '{}*master' --password2 'YENI_MASTERPASS' \
--ssl1 --port1 993 --ssl2 --port2 993 --automap \
--logfile /var/log/imapsync/{}.logİki eşiğe dikkat. Birincisi bant genişliği — --maxbytespersecond 5000000 (5 MB/s) ile üretim sunucusunu boğmayın. İkincisi kaynak sunucunun IMAP bağlantı limiti: Dovecot'ta mail_max_userip_connections varsayılan olarak düşüktür ve 8 paralel iş kolayca "Maximum number of connections from user+IP exceeded" hatası aldırır. Geçiş süresince bu değeri geçici olarak yükseltin, iş bitince eski haline döndürün.
Geçiş anı: MX değişimi ve split-brain'i çözme
Şimdi işin en hassas bölümü. MX'i yeni sunucuya çevirdiğinizde iş bitmez — eski A kaydını cache'lemiş gönderenler, TTL süresince eski sunucuya teslim etmeye devam eder. Bu mailleri kaybetmemenin yolu çift teslimat: eski Postfix'e, aldığı her maili yeni sunucuya da relay eden bir transport tanımlarsınız.
Eski Postfix tarafında main.cf ve bir transport dosyası:
# main.cf
transport_maps = hash:/etc/postfix/transport
# /etc/postfix/transport
example.com relay:[mx1.evilmail.pro]:25postmap /etc/postfix/transport && systemctl reload postfix sonrası eski sunucuya düşen her mail yeni sunucuya da iletilir. Böylece yayılım süresince iki uçtaki tüm mail yeni sunucuda birleşir ve split-brain penceresi kapanır. Alternatifi, eski sunucuyu tamamen "yalnızca-relay" moduna almaktır: yerel teslimatı kapatıp her şeyi yeni sunucuya yönlendirirsiniz. Bu arada istemci autoconfig/autodiscover kayıtlarını da yeni sunucuya güncelleyin, yoksa yeni kurulan istemciler eski sunucuyu arar.
Son delta ve doğrulama
MX değişikliği yayıldıktan sonra — 300s TTL artı makul bir pay olarak yaklaşık 1 saat bekleyin — tek bir son imapsync turu çalıştırın. Bu tur kaynakta son anlarda biriken mailleri de çeker. Beklentiniz nettir: son turda transferred neredeyse sıfır, skipped ise toplam mesaj sayısına eşit olmalı — çünkü her şey zaten taşınmıştır.
Doğrulamayı gözle değil sayıyla yapın. İki sunucuda da:
doveadm mailbox status -u [email protected] messages '*'Çıktıdaki mesaj sayıları klasör klasör eşleşmeli. Bunu bir betikle örneklem hesaplar üzerinde otomatikleştirin; 400 hesabın hepsini elle karşılaştırmayın ama rastgele 20-30 hesabı ve bilinen "ağır" kullanıcıları mutlaka kontrol edin. Birkaç kullanıcıyı gerçek istemcilerinde açıp gönderilenler ve son gelenler üzerinde spot kontrol yapın.
En önemlisi: eski sunucuyu hemen kapatmayın. 7 gün salt-okunur modda tutun. Bir sorun çıkarsa rollback için elinizde bozulmamış bir kaynak kalır. Yıkıcı bayrakları (--delete1, --delete2) yalnızca tüm doğrulama tamamlandıktan sonra, ayrı ve bilinçli bir turda kullanın — asla geçiş öncesinde.
Geçiş kontrol listesi
- [ ] MX ve autoconfig TTL'i 48 saat önce 300s'ye indirildi
- [ ] Yeni sunucuda 400 hesap doğru uid/gid (5000:5000) ile açıldı
- [ ] Master user / OAuth2 kimlik doğrulaması test edildi
- [ ]
--dryturu çalıştırıldı, transfer sayısı doğrulandı - [ ] İlk toplu senkron tamamlandı, exit code 0
- [ ] Delta döngüsü kuruldu,
--maxbytespersecondve bağlantı limitleri ayarlandı - [ ] Eski Postfix'te çift teslimat (
transport_mapsrelay) kuruldu ve test edildi - [ ] MX yeni sunucuya çevrildi, autodiscover güncellendi
- [ ] Yayılım sonrası son delta turu çekildi (
transferred ≈ 0) - [ ]
doveadm mailbox statusile iki tarafın sayımları eşleşti


