VPS.TC
| $
Sunucu Durumu
Turkey İstanbul, Türkiye
Aktif
USA New York, ABD
Aktif
Sepet Toplamı:
Sepeti Görüntüle
VPS’te MySQL Kurulumu ve Güvenli Yapılandırma
Linux

VPS’te MySQL Kurulumu ve Güvenli Yapılandırma

Defne avatarı Defne Ağustos 30, 2026 13 dk okuma 0 Yorumlar
Paylaş:

VPS’te MySQL kurmadan önce bilmeniz gerekenler

Bir VPS üzerinde MySQL kurmak birkaç dakikalık iştir. Güvenli, bakımı yapılabilir ve dışarıya gereksiz yere açık olmayan bir kurulum ise biraz daha fazla dikkat ister. Benim için VPS MySQL kurulumu, apt install komutunu çalıştırıp servisin yeşile dönmesini görmekle bitmiyor; veritabanına kimlerin erişeceği, hangi adreste dinleyeceği, nasıl yedekleneceği ve disk dolduğunda ne olacağı da aynı planın parçası.

Önce işletim sistemiyle veritabanı paketini netleştirin. Ubuntu 22.04 ve 24.04 üzerinde resmi depolarda MySQL 8.0 paketleriyle karşılaşmanız yaygın. Debian 12 ise varsayılan olarak çoğu kurulumda MariaDB 10.11 sağlar. MariaDB, MySQL ile aynı aileden gelse de birebir aynı ürün değildir; yapılandırma seçenekleri, sürüm davranışları ve bazı SQL özellikleri farklılaşabilir.

🚀 VPS Sunucu ile Hızınızı Artırın!

Yüksek performanslı SSD depolama ve %99.9 uptime garantisi ile projelerinizi hızlandırın.

Hemen Başla

Uygulamanız özellikle MySQL 8.0 veya 8.4 istiyorsa işletim sistemi deposunu, MySQL’in resmi deposunu ya da sağlayıcınızın hazır imajını seçmeden önce sürüm uyumluluğunu kontrol edin. Rastgele bir üçüncü taraf betiğini root olarak çalıştırmak kurulumu hızlandırıyor gibi görünebilir. Geride ne bıraktığını anlamak daha zordur.

Kurulumdan önce kısa kontrol listesi

  • VPS’e SSH ile ayrı bir yönetici hesabından bağlanabiliyor musunuz?
  • İşletim sistemi güncel mi ve saat doğru mu?
  • Veritabanı, binary log ve yedekler için yeterli disk alanı var mı?
  • Uygulama ile MySQL aynı VPS’te mi çalışacak, yoksa uzak bir sunucudan mı bağlanacak?
  • Sağlayıcının snapshot özelliği var mı? Snapshot’ın tek başına yedek olmadığını hesaba kattınız mı?

Yeni bir makineyi önce labımdaki Proxmox sanal makinesinde kurarım. Dell OptiPlex 7050 üzerindeki bu VM, yanlış bir bind-address veya bozuk bir systemd override yüzünden çökerse müşteri sitesi etkilenmez. Üretim sunucusunda deneme yapmanın romantik bir tarafı yok.

Ubuntu ve Debian üzerinde MySQL kurulumu

Aşağıdaki adımlar Ubuntu 22.04 ve 24.04 üzerinde MySQL 8.0 paket düzeni için hazırlanmıştır. Debian kullanıyorsanız önce hangi paketin kurulacağını kontrol edin:

☁️ Cloud Sunucu ile Esneklik Kazanın!

Ölçeklenebilir kaynaklar ve anlık yedekleme ile bulutun gücünü deneyimleyin.

Keşfet
cat /etc/os-release
apt-cache policy mysql-server mariadb-server

Çıktıdaki Candidate satırı depoda hangi sürümün seçileceğini gösterir. Ubuntu tarafında MySQL paketini kurmak için:

sudo apt update
sudo apt full-upgrade -y
sudo apt install -y mysql-server
sudo systemctl enable --now mysql
sudo systemctl status mysql --no-pager

enable --now iki işi birden yapar: servisi hemen başlatır ve VPS yeniden başladığında otomatik açılmasını sağlar. status çıktısında active (running) görmeniz iyi bir işarettir; güvenli yapılandırmanın tamamlandığı anlamına gelmez.

Sürümü ve gerçekten hangi sunucunun çalıştığını kontrol edin:

mysql --version
sudo mysql -e "SELECT VERSION(), USER(), @@hostname;"

@@hostname değerini özellikle not alırım. Birkaç VPS ile çalışırken yanlış sunucuda işlem yapma ihtimali küçümsenecek bir şey değil. Bir gece staging sandığım sunucuda eski bir log dizinini silmeye hazırlanırken shell otomatik tamamlamada production hostname’ini gördüm. Elim Enter‘a gitmişti. O günden beri sunucu adını komuttan hemen önce tekrar kontrol ederim; production prompt’lerinin kırmızı olması da bu yüzden.

Servis çalışmıyorsa loglara bakın

Servisi tekrar tekrar başlatmadan önce neden açılmadığını okuyun. Log okumadan reboot etmek, motor ışığı yandığında aküyü sökmeye benziyor.

sudo journalctl -u mysql -b --no-pager -n 100
sudo ss -lntp | grep 3306
sudo systemctl is-enabled mysql

journalctl son açılıştan itibaren MySQL günlüklerini getirir. ss ise 3306/TCP portunda hangi adresin dinlendiğini gösterir. Henüz uzak erişimi açmadıysanız yalnızca 127.0.0.1:3306 veya IPv6 için ::1:3306 görmeniz beklenir.

İlk güvenlik adımları

Kurulumdan hemen sonra mysql_secure_installation komutunu çalıştırabilirsiniz:

sudo mysql_secure_installation

Komut, sürüme göre root doğrulama eklentisi, anonim kullanıcılar, test veritabanı ve uzaktan root erişimi hakkında sorular sorar. Anonim kullanıcıları kaldırmak, test veritabanını silmek ve root’un uzaktan bağlanmasını reddetmek çoğu kurulumda doğru tercihtir.

Ubuntu paketlerinde root hesabı çoğu zaman auth_socket veya unix_socket üzerinden yalnızca işletim sistemi root yetkisiyle çalışır. Bu durumda parolayla mysql -u root -p denemek yerine:

sudo mysql

ile bağlanırsınız. Bu davranış bir problem değil, saldırı yüzeyini azaltan bilinçli bir tercihtir. Uygulamaya root parolası vermeyin. Uygulama için ayrı bir hesap açın.

Uygulama veritabanı ve kullanıcı oluşturma

Önce güçlü ve tahmin edilmesi zor bir parola üretin. Parolayı komut satırına doğrudan yazmak shell geçmişinde kalabileceği için parola istemek veya güvenli bir parola yöneticisi kullanmak daha iyidir. MySQL istemcisinde aşağıdaki SQL veritabanı ve kullanıcı oluşturur:

sudo mysql
CREATE DATABASE shop CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
CREATE USER 'shop_app'@'localhost' IDENTIFIED BY 'uzun-ve-rastgele-bir-parola';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, DROP
ON shop.* TO 'shop_app'@'localhost';
FLUSH PRIVILEGES;
EXIT;

utf8mb4 güncel uygulamalar için iyi bir başlangıçtır; dört baytlık Unicode karakterlerini destekler. utf8mb4_0900_ai_ci MySQL 8.0 içindir. MariaDB kullanıyorsanız bu collation adının desteklenip desteklenmediğini ayrıca kontrol edin.

DROP yetkisini uygulamanın normal çalışma hesabına vermek istemezseniz migration işlemleri için ayrı bir kullanıcı oluşturun. Her şeyi tek hesaba vermek ilk gün kolay görünür, üçüncü ayda kimin ne yapabildiğini izlemeyi zorlaştırır.

Yetkileri kontrol etmek için:

sudo mysql -e "SHOW GRANTS FOR 'shop_app'@'localhost';"

Uygulama bağlantısını da test edin. Parolayı history’ye yazmamak için istemcinin parola sormasını sağlayın:

mysql -u shop_app -p -h 127.0.0.1 -D shop -e "SELECT DATABASE(), CURRENT_USER();"

Burada localhost ile 127.0.0.1 arasında küçük ama önemli bir fark vardır. MySQL istemcisi localhost için Unix socket kullanabilir; 127.0.0.1 TCP bağlantısını zorlar. Uygulamanızın kullandığı yöntemle test edin.

MySQL’i internete açmalı mısınız?

Çoğu VPS senaryosunda cevap hayırdır. Web uygulaması ve MySQL aynı makinedeyse MySQL’i yalnızca loopback adresinde dinletin. Ubuntu paketlerinde ayar dosyasını şu konumda bulabilirsiniz:

sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf

vim yerine sunucuda bulunan başka bir editörü kullanabilirsiniz; ben sade .vimrc düzenimle devam ediyorum. İlgili bölümde şu satırı kontrol edin:

[mysqld]
bind-address = 127.0.0.1

Bazı sürümlerde satırın başında # bulunabilir. Değişiklikten sonra önce yapılandırmayı test edip servisi yeniden başlatın:

sudo mysqld --validate-config
sudo systemctl restart mysql
sudo ss -lntp | grep 3306

mysqld --validate-config sessiz dönüyorsa yapılandırma sözdizimi açısından sorun görmemiştir. Yine de restart sonrasında systemctl status mysql ve journal çıktısını kontrol ederim. Bir satırdaki yazım hatası veritabanını açılmayacak hale getirebilir.

Başka bir VPS’teki uygulamanın bağlanması gerekiyorsa 3306 portunu herkese açmayın. Önce kaynak IP’yi belirleyin, sonra firewall’da yalnızca o IP’ye izin verin:

sudo ufw allow from 203.0.113.25 to any port 3306 proto tcp
sudo ufw status numbered

Uygulama IP’si değişebilen bir bulut ortamındaysa sabit özel ağ, VPN veya SSH tüneli daha sağlıklı olabilir. UFW kullanmıyorsanız nftables ya da sağlayıcının güvenlik grubunu aynı kural mantığıyla yapılandırın. 0.0.0.0/0 kaynaklı 3306 kuralını “geçici” diye bırakmak, geçiciliğini en hızlı kaybeden kurallardan biridir.

Uzak kullanıcı hesabı gerekiyorsa

Uzak bağlantı şartsa kullanıcıyı 'shop_app'@'%' olarak yaratmak yerine izin verilen kaynak adresini yazın:

CREATE USER 'shop_app'@'203.0.113.25' IDENTIFIED BY 'uzun-ve-rastgele-bir-parola';
GRANT SELECT, INSERT, UPDATE, DELETE ON shop.*
TO 'shop_app'@'203.0.113.25';

MySQL kullanıcı hesabında host bölümü de kimliğin parçasıdır. 'shop_app'@'localhost' ile 'shop_app'@'203.0.113.25' iki ayrı hesaptır. Bu ayrıntıyı atlayıp “kullanıcı var ama erişemiyor” şikâyetiyle epey vakit kaybettim; SELECT user, host FROM mysql.user; çıktısı gerçeği genellikle hızlıca gösterir.

Root parolası, kimlik doğrulama ve TLS

MySQL 8.0 yeni kullanıcılar için varsayılan olarak caching_sha2_password eklentisini kullanır. Eski PHP sürümleri veya eski istemciler bunu desteklemeyebilir. Sırf eski uygulama bağlansın diye bütün sunucuyu eski bir kimlik doğrulama yöntemine çevirmek yerine önce uygulama sürücüsünü güncelleyin.

Mevcut kullanıcıların eklentisini şöyle görebilirsiniz:

sudo mysql -e "SELECT user, host, plugin FROM mysql.user;"

Uygulama ile MySQL ayrı sunuculardaysa bağlantıyı şifrelemek gerekir. MySQL sunucusunun TLS durumunu kontrol edin:

sudo mysql -e "SHOW VARIABLES LIKE 'require_secure_transport';"
sudo mysql -e "SHOW VARIABLES LIKE 'have_ssl';"

Sertifika üretimi, dosya sahiplikleri ve istemci yapılandırması kullandığınız dağıtım ile MySQL sürümüne göre değişir. Üretimde self-signed sertifikayı istemciye doğrulatmadan kullanmak, trafiği şifreli gösterip sunucunun gerçekten doğrulanmasını ihmal edebilir. Uzak erişim gerekiyorsa CA sertifikasını uygulama tarafında doğrulayın ve kullanıcıyı REQUIRE SSL ile sınırlayın:

ALTER USER 'shop_app'@'203.0.113.25' REQUIRE SSL;

Bu kullanıcı daha önce oluşturulmadıysa komut doğal olarak hata verir; ALTER USER mevcut hesabı değiştirir, yeni hesap oluşturmaz. Üretimde kopyalamadan önce kullanıcı ve host değerlerini kendi kurulumunuzla karşılaştırın.

Kaynak kullanımı ve temel MySQL yapılandırması

VPS MySQL kurulumunda sık gördüğüm hata, fiziksel RAM’in tamamını MySQL’e bırakmak. Aynı sunucuda nginx, PHP-FPM ve Redis varsa innodb_buffer_pool_size değerini körlemesine yükseltmeyin. InnoDB için ayrılan bellek, uygulamanın ve işletim sisteminin payı çıkarıldıktan sonra belirlenmeli.

Örneğin 4 GB RAM’li, yalnızca küçük bir web uygulaması çalıştıran VPS’te başlangıç değerini 1 GB civarında tutup gözlemlemek, 2 GB’ı doğrudan buffer pool’a vermekten daha güvenlidir. Kesin değer iş yüküne, bağlantı sayısına ve sorgulara bağlıdır. Ben önce metrik toplar, sonra değiştiririm.

Ayar dosyasının dağıtımda hangi dosyalardan oluştuğunu görün:

sudo mysqld --verbose --help 2>/dev/null | grep -A 1 "Default options"
sudo mysql -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
sudo mysql -e "SHOW VARIABLES LIKE 'max_connections';"

Değişiklik yapmadan önce dosyanın yedeğini alın:

sudo cp -a /etc/mysql/mysql.conf.d/mysqld.cnf 
  /etc/mysql/mysql.conf.d/mysqld.cnf.$(date +%F)

Ardından örnek bir ayarı iş yükünüze göre ekleyebilirsiniz:

[mysqld]
innodb_buffer_pool_size = 1G
max_connections = 100
slow_query_log = ON
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 1

max_connections için yüksek bir sayı yazmak kapasite yaratmaz; her bağlantının bellek maliyeti vardır. PHP-FPM process sayısı, uygulamanın connection pool ayarı ve gerçek eşzamanlı trafik bilinmeden bu değeri artırmayın. Yavaş sorgu günlüğü de kalıcı olarak açık bırakılırsa disk tüketebilir; logrotate ve izleme kuralını birlikte planlayın.

Değişiklikten sonra:

sudo mysqld --validate-config
sudo systemctl restart mysql
sudo systemctl --no-pager --full status mysql
sudo journalctl -u mysql -b -n 50 --no-pager

Hata varsa eski yapılandırma yedeğine dönmekten çekinmeyin. Bir ayarın daha performanslı olması, servis açılmıyorsa teorik bir başarıdır.

Yedekleme olmadan kurulum tamamlanmış sayılmaz

VPS snapshot’ı kullanışlıdır ama tek başına MySQL yedeği değildir. Snapshot alınırken veritabanı yazma işlemleri devam edebilir; ayrıca snapshot aynı sağlayıcıya ve çoğu zaman aynı arıza alanına bağlıdır. Uygulama verisi için düzenli mantıksal veya fiziksel yedek, farklı bir depolama alanında tutulmalıdır.

Küçük veritabanlarında mysqldump ile başlayabilirsiniz:

sudo install -d -m 700 /var/backups/mysql
sudo mysqldump --single-transaction --routines --triggers 
  --databases shop > /var/backups/mysql/shop-$(date +%F).sql

--single-transaction InnoDB tablolarında dump alınırken tablo kilitlerini azaltır. Çok büyük veritabanlarında dump süresi ve disk kullanımı sorun olabilir; o noktada Percona XtraBackup veya MySQL Enterprise Backup gibi fiziksel yedekleme seçeneklerini ayrıca değerlendirmek gerekir.

Dump dosyasını VPS’te bırakıp “yedek aldım” demeyin. Ben rsync ile ayrı bir yedek makinesine gönderip borgbackup ile sürümlü ve şifreli saklamayı tercih ediyorum. Ayda bir geri dönüş provası yaparım; test edilmemiş yedek yalnızca iyi niyetli bir dosyadır.

mysql -u root -p shop < /path/to/shop-2026-08-30.sql

Geri yükleme komutunu canlı veritabanında çalıştırmadan önce ayrı bir test veritabanında veya test VPS’inde deneyin. Karakter seti, kullanıcı yetkileri, stored procedure’ler ve dosyanın gerçekten güncel olup olmadığı kontrol edilmelidir.

Kurulumdan sonra kontrol edilmesi gerekenler

MySQL kurulumu sonrasında şu kontrolleri otomatik izlemeye almak mantıklıdır:

  • MySQL servisinin çalışıp çalışmadığı
  • Disk kullanımının ve inode durumunun sınırı
  • Bağlantı sayısı ve reddedilen bağlantılar
  • InnoDB buffer pool kullanımı
  • Yavaş sorgu sayısı
  • Son başarılı yedekleme zamanı

Evdeki Proxmox sistemimde Prometheus için node_exporter çalıştırıyorum; disk ve RAM alarmları, MySQL’i doğrudan izlemekten önce bile birkaç ciddi sorunu yakaladı. MySQL metrikleri için uygun bir exporter ekleyebilirsiniz, fakat exporter hesabına yalnızca gereken global okuma yetkilerini verin. Monitoring hesabı da root olmamalı.

Disk kullanımını hızlıca görmek için ncdu hâlâ en pratik araçlardan biri:

sudo ncdu -x /var/lib/mysql
sudo du -sh /var/log/mysql /var/lib/mysql

Özellikle binary log kullanıyorsanız dosyaların retention ayarını kontrol edin. Binary log’lar point-in-time recovery için değerlidir, fakat sınırsız tutulursa disk alarmını sizden önce üretim ortamı verir. Saklama süresini yedekleme stratejinizle birlikte belirleyin.

Güvenlik kontrol komutları

sudo ss -lntp | grep 3306
sudo mysql -e "SELECT user, host FROM mysql.user;"
sudo mysql -e "SHOW VARIABLES LIKE 'local_infile';"
sudo ufw status verbose

local_infile uygulamanız gerektirmiyorsa kapatılabilir; dosya yükleme davranışlarını gereksiz yere genişletmenin anlamı yoktur. SSH portunu değiştirmek tek başına güvenlik değildir. Asıl savunma katmanları güçlü kimlik doğrulama, güncel paketler, firewall, en az yetki ve izlenen log’lardır. MySQL için de aynı yaklaşım geçerli.

Sunucuyu işletim sistemi seviyesinde de sıkılaştırmak isterseniz Linux Sunucu Güvenliği için Zorunlu 10 Temel Adım başlıklı içeriğe bakabilirsiniz. Yeni bir VPS’in temel hazırlığı için Yeni VPS Sunucuyu 30 Dakikada Canliya Alma Rehberi de kurulum sırasını oturtmanıza yardımcı olur.

Uygulamanın MySQL’e bağlanması

Uygulama yapılandırmasında veritabanı host’u, portu, adı, kullanıcı adı ve parolası bulunur. Parolayı Git deposuna, hata mesajına veya herkesin okuyabildiği bir .env dosyasına koymayın. Dosya izinlerini de kontrol edin:

sudo chown root:www-data /var/www/shop/.env
sudo chmod 640 /var/www/shop/.env
sudo -u www-data test -r /var/www/shop/.env && echo "ok"

Web sunucusu ile veritabanı aynı VPS’teyse bağlantıyı loopback üzerinde tutun. Ayrı sunucularda özel ağ, firewall kısıtı ve TLS’i beraber kullanın. Tek bir katmana güvenmek yerine birkaç küçük ve anlaşılır sınır kurmak daha az sürpriz üretir.

Uygulamanız WordPress, Joomla veya Drupal ise veritabanı ayarlarının yanında sorgu önbelleği, PHP-FPM ve sayfa önbelleğini de ele alın. TTFB’yi milisaniye milisaniye tartışıp temel cache katmanını kurmamak, ölçüm yapıyor gibi görünmenin başka bir biçimi.

VPS MySQL kurulumu için son kontrol

Kurulum bittiğinde terminalde yeşil bir servis görmek hoş, fakat asıl test birkaç gün sonra yapılır. Uygulama gerçek trafik altında hata veriyor mu, disk büyümesi izleniyor mu, yedekten geri dönebiliyor musunuz, uzak port gerçekten kapalı mı? Bu soruların cevabı yoksa yapılandırma tamamlanmış sayılmaz.

Benim minimum düzenim şu: uygulama için ayrı bir MySQL kullanıcısı, loopback’te dinleyen 3306, sağlayıcı firewall’ı, düzenli ve farklı yerde tutulan yedek, yedek geri dönüş testi ve servis loglarını izleyen bir alarm. Daha büyük sistemlerde replikasyon, point-in-time recovery, ayrı veritabanı sunucusu ve bağlantı havuzu eklenir; temel disiplin değişmez.

Kurulumdan sonra terminali kapatmadan önce bir kez daha SELECT @@hostname; çıktısına bakarım. Geçmişte Tab tuşu beni yanlış bir rm komutundan kurtardı; o küçük duraksama, uzun bir kesintiden ucuzdu. Sizin sunucunuzda bugün hangi komut, çalışmadan önce iki saniyelik bir kontrol bekliyor?

Sık Sorulan Sorular

VPS üzerinde MySQL root parolası nasıl belirlenir?

Ubuntu paketlerinde root hesabı çoğu zaman Unix socket kimlik doğrulamasıyla gelir ve sudo mysql komutuyla açılır. Uygulamalara root hesabını vermek yerine ayrı kullanıcı oluşturun; gerçekten parola tabanlı root erişimi gerekiyorsa erişim yöntemini ve riskini bilerek değiştirin.

MySQL 3306 portu internete açılmalı mı?

Uygulama ve MySQL aynı VPS’teyse açılmamalıdır; bind-address = 127.0.0.1 kullanın. Uzak bağlantı zorunluysa yalnızca belirli kaynak IP’lere firewall izni verin, kullanıcıyı host adresiyle sınırlandırın ve TLS kullanın.

MySQL ile MariaDB arasında hangisi tercih edilmeli?

Seçim, uygulamanın ve kullandığınız eklentilerin desteklediği sürüme göre yapılmalıdır. Debian’ın varsayılan MariaDB paketini MySQL sanarak kurmak sonradan uyumluluk sorunu çıkarabilir; kuruluma başlamadan önce apt-cache policy ve uygulama belgelerini kontrol edin.

MySQL VPS yedeği nasıl test edilir?

Dump veya fiziksel yedeği ayrı bir test VPS’ine geri yükleyip uygulamanın gerçekten bağlandığını doğrulayın. Sadece dosyanın oluşması yeterli değildir; geri dönüş süresini, eksik tabloları, kullanıcı yetkilerini ve karakter setini de kontrol edin.

Defne avatarı
Yazar

Defne

vps.tc blog yazarı. Sistem yönetimi, Linux ve hosting dünyası üzerine yazıyor.