- Katılım
- 22 Ara 2011
- Konular
- 49
- Mesajlar
- 245
- Online süresi
- 6d 15h
- Reaksiyon Skoru
- 187
- Altın Konu
- 2
- Başarım Puanı
- 138
- MmoLira
- 141
- DevLira
- 6
ROHAN2 WORLD 1-120 TR TİPİ OFFICIAL YOHARA, BALATHOR VE AMON! 80. GÜNÜNDE! +10.000 ONLİNE! HİLE VE BOT %100 ENGELLİ HEMEN TIKLA!
HEDEF SÜRÜM: 40K–55K tüm farm dosyaları
LİSANSLAMA: MIT – serbest kullanım
[/CODE]
Açıklama
Farm sunucularında anlık DROP yoğunluğu sırasında gamed’in milisaniyelik MySQL kilitlenmeleri 3-5 sn’lik “mikro-donma” yaratır. Aşağıdaki yöntem, bu zamana kadar Turkmmo’da yayınlanmamış, tamamen yeni ve kalıcı bir çözümdür.
---
**Belirtiler (Problem Tanı)**
- Kanal TPS (ticks-per-second) aniden 50→5’e düşer, CPU boşta kalır.
- `syslog` içinde “InnoDB wait for lock” satırları.
- Oyuncu dropları yere düştüğünde veya toplarken hissedilen lag.
---
**Kök Neden**
- `log.item` (veya `player.item_log`) tablosuna senkron tek tek `INSERT` yapan 200+ eşzamanlı thread.
- MySQL’de AUTO_INCREMENT kilidi; özellikle `REPEATABLE-READ` + `ROW_FORMAT=COMPACT` kullanıldığında tampon taşması.
- Büyük farm sunucularında saniyede ~4 000 sorgu → buffer pool thrash.
---
**KESİN ÇÖZÜM – “ASYNC DROPLOG PIPELINE”**
---
**Kurulum Sırası**
1. Yeni tabloyu import et.
2. `log.cpp` patch’ini uygula, `gmake clean && gmake` ile gamed’i derle.
3. `flush_daemon.py`’yı `/root` dizinine kopyala, cron’a ekle.
4. Eski `INSERT INTO item_log …` çağrılarını `ItemLogAsync` ile değiştir.
5. MySQL `innodb_flush_log_at_trx_commit=2`, `binlog_format=ROW` ayarla.
6. Sunucuyu aç, `itemlog_queue`’yun saniyede artıp 0’a düştüğünü izle.
---
**Ek Sorunlar & Çözümleri**
**Veri Kaybı Endişesi**
- flush_daemon 0.2 sn aralıkla aktardığından maksimum kayıp 1 kayıt olur (sunucu çökse). `innodb_doublewrite=ON` korur.
---
**Queue Şişmesi (>1 M satır)**
- **Sebep**: daemon kapanmış.
- **Çözüm**: `systemctl --failed` kontrol; watchdog ekle:
---
**“wait for flush list” MySQL Logu**
- **Sebep**: Disk IOPS yetersiz.
- **Çözüm**: `innodb_flush_method=O_DIRECT`, NVMe veya RAID-10 geç.
---
**Alternatif Performans Yöntemleri**
**Redis Buffer**
- drop_buffer → redis `LPUSH`, ayrı worker `BRPOP` → MySQL; tek satır bile kaybolmaz (AOF).
---
**Sıkça Sorulan Diğer Farm Lag Kaynakları**
**Büyük Sürgün Mağarası Lagı**
- Monster AI tick süresi 100 ms yerine 20 ms: `ai_speed` ini değeri → 5 000 altı tut.
**Kargo NPC Basılması**
- Yığılmış `refine_log` → haftalık `PARTITION BY RANGE (ts)`
**Shop Flood (CH1 pazar)**
- PHP itemshop READ UNCOMMITTED + memcached front-cache.
---
LİSANSLAMA: MIT – serbest kullanım
[/CODE]
Açıklama
Farm sunucularında anlık DROP yoğunluğu sırasında gamed’in milisaniyelik MySQL kilitlenmeleri 3-5 sn’lik “mikro-donma” yaratır. Aşağıdaki yöntem, bu zamana kadar Turkmmo’da yayınlanmamış, tamamen yeni ve kalıcı bir çözümdür.
---
**Belirtiler (Problem Tanı)**
- Kanal TPS (ticks-per-second) aniden 50→5’e düşer, CPU boşta kalır.
- `syslog` içinde “InnoDB wait for lock” satırları.
- Oyuncu dropları yere düştüğünde veya toplarken hissedilen lag.
---
**Kök Neden**
- `log.item` (veya `player.item_log`) tablosuna senkron tek tek `INSERT` yapan 200+ eşzamanlı thread.
- MySQL’de AUTO_INCREMENT kilidi; özellikle `REPEATABLE-READ` + `ROW_FORMAT=COMPACT` kullanıldığında tampon taşması.
- Büyük farm sunucularında saniyede ~4 000 sorgu → buffer pool thrash.
---
**KESİN ÇÖZÜM – “ASYNC DROPLOG PIPELINE”**
Kod:
-- 1) Yeni Kuyruk Tablosu (kilitsiz)
CREATE TABLE itemlog_queue (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
pid INT UNSIGNED,
item_vnum INT UNSIGNED,
qty SMALLINT UNSIGNED,
map_idx SMALLINT UNSIGNED,
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
KEY(pid), KEY(item_vnum)
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
Kod:
-- 2) C++ PATCH (game/src/log.cpp)
static std::vector<std::string> drop_buffer;
static time_t flush_tick = 0;
void LogManager::ItemLogAsync(DWORD pid, DWORD vnum, int qty, int map)
{
char buf[256];
snprintf(buf,sizeof(buf),"(%u,%u,%d,%d)",pid,vnum,qty,map);
drop_buffer.emplace_back(buf);
if (drop_buffer.size() >= 200 || get_dword_time()-flush_tick > 1000)
FlushDropBuffer();
}
void LogManager::FlushDropBuffer()
{
if(drop_buffer.empty()) return;
std::string q = "INSERT INTO player.itemlog_queue (pid,item_vnum,qty,map_idx) VALUES ";
q += boost::algorithm::join(drop_buffer, ",");
CDBManager::instance().AsyncQuery(q.c_str(),"LOG");
drop_buffer.clear();
flush_tick = get_dword_time();
}
Kod:
# 3) Dış Servis – flush_daemon.py
import pymysql, time
DB = pymysql.connect(host='127.0.0.1',user='root',passwd='pw',db='player',autocommit=True)
while True:
with DB.cursor() as c:
c.execute("""INSERT INTO item_log
(pid,item_vnum,qty,map_idx,ts)
SELECT pid,item_vnum,qty,map_idx,ts
FROM itemlog_queue ORDER BY id LIMIT 5000""")
moved = c.rowcount
if moved:
c.execute("DELETE FROM itemlog_queue ORDER BY id LIMIT %s", (moved,))
time.sleep(0.2)
Kod:
# 4) CRON – daemon başlat
@reboot root /usr/bin/python3 /root/flush_daemon.py &
---
**Kurulum Sırası**
1. Yeni tabloyu import et.
2. `log.cpp` patch’ini uygula, `gmake clean && gmake` ile gamed’i derle.
3. `flush_daemon.py`’yı `/root` dizinine kopyala, cron’a ekle.
4. Eski `INSERT INTO item_log …` çağrılarını `ItemLogAsync` ile değiştir.
5. MySQL `innodb_flush_log_at_trx_commit=2`, `binlog_format=ROW` ayarla.
6. Sunucuyu aç, `itemlog_queue`’yun saniyede artıp 0’a düştüğünü izle.
---
**Ek Sorunlar & Çözümleri**
**Veri Kaybı Endişesi**
- flush_daemon 0.2 sn aralıkla aktardığından maksimum kayıp 1 kayıt olur (sunucu çökse). `innodb_doublewrite=ON` korur.
---
**Queue Şişmesi (>1 M satır)**
- **Sebep**: daemon kapanmış.
- **Çözüm**: `systemctl --failed` kontrol; watchdog ekle:
Kod:
*/1 * * * * root pgrep -f flush_daemon.py || /usr/bin/python3 /root/flush_daemon.py &
---
**“wait for flush list” MySQL Logu**
- **Sebep**: Disk IOPS yetersiz.
- **Çözüm**: `innodb_flush_method=O_DIRECT`, NVMe veya RAID-10 geç.
---
**Alternatif Performans Yöntemleri**
**Redis Buffer**
- drop_buffer → redis `LPUSH`, ayrı worker `BRPOP` → MySQL; tek satır bile kaybolmaz (AOF).
---
**Sıkça Sorulan Diğer Farm Lag Kaynakları**
**Büyük Sürgün Mağarası Lagı**
- Monster AI tick süresi 100 ms yerine 20 ms: `ai_speed` ini değeri → 5 000 altı tut.
**Kargo NPC Basılması**
- Yığılmış `refine_log` → haftalık `PARTITION BY RANGE (ts)`
**Shop Flood (CH1 pazar)**
- PHP itemshop READ UNCOMMITTED + memcached front-cache.
---
Kod:
[B]PERİYODİK BAKIM ÖNERİLERİ:[/B]
• `OPTIMIZE TABLE itemlog_queue,item_log PARTITION p2024_*;`
• Haftalık NVMe smartctl – “Media_Wearout_Indicator” takibi
• flush_daemon log’unu `/var/log/drop_flush.log` dosyasında sakla
Kod:
metin2, pvp, farm, lag, deadlock, mysql, itemlog, async, rehber, optimizasyon


