Azure Database for MySQL Kurulumu ve Yapılandırması
Bulut altyapısına geçen ekiplerin en sık sorduğu sorulardan biri şu oluyor: “Veritabanımı da buluta taşımalı mıyım?” MySQL kullanıyorsanız ve Azure’dasınız, cevap neredeyse her zaman evet. Azure Database for MySQL, hem Flexible Server hem de tam yönetilen yapısıyla operasyonel yükü ciddi ölçüde azaltıyor. Yama yönetimi, yedekleme, yüksek erişilebilirlik gibi konular artık sizin sorununuz değil. Bu yazıda sıfırdan bir Azure Database for MySQL ortamı kuracağız, bağlantıyı test edeceğiz ve production’a hazır hale getireceğiz.
Ön Gereksinimler
Başlamadan önce şunların hazır olduğundan emin olun:
- Aktif bir Azure aboneliği
- Azure CLI (en az 2.40 sürümü) veya Azure Portal erişimi
- MySQL client (mysql-client paketi)
- Temel networking bilgisi (VNet, subnet kavramları)
Azure CLI kurulu değilse hızlıca kurabilirsiniz:
# Ubuntu/Debian
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
# Kurulumu doğrula
az --version
# Azure'a giriş yap
az login
Giriş yaptıktan sonra hangi subscription’da çalıştığınızı kontrol edin. Birden fazla subscription varsa doğru olanı seçin:
# Mevcut subscription'ları listele
az account list --output table
# Doğru subscription'ı seç
az account set --subscription "Subscription-ID-veya-Adı"
# Seçimi doğrula
az account show --output table
Resource Group ve Temel Altyapı Oluşturma
Azure’da her şey bir resource group içinde yaşar. Veritabanı projeniz için ayrı bir resource group açmak, ileride temizlik yaparken veya erişim kontrolü tanımlarken hayat kurtarır. Ben genellikle proje adı ve ortam bazlı isimlendirme kullanıyorum.
# Değişkenleri tanımla
RESOURCE_GROUP="rg-mysql-production"
LOCATION="westeurope"
VNET_NAME="vnet-db-production"
SUBNET_NAME="subnet-mysql"
SERVER_NAME="mysql-prod-$(date +%s)" # Benzersiz isim için timestamp
ADMIN_USER="mysqladmin"
ADMIN_PASSWORD="Guclu_Parola_2024!"
DB_NAME="uygulama_db"
# Resource group oluştur
az group create
--name $RESOURCE_GROUP
--location $LOCATION
# Resource group oluşturulduğunu doğrula
az group show --name $RESOURCE_GROUP --output table
Şimdi networking tarafını hazırlayalım. Flexible Server için private access önerilen yöntemdir. Bu sayede veritabanınız doğrudan internete açık olmaz, sadece aynı VNet içindeki kaynaklar erişebilir.
# VNet oluştur
az network vnet create
--resource-group $RESOURCE_GROUP
--name $VNET_NAME
--location $LOCATION
--address-prefix 10.0.0.0/16
# MySQL için dedicated subnet oluştur
az network vnet subnet create
--resource-group $RESOURCE_GROUP
--vnet-name $VNET_NAME
--name $SUBNET_NAME
--address-prefix 10.0.1.0/24
--delegations Microsoft.DBforMySQL/flexibleServers
# Private DNS Zone oluştur (Flexible Server için zorunlu)
az network private-dns zone create
--resource-group $RESOURCE_GROUP
--name "mysql-prod.private.mysql.database.azure.com"
# DNS Zone'u VNet'e bağla
az network private-dns link vnet create
--resource-group $RESOURCE_GROUP
--zone-name "mysql-prod.private.mysql.database.azure.com"
--name "dns-link-mysql"
--virtual-network $VNET_NAME
--registration-enabled false
Flexible Server Kurulumu
Azure Database for MySQL’in iki deployment modu var: Flexible Server ve eski nesil Single Server (bu mod artık deprecated durumda, yeni kurulumlar için kesinlikle Flexible Server kullanın).
Flexible Server kurulumunda dikkat etmeniz gereken birkaç parametre var:
- –sku-name: Compute SKU’su. Buradaki seçim maliyet ve performansı doğrudan etkiler.
- –tier: Burstable, GeneralPurpose veya MemoryOptimized
- –version: MySQL sürümü (8.0 veya 5.7)
- –storage-size: GB cinsinden disk boyutu
- –backup-retention: Backup saklama süresi (1-35 gün)
- –high-availability: ZoneRedundant veya SameZone
# Flexible Server oluştur
az mysql flexible-server create
--resource-group $RESOURCE_GROUP
--name $SERVER_NAME
--location $LOCATION
--admin-user $ADMIN_USER
--admin-password $ADMIN_PASSWORD
--sku-name Standard_D2ds_v4
--tier GeneralPurpose
--version 8.0
--storage-size 64
--storage-auto-grow Enabled
--backup-retention 7
--geo-redundant-backup Disabled
--high-availability Disabled
--vnet $VNET_NAME
--subnet $SUBNET_NAME
--private-dns-zone "mysql-prod.private.mysql.database.azure.com"
--resource-group $RESOURCE_GROUP
# Oluşturma biraz zaman alabilir, durumu kontrol et
az mysql flexible-server show
--resource-group $RESOURCE_GROUP
--name $SERVER_NAME
--query "state"
--output tsv
Sunucu “Ready” durumuna geldiğinde devam edebilirsiniz. Bu işlem genellikle 3-7 dakika sürer.
Veritabanı ve Kullanıcı Yönetimi
Sunucu hazır olduğunda production için gerekli veritabanını ve kullanıcıları oluşturalım. En büyük hatalardan biri admin kullanıcıyı uygulama bağlantısı için kullanmak. Her uygulama için ayrı kullanıcı, ayrı yetki tanımlayın.
# Veritabanı oluştur
az mysql flexible-server db create
--resource-group $RESOURCE_GROUP
--server-name $SERVER_NAME
--database-name $DB_NAME
--charset utf8mb4
--collation utf8mb4_unicode_ci
# Mevcut veritabanlarını listele
az mysql flexible-server db list
--resource-group $RESOURCE_NAME
--server-name $SERVER_NAME
--output table
Şimdi uygulama kullanıcısı oluşturmak için MySQL client ile bağlanmamız gerekiyor. Bağlantı için sunucunun FQDN’ini öğrenelim:
# Sunucu FQDN'ini öğren
SERVER_FQDN=$(az mysql flexible-server show
--resource-group $RESOURCE_GROUP
--name $SERVER_NAME
--query "fullyQualifiedDomainName"
--output tsv)
echo "Sunucu adresi: $SERVER_FQDN"
# MySQL'e bağlan (bu komutu VNet içindeki bir VM'den çalıştırın)
mysql -h $SERVER_FQDN
-u $ADMIN_USER
-p$ADMIN_PASSWORD
--ssl-mode=REQUIRED
MySQL shell’e girdikten sonra kullanıcı ve yetki yönetimini yapın:
-- Uygulama kullanıcısı oluştur
CREATE USER 'app_user'@'%' IDENTIFIED BY 'AppKullanici_2024!';
-- Sadece ilgili veritabanına yetki ver
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER
ON uygulama_db.*
TO 'app_user'@'%';
-- Read-only rapor kullanıcısı
CREATE USER 'report_user'@'%' IDENTIFIED BY 'RaporKullanici_2024!';
GRANT SELECT ON uygulama_db.* TO 'report_user'@'%';
-- Yetkileri uygula
FLUSH PRIVILEGES;
-- Kullanıcıları doğrula
SELECT user, host, authentication_string FROM mysql.user WHERE user IN ('app_user', 'report_user');
Server Parameters Yapılandırması
Azure Database for MySQL’in varsayılan parametreleri çoğu workload için makul ama production ortamı için bazı ayarların gözden geçirilmesi şart. Özellikle slow_query_log ve long_query_time parametrelerini mutlaka açın, ileride performans sorunlarını debug etmek için altın değerinde.
# Slow query log'u etkinleştir
az mysql flexible-server parameter set
--resource-group $RESOURCE_GROUP
--server-name $SERVER_NAME
--name slow_query_log
--value ON
# Slow query eşiğini ayarla (saniye cinsinden, 2 saniye üzeri sorgular loglanır)
az mysql flexible-server parameter set
--resource-group $RESOURCE_GROUP
--server-name $SERVER_NAME
--name long_query_time
--value 2
# max_connections ayarı (SKU'ya göre farklılık gösterir)
az mysql flexible-server parameter set
--resource-group $RESOURCE_GROUP
--server-name $SERVER_NAME
--name max_connections
--value 500
# innodb_buffer_pool_size (RAM'in %70-80'i önerilir, byte cinsinden)
# Standard_D2ds_v4 için 8GB RAM var, ~5.5GB ayarlıyoruz
az mysql flexible-server parameter set
--resource-group $RESOURCE_GROUP
--server-name $SERVER_NAME
--name innodb_buffer_pool_size
--value 5905580032
# Mevcut parametreleri listele
az mysql flexible-server parameter list
--resource-group $RESOURCE_GROUP
--server-name $SERVER_NAME
--output table | head -30
Parametreleri toplu olarak gözden geçirmek için Azure Portal’daki “Server parameters” bölümü daha kullanışlı. Ama otomasyon scriptlerinizde CLI kullanmak her zaman daha iyi.
Yedekleme ve Geri Yükleme Stratejisi
Azure MySQL Flexible Server otomatik yedekleme yapıyor ama bunu sadece “var olsun” diye bırakmayın. Yedekleme politikasını ve geri yükleme prosedürünü önceden test edin.
# Mevcut backup listesini görüntüle
az mysql flexible-server backup list
--resource-group $RESOURCE_GROUP
--name $SERVER_NAME
--output table
# Point-in-time restore (belirli bir zamana geri dön)
# Bu işlem yeni bir sunucu oluşturur, mevcut sunucuyu değiştirmez
RESTORE_TIME="2024-01-15T10:00:00Z"
RESTORE_SERVER_NAME="mysql-prod-restored-$(date +%s)"
az mysql flexible-server restore
--resource-group $RESOURCE_GROUP
--name $RESTORE_SERVER_NAME
--source-server $SERVER_NAME
--restore-time $RESTORE_TIME
--vnet $VNET_NAME
--subnet $SUBNET_NAME
--private-dns-zone "mysql-prod.private.mysql.database.azure.com"
Geo-redundant backup konusunda dikkatli olun. Production ortamı için açmanızı öneririm ama bu ek maliyet demek. Region disaster recovery ihtiyacınız varsa kesinlikle etkinleştirin.
Monitoring ve Alerting Kurulumu
Veritabanınızı kurup bırakmak olmaz. Ne zaman sorun çıktığını öğrenmek için monitoring şart. Azure Monitor entegrasyonu ile CPU, memory, connections, storage gibi metrikleri takip edebilirsiniz.
# Log Analytics Workspace oluştur (henüz yoksa)
WORKSPACE_NAME="law-mysql-monitoring"
az monitor log-analytics workspace create
--resource-group $RESOURCE_GROUP
--workspace-name $WORKSPACE_NAME
--location $LOCATION
# Workspace ID'yi al
WORKSPACE_ID=$(az monitor log-analytics workspace show
--resource-group $RESOURCE_GROUP
--workspace-name $WORKSPACE_NAME
--query "id"
--output tsv)
# Diagnostic settings ekle
SERVER_ID=$(az mysql flexible-server show
--resource-group $RESOURCE_GROUP
--name $SERVER_NAME
--query "id"
--output tsv)
az monitor diagnostic-settings create
--name "mysql-diagnostics"
--resource $SERVER_ID
--workspace $WORKSPACE_ID
--logs '[{"category":"MySqlSlowLogs","enabled":true},{"category":"MySqlAuditLogs","enabled":true}]'
--metrics '[{"category":"AllMetrics","enabled":true}]'
CPU kullanımı için alert tanımlayalım:
# CPU %80 geçince alert
az monitor metrics alert create
--name "mysql-high-cpu"
--resource-group $RESOURCE_GROUP
--scopes $SERVER_ID
--condition "avg Percentage CPU > 80"
--window-size 5m
--evaluation-frequency 1m
--severity 2
--description "MySQL CPU kullanımı %80 üzerinde"
# Storage %85 geçince alert
az monitor metrics alert create
--name "mysql-high-storage"
--resource-group $RESOURCE_GROUP
--scopes $SERVER_ID
--condition "avg storage_percent > 85"
--window-size 15m
--evaluation-frequency 5m
--severity 1
--description "MySQL storage kullanımı %85 üzerinde"
# Aktif bağlantı sayısı için alert
az monitor metrics alert create
--name "mysql-high-connections"
--resource-group $RESOURCE_GROUP
--scopes $SERVER_ID
--condition "avg active_connections > 400"
--window-size 5m
--evaluation-frequency 1m
--severity 2
--description "MySQL aktif bağlantı sayısı 400 üzerinde"
Firewall ve Güvenlik Yapılandırması
Private access kullandığımız için internet üzerinden direkt erişim zaten yok. Ama VNet içinden de sadece yetkili kaynakların erişmesi için ek önlemler almak iyi pratik.
# Mevcut firewall kurallarını listele
az mysql flexible-server firewall-rule list
--resource-group $RESOURCE_GROUP
--name $SERVER_NAME
--output table
# Belirli bir IP aralığına izin ver (public access modunda kullanılır)
# Private access modunda bu genellikle gerekmez ama jump server için:
az mysql flexible-server firewall-rule create
--resource-group $RESOURCE_GROUP
--name $SERVER_NAME
--rule-name "allow-jumpserver"
--start-ip-address "10.0.2.10"
--end-ip-address "10.0.2.10"
# SSL zorunluluğunu doğrula
az mysql flexible-server parameter show
--resource-group $RESOURCE_GROUP
--server-name $SERVER_NAME
--name require_secure_transport
TLS/SSL konusuna özellikle dikkat edin. require_secure_transport parametresi ON olmalı ve uygulama bağlantılarınız SSL sertifikasını doğrulamalı. Azure’un root CA sertifikasını indirip uygulama konfigürasyonunuza eklemeniz gerekiyor.
# Azure MySQL SSL sertifikasını indir
wget -O DigiCertGlobalRootCA.crt.pem
"https://dl.cacerts.digicert.com/DigiCertGlobalRootCA.crt.pem"
# SSL ile bağlantıyı test et
mysql -h $SERVER_FQDN
-u $ADMIN_USER
-p$ADMIN_PASSWORD
--ssl-ca=DigiCertGlobalRootCA.crt.pem
--ssl-mode=VERIFY_CA
-e "SELECT @@version, @@ssl_cipher;"
Read Replica Kurulumu
Okuma yoğun workload’lar için read replica ciddi performans kazancı sağlar. Raporlama sorgularını, analitik işlemleri read replica üzerine yönlendirerek primary sunucunuzun üzerindeki yükü azaltabilirsiniz.
# Read replica oluştur
REPLICA_NAME="mysql-prod-replica-01"
az mysql flexible-server replica create
--resource-group $RESOURCE_GROUP
--replica-name $REPLICA_NAME
--source-server $SERVER_NAME
--location $LOCATION
# Replica durumunu kontrol et
az mysql flexible-server show
--resource-group $RESOURCE_GROUP
--name $REPLICA_NAME
--query "{state:state, replicationRole:replicationRole, sourceServerId:sourceServerId}"
--output json
# Replica FQDN'ini öğren
az mysql flexible-server show
--resource-group $RESOURCE_GROUP
--name $REPLICA_NAME
--query "fullyQualifiedDomainName"
--output tsv
Maliyet Optimizasyonu
Bu konuya dikkat etmezseniz ay sonunda sürpriz fatura gelir. Birkaç pratik öneri:
- Burstable tier: Geliştirme ve test ortamları için Standard_B1ms gibi burstable SKU’lar kullanın, production’dan 3-4 kat daha ucuz.
- Stop/Start: Dev ortamlarını gece durdurun. Flexible Server, Single Server’dan farklı olarak durdurulabilir.
- Storage auto-grow: Açık tutun ama boyutu gereksiz yere büyütmeyin, storage küçülmüyor.
- Backup retention: 7 gün çoğu senaryo için yeterli. 35 güne çıkarmanız maliyeti artırır.
- Geo-redundant backup: Gerçekten ihtiyacınız yoksa kapatın.
# Dev/test sunucusunu durdur (maliyet tasarrufu)
az mysql flexible-server stop
--resource-group $RESOURCE_GROUP
--name $SERVER_NAME
# Tekrar başlat
az mysql flexible-server start
--resource-group $RESOURCE_GROUP
--name $SERVER_NAME
# Mevcut maliyet tahminini kontrol et (Azure Cost Management API)
az consumption usage list
--start-date "2024-01-01"
--end-date "2024-01-31"
--query "[?contains(instanceName,'mysql')]"
--output table
Gerçek Dünya Senaryosu: Migration
Şirketin on-premise MySQL 5.7 sunucusunu Azure’a taşıma senaryosunu düşünelim. Bu durumda mydumper/myloader ya da MySQL Workbench migration wizard kullanabilirsiniz. Ama en pratik yöntem genellikle mysqldump ile logical migration.
# Kaynak sunucudan dump al
mysqldump
--host=eski-sunucu.sirket.local
--user=root
--password
--single-transaction
--routines
--triggers
--events
--databases uygulama_db
--ssl-mode=PREFERRED
> uygulama_db_backup.sql
# Dump dosyasının boyutunu kontrol et
ls -lh uygulama_db_backup.sql
# Azure MySQL'e import et
mysql
--host=$SERVER_FQDN
--user=$ADMIN_USER
--password=$ADMIN_PASSWORD
--ssl-mode=REQUIRED
--ssl-ca=DigiCertGlobalRootCA.crt.pem
uygulama_db < uygulama_db_backup.sql
# Import sonrası tablo sayısını doğrula
mysql -h $SERVER_FQDN -u $ADMIN_USER -p$ADMIN_PASSWORD
-e "SELECT COUNT(*) as tablo_sayisi FROM information_schema.tables WHERE table_schema='uygulama_db';"
Büyük veritabanları için (100GB üzeri) Azure Database Migration Service kullanmak daha mantıklı. Hem online migration destekliyor hem de minimum downtime ile geçiş yapabiliyorsunuz.
Sonuç
Azure Database for MySQL Flexible Server, doğru yapılandırıldığında hem güvenli hem de yönetimi kolay bir veritabanı platformu sunuyor. Bu yazıda sıfırdan production-ready bir kurulum yaptık: networking, güvenlik, monitoring, yedekleme ve kullanıcı yönetimini ele aldık.
En kritik noktalara tekrar değinmek gerekirse: public access yerine private VNet entegrasyonu kullanın, uygulama bağlantıları için ayrı kullanıcılar tanımlayın, slow query log’u mutlaka açın ve monitoring alert’lerini kurmadan ortamı production’a almayın. Read replica’yı da erken aşamada planlayın, ileride eklemek her zaman daha zahmetli.
Single Server modunun 2024 sonu itibarıyla tamamen retirement sürecine girdiğini de hatırlatayım. Hala Single Server üzerindeyseniz Flexible Server migration’ını planlamaya başlamanın tam zamanı.
