İçeriğe geç

Metin2'de MySQL Nedir? Yeni Başlayanlar İçin Veritabanı

Hazırlayan: Metin2VIP Editörleri Yayın: 6 dk okuma

Kısaca: MySQL, Metin2 sunucusunun kalıcı hafızasıdır: hesaplar, karakterler, eşyalar, depo, GM listesi ve oyun içi kayıtlar burada tutulur. Oyun çekirdekleri karakter ve eşya verisine doğrudan değil db çekirdeği üzerinden ulaşır; db bu veriyi önbellekte tutar ve birkaç dakikada bir MySQL'e yazar. Bu yüzden oyuncu oyundayken ya da yeni çıkmışken MySQL'de yapılan değişiklik ezilebilir; düzenlemeden önce yedek alınır ve oyuncunun çıkmış, önbelleğin boşalmış olması beklenir.
İçindekiler
  1. Metin2 sunucusunda MySQL ne işe yarar?
  2. db çekirdeği ile MySQL arasındaki ilişki
  3. MySQL'e nasıl bağlanılır?
    1. Komut satırı
    2. HeidiSQL ve Navicat
    3. Hangi kullanıcıyla bağlanılmalı?
  4. Güvenli çalışma alışkanlıkları
  5. Önce yedek: neden ve nasıl?
  6. Sunucu açıkken neden dikkatli olunmalı?

MySQL, Metin2 sunucusunun kalıcı hafızasıdır. Hesaplar, karakterler, eşyalar, depo, GM listesi ve oyun içi kayıtlar MySQL'deki veritabanlarında tutulur; sunucu kapanıp açıldığında oyunun kaldığı yerden devam etmesi bu sayede olur. Oyun çekirdekleri karakter ve eşya verisine doğrudan değil, araya giren db çekirdeği üzerinden ulaşır. db bu veriyi önbellekte tutup birkaç dakikada bir MySQL'e yazdığı için, MySQL'de bir değeri değiştirmek oyunda o değerin hemen geçerli olacağı anlamına gelmez.

Aşağıdaki davranışlar Metin2'nin kendi sunucu kodundan gelir; db çekirdeğini ve tabloları değiştirmemiş sunucuların çok büyük çoğunluğunda aynı işler. Veritabanlarının tek tek tanıtımı Metin2 veritabanları yazısında.

Metin2 sunucusunda MySQL ne işe yarar?

Metin2 her şeyi MySQL'de tutmaz. Oyun boyunca değişen ve kaybolmaması gereken veri MySQL'dedir; sunucu sahibinin elle hazırladığı ayarların çoğu ise dosyadadır. Canavar düşüşleri, cube tarifleri, haritalar ve questler oyun çekirdekleri açılırken dosyalardan okunur (drop dosyaları).

Veri Durduğu yer Kim okur, kim yazar
Hesap, parola özeti, ban account.account Auth çekirdeği her girişte okur
Karakterler player.player db çekirdeği, önbellekle
Envanter, ekipman ve depo eşyaları player.item db çekirdeği; depo eşyaları değiştiği anda yazılır
Görev bayrakları, süren etkiler player.quest, player.affect db her girişte MySQL'den okur
Depo boyutu ve depo şifresi player.safebox db, depo açılınca
GM listesi, yerel ayar, EXP tablosu common veritabanı Çekirdekler açılışta okur
Oyun içi kayıtlar log veritabanı Oyun çekirdekleri doğrudan yazar
Eşya ve canavar tabloları db klasöründeki item_proto.txt, mob_proto.txt; MySQL'de kopyası db açılışta okur
Drop, cube, harita, quest share/locale/turkey altındaki dosyalar Oyun çekirdekleri açılışta okur

Eşya ve canavar tablolarının MySQL'deki kopyası, yaygın paketlerde her db açılışında txt dosyasıyla ezilir; bu yüzden onları MySQL'de düzenlemek oyuna yansımaz. Ayrıntısı item_proto yazısında.

db çekirdeği ile MySQL arasındaki ilişki

Oyuncu bir karakter seçtiğinde oyun çekirdeği karakteri db'den ister. db karakter önbellekteyse onu gönderir, değilse player satırını ve eşyalarını MySQL'den okuyup önbelleğe alır. Oyun sırasında oyun çekirdeği değişiklikleri db'ye bildirir, db de bunları belli aralıklarla MySQL'e yazar.

Ne MySQL'e ne zaman yazılır
Karakter satırı (player) Değiştiyse varsayılan olarak 7 dakikada (420 saniye) bir
Envanter ve ekipman (item) Değiştiyse 5 dakikada (300 saniye) bir
Depo ve Nesne Marketi Deposu eşyaları Değiştiği anda, önbelleğe girmez
Görev bayrakları ve etkiler Oyun çekirdeği kaydettikçe; girişte her seferinde MySQL'den okunur
Oyundan çıkan karakter 10 dakika daha önbellekte kalır, sonra yazılıp önbellekten silinir

İlk iki süre db'nin conf.txt dosyasından değiştirilebilir (en çok 1.800 saniye), çıkıştan sonraki 10 dakika ise koda gömülüdür (db conf.txt). Sunucu stop.py ile düzgün kapatıldığında db önbellekteki her şeyi MySQL'e yazar; süreci zorla öldürmek son yazmadan sonraki ilerlemeyi kaybettirir.

account, common ve log veritabanları bu önbelleğe girmez. Auth her girişte hesabı MySQL'den okuduğu için ban gibi hesap değişiklikleri bir sonraki girişte geçerli olur. Oyun çekirdekleri log veritabanına db'yi beklemeden, kendi bağlantılarıyla yazar.

MySQL'e nasıl bağlanılır?

Komut satırı

Sunucuya SSH ile bağlandıktan sonra MySQL'in kendi istemcisi kullanılır:

mysql -u YONETICI -p --safe-updates player

--safe-updates dikkatsizliğe karşı bir sigortadır: WHERE koşulunda anahtar sütun ya da LIMIT bulunmayan UPDATE ve DELETE komutlarını reddeder. Metin2 tablolarında player.id, player.name, account.login, item.id ve item.owner_id anahtarlıdır; bunlarla yazılan sorgular bu modda da çalışır.

HeidiSQL ve Navicat

Windows'tan çalışanlar için HeidiSQL ücretsiz, Navicat ücretli bir görsel istemcidir; ikisiyle de tablo açmak, satır düzenlemek ve SQL çalıştırmak mümkündür. Asıl önemli olan bağlantının nasıl kurulduğudur: MySQL'in 3306 portunu internete açmak yerine SSH tüneli kullanılır. İki programın bağlantı ayarlarında da bir SSH bölümü vardır; oraya sunucunun adresi ve SSH kullanıcısı, MySQL bölümüne ise adres olarak 127.0.0.1 yazılır. Tünel elle de açılabilir:

ssh -L 3307:127.0.0.1:3306 kullanici@SUNUCU_IP

Bu komut açıkken bilgisayardaki herhangi bir istemci 127.0.0.1:3307 adresine bağlanır, trafik SSH içinden sunucudaki MySQL'e gider. Açık bırakılan 3306 portunun riski server güvenlik hataları yazısında.

Hangi kullanıcıyla bağlanılmalı?

Yaygın paketlerin oluşturduğu mt2 kullanıcısı yalnız sunucunun kendisinden bağlanır ve beş veritabanında yalnız SELECT, INSERT, UPDATE ve DELETE yapabilir. Ban atmak, eşya vermek ya da GM eklemek için bu yetkiler yeter. Tabloya sütun ya da indeks eklemek ve yedek almak için ise ayrı bir yönetici kullanıcı gerekir: mysqldump varsayılan olarak tabloları kilitler ve bunun için LOCK TABLES yetkisi ister. Yönetici kullanıcı da yalnız localhost'tan bağlanmalı, root'a uzaktan erişim hiç açılmamalıdır. Kullanıcıların nasıl oluşturulduğu server kurulumu yazısında.

Güvenli çalışma alışkanlıkları

  1. Önce SELECT, sonra UPDATE. Değiştireceğin satırları aynı WHERE koşuluyla önce listele, satır sayısının beklediğin gibi olduğunu gör, sonra aynı koşulla UPDATE yaz.
  2. Tek satırı hedefle. Karakterde id, hesapta login kullan; tek satır değişecekse sorgunun sonuna LIMIT 1 ekle.
  3. Geri alma olmadığını bil. Metin2 tabloları MyISAM motorundadır ve işlem (transaction) desteklemez; ROLLBACK bu tablolarda hiçbir şeyi geri getirmez. Yanlış bir UPDATE'ten tek dönüş yolu yedektir.
  4. Oyuncu verisini oyuncu yokken değiştir. Ne zaman güvenli olduğu aşağıdaki bölümde.
  5. Türkçe metinlere dikkat et. Tabloların çoğu latin1, kayıt metinlerini tutan log sütunları ise ikili (varbinary) tanımlıdır; oyun çekirdekleri MySQL'e latin5 karakter kümesiyle bağlanır. Bu yüzden görsel istemcide Türkçe harfler farklı görünebilir. ğ, ş ve ı latin1'de bulunmadığı için bir metni istemciden yeniden yazmak bu harfleri soru işaretine çevirebilir. Karakter adları zaten yalnız harf ve rakamdan oluşur.

Eşya verme, ban, seviye ve GM için hazır sorgular MySQL ile sık yapılan işlemler yazısında.

Önce yedek: neden ve nasıl?

Bir sorgunun yanlış satıra ya da bütün tabloya gitmesi tek harflik bir hatayla olur ve MyISAM'da geri alınamaz. Bu yüzden her elle düzenlemeden önce en azından değişecek satırların yedeği alınır. mysqldump'ın --where seçeneği tek bir karakterin satırlarını ayırmaya yarar:

mysqldump -u YONETICI -p --no-create-info --replace player item --where="owner_id=1234" > item_1234_once.sql

--no-create-info burada zorunludur: o olmadan dosya DROP TABLE ve CREATE TABLE satırlarıyla başlar ve geri yüklendiğinde bütün item tablosunu silip yalnız bu karakterin eşyalarını bırakır. --replace geri yüklemede değişmiş satırların eski haliyle üzerine yazılmasını sağlar; yedekten sonra eklenmiş satırlar ise silinmez, onlar ayrıca kaldırılır. Geri yükleme mysql -u YONETICI -p player < item_1234_once.sql ile yapılır.

Sunucu açıkken alınan yedek, db önbelleğinde bekleyen son birkaç dakikanın değişikliklerini içermez. Tam ve tutarlı bir yedek için sunucu stop.py ile kapatılır, db önbelleği yazdıktan sonra dump alınır. mysqldump tabloları her veritabanı için ayrı kilitlediğinden, sunucu açıkken alınan account ve player dökümleri aynı ana ait olmayabilir. Düzenli yedek düzeni server yedekleme yazısında.

Sunucu açıkken neden dikkatli olunmalı?

Sorun db'nin önbelleğidir. Oyundaki bir oyuncunun Yang'ını MySQL'de 1.000.000'dan 5.000.000'a çıkardığını düşün. db o karakterin satırını önbellekte 1.000.000 olarak tutuyor ve birkaç dakika içindeki ilk yazmada MySQL'deki 5.000.000'u kendi değeriyle ezer. Oyun çekirdeği de karakteri bellekte tuttuğu için her kayıtta yine eski değeri gönderir. Eşya eklemek daha da risklidir: oyundaki karakter yeni satırı görmez, sunucu açıkken eklenen bir eşyanın kimliği ise bir oyun çekirdeğinin birazdan oluşturacağı eşyanınkiyle çakışabilir (item tablosu).

Durum Güvenli yol
Oyuncu oyunda Oyun içi GM komutu; eşya için item_award tablosu
Oyuncu yeni çıktı 10 dakika bekle ya da IMPLEMENTOR yetkili bir GM /flush <karakter numarası> yazsın
Çok sayıda karakter değişecek Sunucuyu stop.py ile kapat, düzenle, yeniden aç
Ban, GM listesi (account, common) Her zaman; ban bir sonraki girişte, GM listesi /reload a ile geçerli olur
Görev bayrakları, etkiler Oyuncu çevrim dışıyken

/flush, oyundan çıkmış bir oyuncunun önbellekteki karakter ve eşya verisini hemen MySQL'e yazar ve önbellekten siler; ardından yapılan düzenlemeyi oyuncu bir sonraki girişinde görür. Oyundaki bir oyuncu için kullanılması işe yaramaz, çünkü oyun çekirdeği karakteri bellekte tutmaya devam eder. Komutların seviyeleri GM komutları sayfasında, hangi karakter sütununun güvenle değiştirilebileceği player tablosu yazısında.

Sık sorulan sorular

Metin2'de MySQL şifresi nerede yazılı?
Auth ve oyun çekirdeklerinde her çekirdeğin CONFIG dosyasındaki PLAYER_SQL, COMMON_SQL ve LOG_SQL satırlarında, db çekirdeğinde conf.txt'deki SQL_ satırlarında. Yaygın paketler bu dosyaları gen_settings.py'den ürettiği için parola orada da değiştirilmelidir; tek bir dosyayı unutmak o çekirdeğin açılmamasına yol açar.
MySQL'de değiştirdiğim değer oyunda görünmüyor, neden?
Karakter ve eşya tablolarında büyük ihtimalle db çekirdeğinin önbelleği değişikliği ezmiştir: oyuncu oyundaysa ya da 10 dakikadan kısa süre önce çıktıysa db kendi kopyasını MySQL'e yazar. item_proto ve mob_proto içinse yaygın paketlerde db her açılışta MySQL'deki tabloyu txt dosyasıyla ezer; bu tablolar txt dosyasında düzenlenir.
Metin2 için Navicat mı, HeidiSQL mi?
İkisi de iş görür; HeidiSQL ücretsiz, Navicat ücretlidir. Hangisi seçilirse seçilsin MySQL portunu internete açmadan SSH tüneliyle bağlanılmalı ve yalnız sunucunun kendisinden bağlanabilen bir yönetici kullanıcı kullanılmalıdır.

İlgili sayfalar

Kategori: Server Kurma Server Kurulumu veritabanı server kurulumu mysql heidisql navicat

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?

Bu sayfa işine yaradı mı?

Giriş yap, oy ver ya da sayfayı kaydet. Okumak için üyelik gerekmez. WhatsApp X'te paylaş
Yanlış ya da eksik bir bilgi mi gördün? Bildir
Neyin yanlış olduğunu, doğrusunun ne olduğunu ve bunu nereden bildiğini yaz. Mesajın editörlere gider; yazı, kontrol edildikten sonra düzeltilir.
Yalnız editör görür.

Tartışma

Kurallar

Henüz yorum yok. Bu konuda bir deneyimin ya da sorun varsa ilk yorumu sen yaz.

Giriş yap ya da kayıt ol, sonra yorum yaz. Metin2VIP üyeliği hiçbir oyun sunucusunun hesabı değildir.