aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Oyun Sunucusu

MySQL Replikasyon: Master-Slave Kurulum Rehberi

Bir oyun sunucusu ya da yoğun bir web uygulaması büyüdükçe, tek bir veritabanı tüm okuma ve yazma yükünü tek başına taşımakta zorlanır. MySQL replikasyon, verini bir ana sunucudan (master) bir veya daha fazla kopyaya (replica/slave) gerçek zamanlıya yakın aktararak bu yükü dağıtmanı sağlar: yazma işlemleri master'a gider, ağır okuma sorgularını ise replikalara dağıtırsın. Bu rehberde master-replica yapısını sıfırdan kuracak, GTID tabanlı modern yaklaşımı kullanacak ve replikanın sağlığını nasıl izleyeceğini göreceksin.

Replikasyon nasıl çalışır?

MySQL replikasyonunun temelinde binary log (binlog) yatar. Master üzerinde yapılan her veri değiştiren işlem (INSERT, UPDATE, DELETE, DDL) binlog'a yazılır. Replika, master'a bağlanır, bu logu kendi relay log'una kopyalar ve ardından olayları kendi üzerinde tekrar uygular. Süreç iki iş parçacığıyla yürür:

  • I/O thread: Master'ın binlog'unu okuyup replikanın relay log'una yazar.
  • SQL (applier) thread: Relay log'daki olayları replikanın verisine uygular.

Varsayılan replikasyon asenkrondır: master, replikanın olayı aldığını beklemeden işlemini tamamlar. Bu, replikanın master'ın birkaç saniye gerisine düşebileceği anlamına gelir; buna replication lag denir. Bunun bilincinde olmak, okuma dağıtımı tasarlarken kritiktir.

Master sunucuyu yapılandırma

İlk adım master üzerinde binary log'u açmak ve sunucuya benzersiz bir kimlik vermek. Her replikasyon düğümünün ağ genelinde eşsiz bir server_id değeri olmalıdır. my.cnf dosyasının [mysqld] bölümüne ekle:

[mysqld]
server_id = 1
log_bin = /var/log/mysql/mysql-bin.log
binlog_format = ROW
gtid_mode = ON
enforce_gtid_consistency = ON
bind_address = 0.0.0.0

binlog_format = ROW, satır bazlı değişiklikleri kaydeder ve STATEMENT moduna göre çok daha güvenilirdir. gtid_mode = ON ise modern, konum yönetimini otomatikleştiren GTID tabanlı replikasyonu açar. Değişiklikten sonra servisi yeniden başlat:

sudo systemctl restart mysql

Sonra replikanın bağlanacağı özel bir kullanıcı oluştur. Bu kullanıcıya sadece REPLICATION SLAVE yetkisini ver; geniş yetki verme:

CREATE USER 'repl'@'%' IDENTIFIED BY 'GucluParola!';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;

Mevcut veriyi replikaya taşıma

Replika master'ı yakalamadan önce var olan veriyle aynı noktadan başlamalı. Tutarlı bir anlık görüntü almanın en temiz yolu mysqldump aracıdır. GTID açıkken, dökümün içine başlangıç GTID kümesi de gömülür:

mysqldump --all-databases --single-transaction \
  --source-data=2 --triggers --routines --events \
  -u root -p > tam-yedek.sql

--single-transaction, InnoDB tabloları kilitlemeden tutarlı bir görüntü alır; --source-data=2 ise binlog konumunu yorum olarak ekler. Dosyayı replikaya kopyala ve içeri aktar:

scp tam-yedek.sql kullanici@replika-ip:/tmp/
# replika üzerinde:
mysql -u root -p < /tmp/tam-yedek.sql

Replika sunucuyu bağlama

Replikanın my.cnf dosyasında farklı bir server_id ver ve onu salt okunur yapmayı düşün; böylece yanlışlıkla yapılan yazmalar replikasyonu bozmaz:

[mysqld]
server_id = 2
gtid_mode = ON
enforce_gtid_consistency = ON
read_only = ON
super_read_only = ON
relay_log = /var/log/mysql/relay-bin.log

Servisi yeniden başlattıktan sonra replikayı master'a yönlendir. MySQL 8'de modern komutlar SOURCE terminolojisini kullanır:

CHANGE REPLICATION SOURCE TO
  SOURCE_HOST = '10.0.0.1',
  SOURCE_USER = 'repl',
  SOURCE_PASSWORD = 'GucluParola!',
  SOURCE_AUTO_POSITION = 1;

START REPLICA;

SOURCE_AUTO_POSITION = 1, GTID sayesinde binlog dosya adı ve konumunu elle girmek zorunda kalmadan replikanın doğru noktadan devam etmesini sağlar. Eski sürümlerde aynı işin karşılığı CHANGE MASTER TO ... MASTER_AUTO_POSITION = 1 ve START SLAVE komutlarıdır.

Replikasyonu izleme ve sorun giderme

Replikanın gerçekten çalışıp çalışmadığını görmek için durumunu sorgula:

SHOW REPLICA STATUS\G

Çıktıda şu üç alana özellikle dikkat et:

  • Replica_IO_Running: Yes ve Replica_SQL_Running: Yes — iki thread de çalışıyor olmalı.
  • Seconds_Behind_Source — replikanın master'a göre kaç saniye geride olduğu. Sürekli artıyorsa replika yükü yakalayamıyordur.
  • Last_Error — boş değilse SQL thread bir olayı uygularken takılmıştır.

Lag'in en yaygın sebepleri yavaş disk, replikada eksik indeksler ve tek thread'li uygulamadır. MySQL 8'de replica_parallel_workers değerini artırarak olayları paralel uygulayabilirsin:

SET GLOBAL replica_parallel_workers = 4;

Tutarlılık açısından daha güçlü garanti istiyorsan yarı senkron (semi-synchronous) replikasyonu açabilirsin; bu modda master, en az bir replika olayı relay log'una yazana kadar commit'i onaylamaz. Eklentiyi yükleyip etkinleştirmen gerekir:

INSTALL PLUGIN rpl_semi_sync_source SONAME 'semisync_source.so';
SET GLOBAL rpl_semi_sync_source_enabled = 1;

Okuma yükünü dağıtma

Replikasyonun asıl amacı yükü bölmektir. Uygulamanda iki bağlantı havuzu tut: yazma ve SELECT ... FOR UPDATE gibi tutarlılık gerektiren sorgular master'a, raporlama ve listeleme gibi ağır okumalar replikalara gitsin. Laravel gibi framework'ler bunu yapılandırma seviyesinde destekler:

'mysql' => [
  'read'  => ['host' => ['10.0.0.2']],
  'write' => ['host' => ['10.0.0.1']],
  'sticky' => true,
],

sticky => true kritik bir ayrıntıdır: aynı istek içinde bir yazma yaptıysan, sonraki okumaları da master'dan yapar; böylece replika lag yüzünden henüz görünmeyen veriyi okuma sorununu engellersin.

Sık Sorulan Sorular

Replikasyon ile yedekleme aynı şey mi?

Hayır. Replika, master'daki her işlemi tekrarladığı için yanlışlıkla silinen bir tabloyu da anında siler. Replikasyon yüksek erişilebilirlik ve yük dağıtımı içindir; veri kurtarma için yine de düzenli mysqldump ya da fiziksel yedekler almalısın.

Birden fazla replika ekleyebilir miyim?

Evet. Master birden çok replikayı besleyebilir; her birine farklı bir server_id verip aynı kurulum adımlarını tekrarlaman yeterli. Yatay okuma ölçeklemesi için en yaygın yöntem budur.

Replika master'ın gerisine düşerse ne yapmalıyım?

Önce Seconds_Behind_Source değerini izle. Kalıcı lag'de replika diskini hızlandır (SSD/NVMe), paralel applier worker sayısını artır ve replikada eksik indeksleri ekle. Ağır toplu yazmaları küçük partilere bölmek de lag'i belirgin azaltır.

Sunucunu büyütürken veritabanı katmanı seni yavaşlatmasın. Oyun sunucusu ya da web projesi için yüksek erişilebilirlikli bir MySQL replikasyon mimarisi tasarlamak istersen benimle iletişime geç, birlikte kuralım.

Bu kategorideki tüm yazılar →

Devamı için