MySQL ve MariaDB Veritabani Sunucusu Kurulum ve Yonetim Rehberi

Veritabanı sunucusu kurarken “nasılsa çalışıyor” deyip geçmek, ileride başınıza bela açacak en klasik hatalardan biri. MySQL ve MariaDB kurulumu ilk bakışta basit görünse de production ortamında sağlam bir yapı kurmak için bilmeniz gereken onlarca detay var. Bu yazıda sıfırdan kurulumdan başlayarak güvenlik sıkılaştırma, performans ayarları ve günlük yönetim görevlerine kadar her şeyi ele alacağız.

MySQL ve MariaDB: Hangisini Seçmeli?

Önce şunu netleştirelim: MariaDB, MySQL’in 2009’da Oracle tarafından satın alınmasının ardından orijinal geliştiriciler tarafından fork edilen bir proje. Büyük ölçüde MySQL ile uyumlu ama bazı önemli farklar var.

Eğer şu andaki durumunuz:

  • Yeni bir proje başlatıyorsanız: MariaDB tercih edin, topluluk desteği daha güçlü ve açık kaynak taahhüdü daha net
  • Mevcut MySQL kurulumunuz varsa: Geçiş yapabilirsiniz ama önce uygulama uyumluluğunu test edin
  • Oracle ekosistemiyle çalışıyorsanız: MySQL Enterprise size daha fazla entegrasyon seçeneği sunar
  • Galera Cluster kuracaksanız: MariaDB bu konuda çok daha olgun

Biz bu yazıda her iki sistemi de ele alacağız, komutlar büyük ölçüde aynı.

Kurulum

Ubuntu/Debian Üzerinde MariaDB Kurulumu

# Repo anahtarını ekle
curl -LsS https://r.mariadb.org/downloads/mariadb_repo_setup | sudo bash

# Paket listesini güncelle ve kur
sudo apt update
sudo apt install -y mariadb-server mariadb-client

# Servisi başlat ve enable et
sudo systemctl start mariadb
sudo systemctl enable mariadb

# Kurulum durumunu kontrol et
sudo systemctl status mariadb

RHEL/CentOS/Rocky Linux Üzerinde MySQL Kurulumu

# MySQL Community repo ekle
sudo dnf install -y https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm

# GPG anahtarını import et
sudo rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023

# Kurulumu yap
sudo dnf install -y mysql-community-server

# Servisi başlat
sudo systemctl start mysqld
sudo systemctl enable mysqld

# MySQL ilk kurulumda geçici şifre oluşturur, bunu bul
sudo grep 'temporary password' /var/log/mysqld.log

Güvenlik Sıkılaştırma

Kurulum bitti diye sevinmeyin, asıl iş şimdi başlıyor. Varsayılan kurulum bir üretim ortamı için ciddi güvenlik açıkları içerir.

mysql_secure_installation Çalıştırma

sudo mysql_secure_installation

Bu komut sizi interaktif bir sihirbaza götürür. Şu sorulara dikkat edin:

  • Validate Password Plugin: Aktif edin, MEDIUM veya STRONG seçin
  • Remove anonymous users: Evet deyin, bu kullanıcılar production’da işinize yaramaz
  • Disallow root login remotely: Evet deyin, root’un uzaktan bağlanmasına izin vermeyin
  • Remove test database: Evet deyin
  • Reload privilege tables: Evet deyin

Root Kullanıcısını Yapılandırma

# MySQL'e bağlan
sudo mysql -u root -p

# Root'un authentication methodunu kontrol et
SELECT user, host, authentication_string, plugin FROM mysql.user WHERE user='root';

# Unix socket yerine şifre authentication kullanmak istiyorsanız
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'SuperGucluSifre123!@#';

# Değişiklikleri uygula
FLUSH PRIVILEGES;

Uygulama Kullanıcısı Oluşturma

Gerçek dünyada hiçbir uygulama root ile veritabanına bağlanmamalı. Her uygulama için ayrı, kısıtlı yetkili kullanıcı oluşturun:

# MySQL'e giriş yap
sudo mysql -u root -p

# Uygulama veritabanı oluştur
CREATE DATABASE myapp_production CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

# Sadece bu veritabanına erişebilen kullanıcı oluştur
CREATE USER 'myapp_user'@'localhost' IDENTIFIED BY 'GucluUygulamaSifresi456!';

# Minimum gerekli yetkileri ver
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON myapp_production.* TO 'myapp_user'@'localhost';

# Eğer uygulama farklı bir sunucudaysa (örn. 10.0.1.50)
CREATE USER 'myapp_user'@'10.0.1.50' IDENTIFIED BY 'GucluUygulamaSifresi456!';
GRANT SELECT, INSERT, UPDATE, DELETE ON myapp_production.* TO 'myapp_user'@'10.0.1.50';

FLUSH PRIVILEGES;

# Kullanıcı yetkilerini doğrula
SHOW GRANTS FOR 'myapp_user'@'localhost';

Konfigürasyon Optimizasyonu

Varsayılan konfigürasyon küçük bir test ortamı için bile yetersiz kalabilir. /etc/mysql/mariadb.conf.d/50-server.cnf veya /etc/my.cnf dosyasını düzenleyin.

Temel Performans Parametreleri

sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf

Şu parametreleri ekleyin veya düzenleyin:

[mysqld]
# Genel ayarlar
bind-address = 127.0.0.1
port = 3306
max_connections = 200
wait_timeout = 600
interactive_timeout = 600

# InnoDB ayarları - RAM'in %70-80'ini verin
innodb_buffer_pool_size = 4G
innodb_buffer_pool_instances = 4
innodb_log_file_size = 512M
innodb_flush_log_at_trx_commit = 1
innodb_flush_method = O_DIRECT

# Query cache (MySQL 8'de kaldırıldı, MariaDB'de hala var)
query_cache_type = 1
query_cache_size = 256M
query_cache_limit = 2M

# Slow query log - kesinlikle aktif edin
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
log_queries_not_using_indexes = 1

# Binary log - replikasyon ve point-in-time recovery için
log_bin = /var/log/mysql/mysql-bin
binlog_format = ROW
expire_logs_days = 7
max_binlog_size = 100M

# Charset
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

Değişikliklerden sonra servisi yeniden başlatın:

sudo systemctl restart mariadb

# Değişkenlerin aktif olduğunu doğrula
sudo mysql -u root -p -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
sudo mysql -u root -p -e "SHOW VARIABLES LIKE 'slow_query_log%';"

Yedekleme Stratejisi

Yedekleme olmayan veritabanı yönetimi, güvenlik kemeri takmadan araba kullanmak gibi. İki temel yöntem var.

mysqldump ile Mantıksal Yedek

#!/bin/bash
# /usr/local/bin/mysql_backup.sh

BACKUP_DIR="/backup/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
DB_USER="backup_user"
DB_PASS="YedekSifresi789!"
RETENTION_DAYS=7

mkdir -p $BACKUP_DIR

# Tüm veritabanlarını yedekle
mysqldump 
    --user=$DB_USER 
    --password=$DB_PASS 
    --all-databases 
    --single-transaction 
    --flush-logs 
    --master-data=2 
    --routines 
    --triggers 
    --events 
    | gzip > $BACKUP_DIR/full_backup_$DATE.sql.gz

# Eski yedekleri temizle
find $BACKUP_DIR -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete

# Yedek boyutunu logla
echo "$(date): Backup completed - $(du -sh $BACKUP_DIR/full_backup_$DATE.sql.gz | cut -f1)" >> /var/log/mysql_backup.log
# Script'i çalıştırılabilir yap
chmod +x /usr/local/bin/mysql_backup.sh

# Yedek için ayrı kullanıcı oluştur
sudo mysql -u root -p -e "CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'YedekSifresi789!';"
sudo mysql -u root -p -e "GRANT SELECT, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER, RELOAD, PROCESS ON *.* TO 'backup_user'@'localhost';"
sudo mysql -u root -p -e "FLUSH PRIVILEGES;"

# Cron'a ekle - her gece 02:00'da
echo "0 2 * * * root /usr/local/bin/mysql_backup.sh" | sudo tee /etc/cron.d/mysql-backup

Yedekten Geri Yükleme

# Sıkıştırılmış yedeği geri yükle
gunzip < /backup/mysql/full_backup_20241215_020001.sql.gz | sudo mysql -u root -p

# Sadece belirli bir veritabanını geri yükle
gunzip < full_backup_20241215_020001.sql.gz | sudo mysql -u root -p myapp_production

Performans İzleme ve Sorun Giderme

Aktif Bağlantıları ve Sorguları İzleme

# Çalışan process'leri göster
sudo mysql -u root -p -e "SHOW FULL PROCESSLISTG"

# Uzun süren sorguları bul (5 saniyeden fazla)
sudo mysql -u root -p -e "SELECT id, user, host, db, time, state, LEFT(info, 100) AS query FROM information_schema.processlist WHERE time > 5 ORDER BY time DESC;"

# InnoDB durumunu kontrol et
sudo mysql -u root -p -e "SHOW ENGINE INNODB STATUSG"

# Tablo kilitleme sorunlarını kontrol et
sudo mysql -u root -p -e "SHOW OPEN TABLES WHERE In_use > 0;"

Slow Query Log Analizi

# mysqldumpslow ile en yavaş sorguları analiz et
mysqldumpslow -s t -t 10 /var/log/mysql/slow.log

# pt-query-digest ile daha detaylı analiz (Percona Toolkit)
sudo apt install -y percona-toolkit
pt-query-digest /var/log/mysql/slow.log | head -100

Tablo ve Index Bakımı

# Tablo istatistiklerini güncelle
sudo mysql -u root -p -e "ANALYZE TABLE myapp_production.users;"

# Tabloları optimize et (defragment)
sudo mysql -u root -p -e "OPTIMIZE TABLE myapp_production.orders;"

# Index kullanımını kontrol et
sudo mysql -u root -p -e "
SELECT 
    table_schema,
    table_name,
    index_name,
    stat_value as pages
FROM mysql.innodb_index_stats 
WHERE stat_name = 'size'
ORDER BY stat_value DESC 
LIMIT 20;"

Master-Slave Replikasyon Kurulumu

Küçük ölçekli bir production ortamı için bile replikasyon şart. Hem yüksek erişilebilirlik hem de okuma yükünü dağıtmak için kullanılır.

Master Sunucu Konfigürasyonu

# /etc/mysql/mariadb.conf.d/50-server.cnf üzerinde master ayarları
[mysqld]
server-id = 1
log_bin = /var/log/mysql/mysql-bin
binlog_format = ROW
binlog_do_db = myapp_production

# Servisi yeniden başlat
sudo systemctl restart mariadb

# Replikasyon kullanıcısı oluştur
sudo mysql -u root -p -e "
CREATE USER 'repl_user'@'10.0.1.51' IDENTIFIED BY 'ReplSifresi321!';
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'10.0.1.51';
FLUSH PRIVILEGES;"

# Master durumunu not et (slave konfigürasyonu için lazım)
sudo mysql -u root -p -e "SHOW MASTER STATUSG"

Slave Sunucu Konfigürasyonu

# Slave sunucuda /etc/mysql/mariadb.conf.d/50-server.cnf
[mysqld]
server-id = 2
relay-log = /var/log/mysql/mysql-relay-bin
read_only = 1

sudo systemctl restart mariadb

# Slave'i master'a bağla
sudo mysql -u root -p -e "
CHANGE MASTER TO
    MASTER_HOST='10.0.1.50',
    MASTER_USER='repl_user',
    MASTER_PASSWORD='ReplSifresi321!',
    MASTER_LOG_FILE='mysql-bin.000001',
    MASTER_LOG_POS=154;
START SLAVE;"

# Replikasyon durumunu kontrol et
sudo mysql -u root -p -e "SHOW SLAVE STATUSG"
# Seconds_Behind_Master: 0 olmalı
# Slave_IO_Running: Yes olmalı
# Slave_SQL_Running: Yes olmalı

Firewall ve Ağ Güvenliği

# UFW ile MySQL portunu sadece uygulama sunucusuna aç
sudo ufw allow from 10.0.1.50 to any port 3306
sudo ufw deny 3306

# firewalld kullanıyorsanız
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.1.50" port protocol="tcp" port="3306" accept'
sudo firewall-cmd --reload

# MySQL'in gerçekten sadece istenilen arayüzde dinlediğini doğrula
ss -tlnp | grep 3306
# Ya da
netstat -tlnp | grep mysqld

Monitoring: Prometheus + mysqld_exporter

Gerçek bir production ortamında metrikleri görselleştirmek şart:

# mysqld_exporter indir
wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.15.1/mysqld_exporter-0.15.1.linux-amd64.tar.gz
tar xvf mysqld_exporter-0.15.1.linux-amd64.tar.gz
sudo mv mysqld_exporter-0.15.1.linux-amd64/mysqld_exporter /usr/local/bin/

# Exporter için MySQL kullanıcısı oluştur
sudo mysql -u root -p -e "
CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'ExporterSifresi555!' WITH MAX_USER_CONNECTIONS 3;
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';
FLUSH PRIVILEGES;"

# Credentials dosyası oluştur
sudo bash -c 'cat > /etc/.mysqld_exporter.cnf << EOF
[client]
user=exporter
password=ExporterSifresi555!
EOF'
sudo chmod 600 /etc/.mysqld_exporter.cnf

# Systemd service dosyası oluştur
sudo bash -c 'cat > /etc/systemd/system/mysqld_exporter.service << EOF
[Unit]
Description=MySQL Exporter
After=network.target

[Service]
User=prometheus
ExecStart=/usr/local/bin/mysqld_exporter --config.my-cnf=/etc/.mysqld_exporter.cnf
Restart=always

[Install]
WantedBy=multi-user.target
EOF'

sudo systemctl daemon-reload
sudo systemctl start mysqld_exporter
sudo systemctl enable mysqld_exporter

Sık Karşılaşılan Sorunlar ve Çözümleri

“Too many connections” hatası

# Mevcut max_connections değerini kontrol et
sudo mysql -u root -p -e "SHOW VARIABLES LIKE 'max_connections';"

# Anlık olarak değiştir (kalıcı değil)
sudo mysql -u root -p -e "SET GLOBAL max_connections = 300;"

# Kalıcı için my.cnf'e ekle: max_connections = 300

Disk doldu, InnoDB kurtarma

# InnoDB force recovery modunu aktif et
# /etc/mysql/mariadb.conf.d/50-server.cnf'e ekle:
# innodb_force_recovery = 1

# Servisi başlat ve veritabanını dump'la
sudo systemctl start mariadb
mysqldump -u root -p --all-databases > emergency_backup.sql

# Recovery modunu kaldır, servisi yeniden başlat
sudo systemctl restart mariadb

Sonuç

MySQL ve MariaDB yönetimi, kurulumla biten bir iş değil. Güvenlik sıkılaştırma, düzenli yedekleme, performans izleme ve replikasyon kurulumu bir paket halinde düşünülmeli. Bu yazıda anlattıklarım minimum başlangıç noktanız olmalı.

En önemli hatırlatmalar:

  • Root ile uygulama bağlantısı kurmayın, her zaman kısıtlı kullanıcı oluşturun
  • Yedekleri test edin, sadece almak yetmez, geri yükleyebildiğinizi de kanıtlayın
  • Slow query log’u açın ve düzenli inceleyin, çoğu performans sorunu buradan çözülür
  • innodb_buffer_pool_size değerini ayarlayın, varsayılan değer production için yetersiz
  • Replikasyonu olabildiğince erken kurun, sonradan eklemek daha zahmetli

Bir sonraki adım olarak Galera Cluster veya MySQL InnoDB Cluster ile aktif-aktif kuruluma bakmanızı öneririm. Sorularınız için yorum bölümünü kullanın.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir