GCP Cloud SQL ile MySQL Veritabanı Kurulumu ve Yapılandırması

Google Cloud Platform üzerinde veritabanı yönetmek, kendi sunucularında MySQL kurup yönetmeye kıyasla çok farklı bir deneyim. Patch yönetimi, yedekleme, replikasyon gibi işleri GCP’ye devredip sadece uygulamanıza odaklanabiliyorsunuz. Ama bu kolaylık beraberinde öğrenme eğrisi getiriyor: Cloud SQL’in davranışları, ağ yapısı, IAM entegrasyonu… Bunları bilmeden kurduğunuz bir Cloud SQL instance’ı ya güvensiz olur ya da beklediğinizden çok daha pahalıya patlar. Bu yazıda baştan sona gerçek bir üretim ortamı kuruyormuş gibi ilerleyeceğiz.

Ön Hazırlık ve Gereksinimler

Başlamadan önce birkaç şeyin hazır olması lazım. GCP hesabınızın aktif ve faturalandırmanın etkin olması şart, Cloud SQL ücretsiz katmanda çalışmıyor. gcloud CLI aracını da kurmanız işleri çok kolaylaştırıyor.

# gcloud CLI kurulumu (Ubuntu/Debian)
curl https://sdk.cloud.google.com | bash
exec -l $SHELL
gcloud init

# Aktif proje kontrolü
gcloud config get-value project

# Gerekli API'leri etkinleştir
gcloud services enable sqladmin.googleapis.com
gcloud services enable servicenetworking.googleapis.com

Projenizi ayarladıktan sonra hangi bölgede instance açacağınıza karar verin. Uygulamanız europe-west1‘de çalışıyorsa veritabanını da aynı bölgeye koyun, yoksa gecikme kaçınılmaz olur.

Cloud SQL Instance Oluşturma

Console Üzerinden Temel Kurulum

GCP Console’dan SQL > Create Instance > MySQL yolunu izleyebilirsiniz. Ama ben her zaman CLI tercih ederim, tekrarlanabilir ve dokümante edilebilir olması açısından:

gcloud sql instances create prod-mysql-01 
  --database-version=MYSQL_8_0 
  --tier=db-n1-standard-2 
  --region=europe-west1 
  --storage-type=SSD 
  --storage-size=100GB 
  --storage-auto-increase 
  --backup-start-time=02:00 
  --enable-bin-log 
  --maintenance-window-day=SUN 
  --maintenance-window-hour=4 
  --deletion-protection

Bu komuttaki parametreleri açıklayayım:

  • –database-version=MYSQL_8_0: MySQL 8.0 kullanıyoruz, 5.7 hâlâ destekleniyor ama yeni projeler için 8.0 tercih edin
  • –tier=db-n1-standard-2: 2 vCPU, 7.5 GB RAM. Küçük/orta yük için iyi başlangıç noktası
  • –storage-type=SSD: Üretimde mutlaka SSD kullanın, HDD performansı ciddi şekilde düşük
  • –storage-auto-increase: Disk dolmak üzereyken otomatik büyütür, gece 3’te disk full alarmıyla uyanmak istemezsiniz
  • –enable-bin-log: Point-in-time recovery için binary log şart
  • –deletion-protection: Yanlışlıkla instance silmeye karşı koruma, üretimde mutlaka açık olsun

Instance oluşumu 5-10 dakika sürebilir. Durumu takip etmek için:

gcloud sql instances describe prod-mysql-01 --format="value(state)"

Ağ Yapılandırması ve Güvenlik

Bu kısım en kritik nokta. Cloud SQL’i yanlış ağ yapılandırmasıyla açarsanız ya hiçbir yerden bağlanamazsınız ya da herkese açık bırakmış olursunuz. İkisi de kötü.

Private IP ile VPC Entegrasyonu

Üretim ortamlarında her zaman Private IP kullanın. Public IP açık olan bir veritabanı, ne kadar iyi korunmuş olursa olsun saldırı yüzeyinizi artırır.

# Önce VPC peering için IP aralığı ayır
gcloud compute addresses create google-managed-services-my-vpc 
  --global 
  --purpose=VPC_PEERING 
  --prefix-length=16 
  --network=my-vpc

# Service networking bağlantısı oluştur
gcloud services vpc-peerings connect 
  --service=servicenetworking.googleapis.com 
  --ranges=google-managed-services-my-vpc 
  --network=my-vpc

# Mevcut instance'a private IP ekle
gcloud sql instances patch prod-mysql-01 
  --network=projects/MY_PROJECT_ID/global/networks/my-vpc 
  --no-assign-ip

--no-assign-ip ile public IP’yi tamamen kaldırıyoruz. Eğer hem private hem public IP’yi tutmak zorundaysanız (geçiş dönemi gibi) bu bayrağı kaldırın ama authorized networks listesini çok kısıtlı tutun.

Authorized Networks (Public IP Gerekiyorsa)

Bazen ofis VPN’i yoktur, geliştirici makinelerinden direkt erişim gerekebilir. Bu durumda belirli IP’lere izin verin:

# Tek IP için
gcloud sql instances patch prod-mysql-01 
  --authorized-networks=203.0.113.10/32

# Birden fazla IP aralığı
gcloud sql instances patch prod-mysql-01 
  --authorized-networks=203.0.113.0/24,198.51.100.15/32

Uyarı: 0.0.0.0/0 yazmayın. Herkesin bağlanabileceği bir MySQL instance’ı açmak, evinizin kapısını açık bırakmakla aynı şey.

Kullanıcı ve Veritabanı Yönetimi

Root Şifresi ve Kullanıcı Oluşturma

# Root şifresi belirle
gcloud sql users set-password root 
  --host=% 
  --instance=prod-mysql-01 
  --password=SUperSecure_P@ss2024!

# Uygulama için ayrı kullanıcı oluştur
gcloud sql users create appuser 
  --host=% 
  --instance=prod-mysql-01 
  --password=App_User_Pass_789!

# Veritabanı oluştur
gcloud sql databases create myapp_prod 
  --instance=prod-mysql-01 
  --charset=utf8mb4 
  --collation=utf8mb4_unicode_ci

utf8mb4 kullanmak önemli. Emoji ve bazı Unicode karakterler için utf8 yeterli değil, utf8mb4 kullanmazsanız ileride karakter encoding sorunlarıyla boğuşursunuz.

Yetki Kısıtlaması

Root kullanıcıyı uygulama bağlantısında kullanmayın. Uygulama kullanıcısına sadece ihtiyacı olan yetkileri verin. Bunun için Cloud SQL proxy üzerinden bağlanıp MySQL içinde grant işlemi yapabilirsiniz:

-- Cloud SQL proxy bağlantısı sonrası MySQL içinde
GRANT SELECT, INSERT, UPDATE, DELETE ON myapp_prod.* TO 'appuser'@'%';
GRANT CREATE TEMPORARY TABLES ON myapp_prod.* TO 'appuser'@'%';
FLUSH PRIVILEGES;

-- Read-only replica kullanıcısı için
GRANT SELECT ON myapp_prod.* TO 'readonly_user'@'%';
FLUSH PRIVILEGES;

Cloud SQL Auth Proxy Kurulumu

Cloud SQL Auth Proxy, bağlantıları şifreleyerek ve IAM kimlik doğrulamasını kullanarak çok daha güvenli bir bağlantı yöntemi sunuyor. Özellikle GKE veya Compute Engine üzerinde çalışan uygulamalar için standart yöntem bu.

# Cloud SQL Auth Proxy indir (Linux amd64)
curl -o cloud-sql-proxy 
  https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.6.0/cloud-sql-proxy.linux.amd64
chmod +x cloud-sql-proxy

# Proxy'yi başlat
./cloud-sql-proxy 
  --port=3306 
  YOUR_PROJECT:europe-west1:prod-mysql-01 &

# Bağlantı testi
mysql -u appuser -p -h 127.0.0.1 -P 3306 myapp_prod

Proxy çalışırken uygulamanız 127.0.0.1:3306‘ya bağlanır, proxy bağlantıyı şifreleyerek Cloud SQL’e iletir. SSL sertifika yönetimiyle uğraşmanıza gerek kalmaz.

Systemd Servis Olarak Çalıştırma

Proxy’yi elle her başlatmak yerine servis olarak ayarlayın:

# /etc/systemd/system/cloud-sql-proxy.service
cat << 'EOF' > /etc/systemd/system/cloud-sql-proxy.service
[Unit]
Description=Google Cloud SQL Auth Proxy
After=network.target

[Service]
Type=simple
User=cloudsql
ExecStart=/usr/local/bin/cloud-sql-proxy 
  --port=3306 
  YOUR_PROJECT:europe-west1:prod-mysql-01
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable cloud-sql-proxy
systemctl start cloud-sql-proxy
systemctl status cloud-sql-proxy

Yedekleme ve Felaket Kurtarma

Otomatik Yedekleme Yapılandırması

# Yedekleme ayarlarını güncelle
gcloud sql instances patch prod-mysql-01 
  --backup-start-time=01:00 
  --retained-backups-count=30 
  --retained-transaction-log-days=7

# Mevcut yedekleri listele
gcloud sql backups list --instance=prod-mysql-01

# Manuel yedek al
gcloud sql backups create 
  --instance=prod-mysql-01 
  --description="Pre-migration backup $(date +%Y%m%d)"

--retained-transaction-log-days=7 ile 7 gün geriye dönük point-in-time recovery yapabilirsiniz. Yani “dün saat 14:37’deki hale dön” diyebilirsiniz. Bu özellik binary log’u açık tuttuğunuzda çalışır, instance oluştururken --enable-bin-log yazmıştık.

Point-in-Time Recovery

Birisi canlı veritabanında DELETE FROM users çalıştırdı ve nereye bağlandığını fark edemedi. Paniğe gerek yok:

# Belirli bir zamana geri dön (yeni instance'a restore)
gcloud sql instances clone prod-mysql-01 prod-mysql-recovery 
  --point-in-time="2024-01-15T14:30:00.000Z"

# Geri yükleme tamamlandığında verileri kontrol et
# Sonra isterseniz orijinal instance'ı da aynı noktaya restore edebilirsiniz
gcloud sql backups restore BACKUP_ID 
  --restore-instance=prod-mysql-01 
  --backup-instance=prod-mysql-01

Read Replica Oluşturma

Okuma yoğun uygulamalar için read replica kurmak performansı ciddi artırır. Raporlama sorguları, analitik işlemler ayrı replica üzerinde çalışsın, primary’ye dokunmasın.

# Read replica oluştur
gcloud sql instances create prod-mysql-replica-01 
  --master-instance-name=prod-mysql-01 
  --region=europe-west1 
  --tier=db-n1-standard-1 
  --replica-type=READ

# Replica durumunu kontrol et
gcloud sql instances describe prod-mysql-replica-01 
  --format="value(replicaConfiguration,replicationStatus)"

# Replica'nın lag durumunu izle
gcloud sql instances describe prod-mysql-replica-01 
  --format="value(replicationStatus.replicationLag)"

Replica’nın bağlantı adresini uygulamanızda ayrı bir connection string olarak tutun. Django, Laravel, Spring Boot gibi frameworklerin çoğunda “primary/replica” ayrımını destekleyen veritabanı routing mekanizmaları var.

Monitoring ve Alerting

Cloud Monitoring Entegrasyonu

# gcloud ile temel metrikleri sorgula
gcloud monitoring metrics list 
  --filter="metric.type:cloudsql"

# Disk kullanımı için alert policy oluştur
gcloud alpha monitoring policies create 
  --notification-channels=CHANNEL_ID 
  --display-name="Cloud SQL Disk Usage High" 
  --condition-display-name="Disk usage above 80%" 
  --condition-filter='resource.type="cloudsql_database" AND metric.type="cloudsql.googleapis.com/database/disk/utilization"' 
  --condition-threshold-value=0.8 
  --condition-threshold-comparison=COMPARISON_GT 
  --condition-duration=300s

Hangi metrikleri izlemeli:

  • cloudsql.googleapis.com/database/cpu/utilization: CPU kullanımı yüzde 80’i geçince alert
  • cloudsql.googleapis.com/database/disk/utilization: Disk yüzde 85’i geçince alert
  • cloudsql.googleapis.com/database/memory/utilization: Bellek kullanımı
  • cloudsql.googleapis.com/database/mysql/innodb_buffer_pool_pages_dirty: InnoDB buffer pool durumu
  • cloudsql.googleapis.com/database/replication/replica_lag: Replica gecikmesi 30 saniyeyi geçince alert

Slow Query Log Etkinleştirme

# Slow query log için database flags ayarla
gcloud sql instances patch prod-mysql-01 
  --database-flags=slow_query_log=on,long_query_time=2,log_queries_not_using_indexes=on

# Diğer faydalı MySQL flags
gcloud sql instances patch prod-mysql-01 
  --database-flags=
slow_query_log=on,
long_query_time=1,
innodb_buffer_pool_size=5368709120,
max_connections=500,
wait_timeout=28800,
interactive_timeout=28800

long_query_time=1 ile 1 saniyeden uzun süren sorguları logluyoruz. Bu logları Cloud Logging üzerinden görebilir, Logs Explorer’dan analiz edebilirsiniz.

Gerçek Dünya Senaryosu: Mevcut Veritabanını Taşıma

Diyelim ki şirketin eski bir bare-metal sunucusunda MySQL 5.7 çalışıyor ve bunu Cloud SQL’e taşımanız gerekiyor. Sıfır kesinti veya minimum kesinti ile göç:

# Kaynak sunucuda: mysqldump ile export
mysqldump 
  --host=old-server-ip 
  --user=root 
  --password 
  --single-transaction 
  --routines 
  --triggers 
  --events 
  --hex-blob 
  --databases myapp_prod 
  > /backup/myapp_prod_migration.sql

# Dump'ı GCS'e yükle
gsutil cp /backup/myapp_prod_migration.sql 
  gs://my-migration-bucket/myapp_prod_migration.sql

# Cloud SQL'e import et
gcloud sql import sql prod-mysql-01 
  gs://my-migration-bucket/myapp_prod_migration.sql 
  --database=myapp_prod 
  --user=root

Büyük veritabanları için bu yöntem çok uzun sürebilir. 50 GB üzeri veritabanları için Database Migration Service (DMS) kullanmayı düşünün, CDC (Change Data Capture) ile minimum kesinti sağlar.

Maliyet Optimizasyonu

Cloud SQL faturası beklenmedik şekilde şişebilir. Dikkat edilmesi gerekenler:

  • Tier seçimi: db-n1-standard-2 ile db-custom-2-7680 arasında maliyet farkı yok ama custom tier daha esnek
  • Storage: Otomatik büyüyen storage küçülmüyor. 100 GB’tan başladıysa ve 300 GB’a çıktıysa 100 GB’a dönemezsiniz
  • Backup storage: Toplam backup boyutu instance storage’ının yüzde 7’sine kadar ücretsiz, sonrası ücretli
  • Network egress: Aynı bölgedeki GCE instance’larına bağlantı ücretsiz, farklı bölge veya internet çıkışı ücretli
# Geliştirme ortamları için instance'ı durdur (para biriktir)
gcloud sql instances patch dev-mysql-01 
  --activation-policy=NEVER

# Tekrar başlat
gcloud sql instances patch dev-mysql-01 
  --activation-policy=ALWAYS

Geliştirme instance’larını çalışma saatleri dışında durdurmak için Cloud Scheduler + Cloud Functions kombinasyonu kurabilirsiniz, aylık faturayı yüzde 60-70 düşürebilirsiniz.

Sonuç

Cloud SQL MySQL kurulumu teknik olarak birkaç tıklama veya komutla tamamlanıyor ama güvenli, ölçeklenebilir ve maliyet etkin bir kurulum için bunların arkasındaki detayları bilmek şart. Özetlersek:

  • Ağ güvenliği önce gelir: Private IP kullanın, public IP zorunluysa authorized networks’ü kısıtlayın
  • Auth Proxy standart olsun: Özellikle GCE ve GKE’de, SSL yönetimi yerine proxy tercih edin
  • Yedekleme ve PITR’ı doğrulayın: Yedek almak yetmez, restore’u test edin
  • Read replica’yı erkenden kurun: Okuma yükü artmadan önce hazır olsun
  • Monitoring’i ilk günden açın: Disk dolu alarmını production’da öğrenmek istemezsiniz
  • Database flags’leri dikkatli ayarlayın: Yanlış bir innodb_buffer_pool_size tüm instance’ı olumsuz etkileyebilir

GCP’nin managed service olması sizi tamamen sorumluluktan kurtarmıyor. Schema tasarımı, index yönetimi, connection pooling, sorgu optimizasyonu hâlâ sizin işiniz. Ama patch yönetimi, fiziksel disk arızası, replikasyon konfigürasyonu gibi konuları GCP’ye devredebilmek gerçekten değerli. Bu temel kurulumun üstüne Terraform ile Infrastructure as Code entegrasyonu yapmak da harika bir sonraki adım, ama o konuyu ayrı bir yazıya bırakalım.

Bir yanıt yazın

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