Metin2 Server Yedekleme ve Geri Yükleme
Hazırlayan: Metin2VIP Editörleri Yayın: 7 dk okuma
İçindekiler
Metin2 sunucusunda yedeklenmesi gerekenler account, common ve player veritabanları, ihtiyaca göre log veritabanı ve srv1 altındaki sunucu dosyalarıdır. Asıl incelik zamanlamadadır: db çekirdeği karakter ve eşya değişikliklerini anında değil aralıklarla MySQL'e yazar, bu yüzden oyun açıkken alınan bir döküm oyunun o anki hâlini değil son kaydı içerir. Tam tutarlı yedek sunucu düzgün kapatıldıktan sonra alınır; her yedek şifrelenip başka bir yerde saklanır ve geri yüklenerek denenir.
Kayıt aralıkları ve kayıp hesapları db ve oyun çekirdeğinin kaynak kodundan, betik örnekleri paketin baks klasöründen alındı; conf.txt'de kayıt sürelerini değiştiren sunucularda süreler farklıdır.
Hangi veritabanları ve dosyalar yedeklenir?
| Ne | İçinde | Yedek |
|---|---|---|
| account | Hesaplar, parola özeti, silme kodu ve bakiye | Her yedekte |
| player | Karakterler, eşyalar, depo, loncalar, quest bayrakları, oran bayrakları, item_award, market ve artı basma tabloları | Her yedekte |
| common | GM listesi, locale, krallık bonusları, exp_table | Her yedekte |
| log | Eşya, giriş, GM komutu ve artı basma kayıtları | Ayrı ve daha seyrek; en büyüğüdür |
| hotbackup | Boş | Yalnız veritabanının var olması gerekir |
| Sunucu dosyaları | share/conf protoları, share/locale/turkey (drop, quest kaynakları ve object, haritalar), CONFIG'ler, conf.txt, gen_settings.py, chan/mark |
Her değişiklikten önce |
| İkililer | share/bin/game ve db, kaynak kod, istemci pack dosyaları |
Her sürümde |
Üç ayrıntı sık atlanır. Paketteki conf.txt'de PROTO_FROM_DB = 0 ve MIRROR2DB = 1 olduğu için MySQL'deki item_proto ve mob_proto yalnız bir yansıdır; asıl kaynak db klasöründeki txt dosyalarıdır (Metin2 veritabanları). Lonca amblemleri veritabanında değil, chan/mark klasöründe mark_index ve .tga dosyaları olarak durur (lonca amblemi). mob_exp gibi oran bayrakları player'daki quest tablosunda, krallık bonusları common'da tutulur; eski bir yedeği geri yüklemek oranları da o günkü hâline döndürür (oranlar ayarı).
Oyun açıkken alınan yedek neyi içerir?
db çekirdeği değişen bir karakter satırını, son yazmadan bu yana 420 saniye geçince; eşyaları 300, pazar fiyat hafızasını 540 saniye geçince MySQL'e yazar. Quest bayraklarını ve etkileri ise kendisine ulaştığı anda yazar. Oyun açıkken alınan döküm bu yüzden, db çekirdeği o anda çökseydi MySQL'de kalacak olan durumdur: karakterler en fazla yaklaşık 7, eşyalar 5 dakika geriden gelir ve aynı dökümde birbirinden farklı anlara ait satırlar bulunabilir. Süreler conf.txt'den değişir (db conf.txt).
Tablolar MyISAM olduğu için mysqldump seçenekleri de önemlidir:
--single-transactionyalnız InnoDB tablolarında tutarlı döküm verir; MyISAM tabloları döküm sırasında değişmeye devam edebilir.- Varsayılan
--lock-tablesher veritabanını ayrı kilitler; account ile player arasında tutarlılık sağlamaz. --lock-all-tablesdöküm boyunca genel okuma kilidi tutar. Tutarlıdır, ama döküm bitene kadar yazmalar bekler.
Kilitli bir döküm sürerken db çekirdeğinin olağan kayıtları kuyrukta bekler ve oyun sürer. Karakter açma ve silme gibi db'nin yanıtını beklediği yazmalar ise kilit kalkana kadar db çekirdeğinin bütün işini durdurur; girişler ve ışınlanmalar da bu sürede takılır. Sıcak dökümü en sakin saate koy, büyük log veritabanını oyun açıkken kilitle dökme.
Tutarlı (soğuk) yedek nasıl alınır?
Sunucu kapatılır, db önbelleği MySQL'e yazılır, sonra döküm alınır. İkinci adıma geçmeden db syslog'unda MainLoop exited, Starting cache flushing satırını ve db sürecinin çıktığını gör:
sh admin_panel.sh 2 # stop.py: önce oyun çekirdekleri, en son db
for vt in account common player; do
mysqldump --defaults-extra-file=/home/yedek/.my.cnf --no-tablespaces $vt \
| gzip -9 > /yedek/${vt}_$(date +%Y%m%d-%H%M).sql.gz
done
sh admin_panel.sh 1 # yeniden başlat
Parola komut satırına değil, yalnız yedek kullanıcısının okuyabildiği (600 izinli) bir seçenek dosyasına yazılır; komut satırındaki parola aynı makinedeki süreç listesinde görünebilir. Yedek için root yerine ayrı bir kullanıcı aç:
CREATE USER 'yedek'@'localhost' IDENTIFIED BY 'GucluBirParola';
GRANT SELECT, LOCK TABLES ON account.* TO 'yedek'@'localhost';
GRANT SELECT, LOCK TABLES ON common.* TO 'yedek'@'localhost';
GRANT SELECT, LOCK TABLES ON player.* TO 'yedek'@'localhost';
GRANT SELECT, LOCK TABLES ON log.* TO 'yedek'@'localhost';
GRANT RELOAD ON *.* TO 'yedek'@'localhost'; -- yalnız --lock-all-tables için
Kapatma sırası ve önbelleğin neden zorla kapatmayla kaybolduğu server kurulumu yazısında.
Paketteki yedek betiğinin tuzakları
sh admin_panel.sh 4 ve baks/db/Makefile kullanılacaksa şunları bilmek gerekir (klasörün yeri server dosyaları yazısında):
- Veritabanları ayrı ayrı ve oyun açıkken dökülür; yukarıdaki iki tutarlılık sorunu birlikte gelir.
- log veritabanının yalnız yapısı alınır (
--no-data), hotbackup hiç alınmaz. - Komut
mysqldump ... | gzip -9 > dosya 2>> log.txtbiçimindedir. Hata yönlendirmesi gzip'e bağlı olduğu için mysqldump başarısız olsa da küçük bir.gzdosyası oluşur ve hata log.txt'ye düşmez. Her dökümün son satırı-- Dump completed on ...olmalıdır; bu satırı ve dosya boyutunu kontrol et. recoveryhedefi tarihsiz dosya adları bekler ve log'u yapı dökümünden yükler. mysqldump varsayılan olarak her tablodan önceDROP TABLEyazdığı için bu adım mevcut log kayıtlarını siler.wclean7 günden eski yedekleri siler; geç fark edilen bir bozulmada temiz yedek kalmayabilir.- MySQL root kullanıcısı ve parolası Makefile'da düz metin, komut satırında kullanılır.
baks/fsyedeği önceclear.py'yi çalıştırır; her yedekte syslog, syserr, taşınmış eski günlükler veusage.txtsilinir,srv1de çalışırken arşivlenir.
Zamanlama, saklama ve şifreleme
Aşağıdaki düzen bir örnektir; süreleri oyuncu sayına ve disk alanına göre seç:
| Yedek | Ne zaman | Saklama (örnek) | Neden |
|---|---|---|---|
| Soğuk tam yedek | Her bakımda | Birkaç hafta | Tutarlı geri dönüş noktası |
| Sıcak döküm | Gün içinde birkaç saatte bir | Birkaç gün | Çökmeden sonra en yakın nokta |
| Haftalık arşiv | Soğuk yedekten seçilir | Birkaç ay | Geç fark edilen bozulma, hile incelemesi |
| log veritabanı | Ayrı, seyrek | İnceleme ihtiyacına göre | En büyük ve en az kritik veri |
| Sunucu dosyaları | Her değişiklikten önce | Sürüm başına | Güncellemeyi geri alma |
Güncellemeden önce hangi dosyaların saklanacağı server güncelleme yazısında. En az bir kopya sunucunun ve barındırma firmasının dışında durmalıdır; disk arızası ya da kapanan bir hesap aynı makinedeki yedekleri de götürür.
Yedekler hassastır: account her hesabın parola özetini, silme kodunu ve e-postasını tutar, log IP adreslerini. Parola özeti tuzsuzdur, yani aynı parola her hesapta aynı özeti verir. Dökümü sıkıştırdıktan sonra bir açık anahtarla şifrele; özel anahtar sunucuda durmasın:
... | gzip -9 | gpg --encrypt --recipient YEDEK_ANAHTARI --output /yedek/player_$(date +%F).sql.gz.gpg
Yedek klasörünü yalnız yedek kullanıcısı okuyabilsin ve web sitesinin klasöründe durmasın.
Çökme anında neler kaybolur?
| Olay | Kaybolabilecekler | Ardından |
|---|---|---|
| Bir oyun çekirdeği çöker | O çekirdekteki oyuncuların son kayıttan sonraki ilerlemesi: karakter verisi en fazla 180 saniye (SAVE_EVENT_SECOND_CYCLE) ya da son ticaret, NPC alışverişi, seviye atlama ve ışınlanmadan beri; eşya değişiklikleri birkaç saniye |
Diğer çekirdekler ve db çalışmaya devam eder |
db çekirdeği çöker ya da kill -9 ile kapanır |
MySQL'e henüz yazılmamış karakter (en fazla 420 saniye) ve eşya (300 saniye) değişiklikleri; quest bayrakları zaten yazılmıştır | Oyun çekirdekleri 3 saniyede bir yeniden bağlanmayı dener; gruplar dağılır, lonca savaşları durur |
| Makine ya da MySQL aniden kapanır | Yukarıdakilere ek olarak MyISAM tabloları bozulabilir | Çekirdekleri açmadan tabloları CHECK TABLE ile denetle, gerekirse REPAIR TABLE ile onar |
Bozuk işaretlenmiş bir tabloya giden sorguyu çekirdekler bırakmaz, syserr'e AsyncSQL: retrying yazarak tekrar tekrar dener. Elektrik kesintisinden sonra bu satırları görüyorsan önce tabloları onar.
Kaybolan veri, çekirdeklerin yeniden bağlanmasıyla geri gelmez. Geri alma mı yapılacağı, tazminat mı verileceği önceden yazılmış bir kurala göre seçilir (açılış planı).
Geri yükleme provası nasıl yapılır?
- Ayrı bir makine ya da ayrı bir MySQL örneği kullan; provayı canlı veritabanında yapma.
- Paketin
sql/basedosyalarıyla beş veritabanını ve çekirdek kullanıcısını oluştur. Dökümler MySQL kullanıcılarını içermez; hotbackup boş da olsa bulunmalıdır, yoksa db çekirdeği açılmaz. - Dökümleri yükle:
gunzip < player_TARIH.sql.gz | mysql player. Dökümü olduğu gibi yükle, araya karakter kümesini dönüştüren bir araç koyma. - Test kopyasının conf.txt ve CONFIG dosyalarını test veritabanına ve farklı portlara yönelt. Test kopyası canlı MySQL'e bağlanırsa iki db çekirdeği aynı tabloları birbirinin üstüne yazar.
- Çekirdekleri aç; db'nin syserr'i temiz olmalı.
- Test hesaplarıyla gir: karakter listesi, envanter, depo, Nesne Market deposu, lonca ve amblem.
SELECT COUNT(*)ile account, player ve item tablolarının satır sayılarını canlıdakiyle karşılaştır.- Geri yüklemenin ne kadar sürdüğünü not et; gerçek bir kesintide oyunculara söyleyeceğin süre budur.
Kısmi geri yükleme ve silinen karakter
Tek bir oyuncunun verisi için bütün sunucuyu geri alma. Yedeği ayrı bir adla açılan veritabanına yükle ve gereken satırları sunucu kapalıyken aktar. Sunucu açıkken aktarırsan, oyuncu çevrimiçiyse ya da çıkışından sonraki 10 dakika içindeyse db önbelleği aktardığın satırları ezer.
Silinen bir karakterde player_deleted yalnız karakter satırını tutar; envanter, ekipman, simya ve kemer eşyaları, quest bayrakları, etkiler ve lonca üyeliği silinir (karakter silme). Bunlar ancak silmeden önceki bir yedekte vardır.
Farklı anlara ait parçaları karıştırırken bağları unutma: depo ve Nesne Market deposu eşyaları hesap numarasına bağlıdır; bakiye (cash) account'ta, dışarıdan gönderilen eşyalar player'daki item_award'da durur. Yalnız player'ı geri alırsan yedekten sonra açılan hesaplar korunur, ama o arada harcanan bakiye geri gelmez.
Sık sorulan sorular
- Metin2'de oyun açıkken yedek alınır mı?
- Alınır, ama döküm db çekirdeğinin o ana kadar MySQL'e yazdığı hâli içerir: karakter verisi en fazla yaklaşık 7, eşyalar 5 dakika geriden gelir. Bu yedek, sunucu o anda çökmüş gibi bir geri dönüş noktasıdır. Tam tutarlı yedek için sunucu stop.py ile kapatılır, db önbelleği yazdıktan sonra döküm alınır.
- Silinen karakter geri getirilebilir mi?
- player_deleted tablosu yalnız karakterin kendi satırını tutar; silme sırasında envanter ve ekipman eşyaları, quest bayrakları, etkiler ve lonca üyeliği silinir. Bunlar ancak silmeden önce alınmış bir yedekten, sunucu kapalıyken geri aktarılabilir.
- Yedeği yeni makineye yükledim, db çekirdeği açılmıyor. Neden?
- Veritabanı dökümleri MySQL kullanıcılarını ve boş hotbackup veritabanını içermez. db çekirdeği hotbackup bağlantısı olmadan açılmaz, çekirdeklerin kullandığı MySQL kullanıcısı da yeniden oluşturulmalıdır; ikisi paketin sql/base klasöründeki dosyalarla kurulur.
İlgili sayfalar
- Metin2 PvP Server Açılış Planı: Açılıştan Önceki 30 Gün (Server kurma)
- Metin2 db conf.txt Ayarları: SQL Satırları, BIND_PORT ve ITEM_ID_RANGE (Server kurma)
- Metin2 Karakter Silme Kodu Nedir? Karakter Nasıl Silinir (Rehber)
- Metin2 Lonca Amblemi Nasıl Yüklenir? Boyut, Biçim ve Sık Hatalar (Wiki)
- Metin2 EXP, Drop ve Yang Oranı Nasıl Ayarlanır? (Server kurma)
Kategori: Server Kurma Server Kurulumu veritabanı yedekleme mysqldump geri yükleme server yönetimi
Bu sayfadaki bilgiler Metin2'nin sunucu yazılımındaki hesaplamalara ve standart oyun dosyalarına dayanır. Oyun dosyalarını değiştiren sunucularda değerler farklı olabilir. İçerikleri nasıl hazırlıyoruz?