15%

Tüm Hosting Hizmetlerinde %15 indirim

Becerilerini test et ve herhangi bir hosting planında İndirim kazan

Kodu kullanın:

Skills
Başlayın
22.10.2024
1 +1

MySQL Workbench Kullanarak Yedekten MySQL Veritabanı Nasıl Geri Yüklenir

MySQL Workbench kullanarak bir MySQL veritabanını yedekten geri yüklemek, GUI’nin Veri İçe Aktarma/Geri Yükleme sihirbazı aracılığıyla bir .sql döküm dosyasını (veya dizin tabanlı bir dışa aktarımı) hedef bir şemaya aktarmak anlamına gelir; bu işlem dahili olarak sunucunuza karşı mysql istemci komutlarını çalıştırır. Küçük ve orta ölçekli veritabanları için işlem beş dakikadan kısa sürer ve üç şey gerektirir: çalışan bir MySQL sunucu örneği, geçerli bir yedek dosyası ve yeterli ayrıcalıklara sahip bir kullanıcı hesabı (en az CREATE, DROP, INSERT, ALTER ve INDEX).

Bu kılavuz, bağlantı kurulumundan geri yükleme sonrası doğrulamaya kadar her adımı kapsar; resmi belgelerin üstünkörü geçtiği uç durumlar da dahil olmak üzere — karakter seti uyumsuzlukları, kısmi geri yüklemeler, büyük dosya zaman aşımları ve ayrıcalık hataları.

Ön Koşullar ve Ortam Kontrol Listesi

MySQL Workbench’e dokunmadan önce aşağıdakileri doğrulayın:

  • MySQL Workbench 8.0+ yüklü olmalıdır. Burada açıklanan UI düzeni 8.0.x sürümüyle eşleşmektedir. Eski 6.x derlemelerinde farklı bir menü yolu bulunmaktadır.
  • Yedek dosya formatı uyumlu olmalıdır. MySQL Workbench’in Veri İçe Aktarma sihirbazı, mysqldump tarafından, MySQL Workbench’in kendi Veri Dışa Aktarma özelliği tarafından veya standart SQL DDL/DML çıktısı üreten herhangi bir araç tarafından oluşturulan .sql dosyalarını kabul eder. .xbstream (Percona XtraBackup) veya ikili .frm/.ibd dosyalarını yerel olarak içe AKTARMAZ — bunlar ayrı bir fiziksel geri yükleme işlemi gerektirir.
  • Hedef MySQL sunucu sürümü. MySQL 8.0’dan alınan bir dökümü MySQL 5.7 sunucusuna geri yüklemek, döküm 8.0’a özgü sözdizimi kullanıyorsa (örn. görünmez sütunlar, işlevsel indeksler) başarısız olur. Her zaman ana sürümleri eşleştirin veya daha yeni bir sürüme geri yükleyin.
  • Kullanıcı ayrıcalıkları. Hesabınızın gerekli izinlere sahip olduğunu doğrulamak için şu sorguyu çalıştırın:
SHOW GRANTS FOR 'your_user'@'localhost';
  • max_allowed_packet ayarı. BLOB sütunları veya uzun INSERT ifadeleri içeren büyük dökümlerde, sunucunun max_allowed_packet değeri yeterince büyük olmalıdır. Gerekirse kontrol edin ve geçici olarak artırın:
SHOW VARIABLES LIKE 'max_allowed_packet';
SET GLOBAL max_allowed_packet = 1073741824; -- 1 GB
  • net_read_timeout ve net_write_timeout. Yavaş bağlantılar üzerinden yapılan büyük geri yüklemeler zaman aşımı eşiklerine ulaşabilir. Başlamadan önce her ikisini de en az 3600 saniyeye ayarlayın.

Uzak bir sunucu yönetiyorsanız, VPS Hosting örneğinizde MySQL’in 3306 numaralı portunun iş istasyonunuzdan erişilebilir olduğundan emin olun veya bir SSH tüneli kullanın (aşağıda ele alınmaktadır).

Adım 1: MySQL Workbench’i Başlatın ve Sunucunuza Bağlanın

MySQL Workbench’i açın. Ana ekranda, kayıtlı bağlantılarınızı MySQL Connections altında göreceksiniz.

Yerel bir sunucuya bağlanma: Bağlantı kutucuğuna tıklayın. İstendiğinde parolanızı girin.

SSH tüneli aracılığıyla uzak bir sunucuya bağlanma: MySQL sunucunuz uzak bir ana bilgisayardaysa ve 3306 numaralı port herkese açık değilse (önerilen güvenlik yaklaşımı), Workbench’in yerleşik SSH tünelini kullanın:

  1. “MySQL Connections”ın yanındaki + simgesine tıklayın.
  2. Connection Method‘u Standard TCP/IP over SSH olarak ayarlayın.
  3. SSH ana bilgisayar adını, SSH kullanıcı adını ve SSH anahtar dosyası yolunu girin.
  4. MySQL ana bilgisayar adını 127.0.0.1 ve portu 3306 olarak ayarlayın.
  5. Devam etmeden önce tünelin çalıştığını doğrulamak için Test Connection‘a tıklayın.

Bu, herhangi bir üretim sunucusu için doğru yaklaşımdır — MySQL’i asla doğrudan genel internete açmayın.

Adım 2: Hedef Veritabanı Şemasını Hazırlayın

İçe aktarmadan önce bir hedef şemaya ihtiyacınız var. İki seçeneğiniz bulunmaktadır:

Seçenek A: Mevcut Bir Şemaya Geri Yükleme

Yedek, sunucuda hâlâ mevcut olan bir şemadan alındıysa (örn. hatalı bir geçişten sonra geri alıyorsunuz), şema soldaki Navigator > Schemas panelinde zaten görünürdür. Burada herhangi bir işlem yapmanıza gerek yok — içe aktarma yapılandırması sırasında seçeceksiniz.

Kritik uyarı: Mevcut bir şemaya içe aktarma, döküm dosyanız DROP TABLE IF EXISTS ifadeleri içermedikçe mevcut tabloları otomatik olarak silmez. Dökümünüz mysqldump --add-drop-table ile oluşturulduysa (varsayılan), mevcut tablolar silinip yeniden oluşturulacaktır. Oluşturulmadıysa, yinelenen verilerle veya kısıtlama ihlalleriyle karşılaşabilirsiniz. Onaylamak için .sql dosyanızın ilk 50 satırını inceleyin:

head -50 /path/to/your_backup.sql

Seçenek B: Yeni Bir Şema Oluşturma

Yeni bir şemaya geri yüklüyorsanız (geçiş, yeni ortam, felaket kurtarma), önce oluşturun. File > New Query Tab‘a gidin ve şunu çalıştırın:

CREATE DATABASE `database_name`
  CHARACTER SET utf8mb4
  COLLATE utf8mb4_unicode_ci;

CHARACTER SET utf8mb4 değerini her zaman açıkça belirtin. Şemayı sunucunun varsayılan karakter setiyle oluşturursanız ve dökümünüz bir utf8mb4 veritabanından alındıysa, dize sütunlarında sessiz karakter kodlaması bozulması riskiyle karşılaşırsınız. Çalıştırdıktan sonra, yeni şemayı görünür kılmak için Schemas panelindeki yenile simgesine (döngüsel ok) tıklayın.

Adım 3: Veri İçe Aktarma Sihirbazını Açın

Üst menü çubuğunda Server > Data Import‘a gidin. Data Import/Restore paneli ana çalışma alanında açılır.

İki içe aktarma modu göreceksiniz:

İçe Aktarma ModuNe Zaman Kullanılır
Import from Self-Contained Filemysqldump veya Workbench Veri Dışa Aktarma (tek dosya modu) tarafından üretilen tek bir .sql dosyası. Bu en yaygın durumdur.
Import from Dump Project FolderWorkbench’in “proje klasörü” modunda Veri Dışa Aktarma özelliği tarafından üretilen, şema/tablo bazında düzenlenmiş birden fazla .sql dosyası içeren bir dizin. Her tablo kendi dosyasını alır.

Geri yükleme işlemlerinin büyük çoğunluğu için Import from Self-Contained File‘ı seçin.

Browse‘a tıklayın ve .sql yedek dosyanıza gidin. Workbench tam yolu alanda gösterecektir.

Adım 4: Hedef Şemayı ve İçe Aktarma Seçeneklerini Yapılandırın

Varsayılan Hedef Şemayı Seçme

Default Schema to be Imported To altında açılır menüyü açın ve Adım 2’de belirlediğiniz veya oluşturduğunuz hedef şemayı seçin.

Bu alanı boş bırakma durumu: Döküm dosyanız kendi CREATE DATABASE ve USE ifadelerini içeriyorsa (mysqldump --databases veya --all-databases bayrağıyla çalıştırıldığında yaygındır), hedef şema alanını boş bırakabilirsiniz. Workbench, şema seçimini SQL betiğine bırakacaktır. Ancak bu, dökümün veritabanını kendisinin oluşturmaya çalışacağı anlamına gelir — zaten mevcutsa, döküm CREATE DATABASE IF NOT EXISTS içermiyorsa hata alabilirsiniz.

Hedef şema seçmeniz gereken durum: Döküm mysqldump database_name > backup.sql ile oluşturulduysa (--databases olmadan), dosya hiçbir CREATE DATABASE veya USE ifadesi içermez. Burada hedef şemayı SEÇMENİZ ZORUNLUDUR, aksi takdirde içe aktarma ERROR 1046: No database selected hatasıyla başarısız olur.

Döküm Yapısı ve Verisi

Workbench’in proje klasörü dışa aktarımını kullandıysanız, seçici olarak içe aktarmak için onay kutuları göreceksiniz:

  • Dump Structure and Data — tam geri yükleme (varsayılan, felaket kurtarma için önerilir)
  • Dump Data Only — şemayı yeniden oluşturmadan tabloları yeniden doldurur; şema zaten eşleştiğinde kullanışlıdır
  • Dump Structure Only — satır eklemeden tabloları/görünümleri/prosedürleri yeniden oluşturur

Adım 5: İçe Aktarmayı Çalıştırın

Panelin sağ alt köşesindeki Start Import‘a tıklayın.

Workbench, .sql dosyanızı mysql komut satırı istemcisi aracılığıyla ileten bir arka plan işlemi başlatır. Import Progress sekmesi ve Logs paneli gerçek zamanlı olarak güncellenir. Şunlara dikkat edin:

  • Yeşil ilerleme çubuğunun %100’e ulaşması — başarılı tamamlama.
  • ERROR 1044 — erişim reddedildi; kullanıcınızın hedef şema üzerinde yeterli ayrıcalığı yok.
  • ERROR 1005 / ERROR 1215 — yabancı anahtar kısıtlaması hatası; tablolar yanlış sırada oluşturuluyor veya başvurulan tablo eksik. Bu bazen kısmi dökümlerde yaşanır.
  • ERROR 2006: MySQL server has gone awaymax_allowed_packet veya zaman aşımı eşiğine ulaşıldı. Ön Koşullar bölümünde gösterildiği gibi her iki değeri de artırın ve yeniden deneyin.
  • Packet too large — yukarıdakiyle aynı temel neden.

Büyük veritabanlarında (çok GB’lık dökümlerde), Workbench GUI donmuş görünebilir. Değildir — altta yatan mysql işlemi hâlâ çalışmaktadır. Pencereyi kapatmayın. Büyük geri yüklemeler üzerinde daha fazla kontrole ihtiyaç duyuyorsanız, komut satırı yaklaşımı daha güvenilirdir:

mysql -u your_user -p --max_allowed_packet=1G database_name < /path/to/backup.sql

Adım 6: Geri Yüklenen Veritabanını Doğrulayın

Başarılı içe aktarma mesajı yeterli bir onay değildir. Her zaman aktif doğrulama yapın.

Şema Düzeyinde Doğrulama

Navigator panelinde Schemas‘a sağ tıklayın ve Refresh All‘u seçin. Geri yüklenen veritabanını genişletin ve görsel olarak doğrulayın:

  • Beklenen tüm tablolar mevcut
  • Görünümler, saklı prosedürler ve tetikleyiciler ilgili düğümler altında listeleniyor

Satır Sayısı Spot Kontrolü

Yeni bir sorgu sekmesi açın, geri yüklenen veritabanınızı seçin ve şunu çalıştırın:

SELECT
  table_name,
  table_rows,
  ROUND((data_length + index_length) / 1024 / 1024, 2) AS size_mb
FROM information_schema.tables
WHERE table_schema = 'database_name'
ORDER BY table_rows DESC;

Bu satır sayılarını kaynak sisteminizle veya önceki bir yedek manifestosuyla karşılaştırın. table_rows değeri information_schema içinde InnoDB için bir tahmindir — kritik tablolarda kesin sayılar için doğrudan SELECT COUNT(*) FROM table_name çalıştırın.

Veri Bütünlüğü Kontrolü

InnoDB tabloları için hızlı bir tutarlılık kontrolü çalıştırın:

CHECK TABLE your_table_name EXTENDED;

Yabancı anahtar ilişkileriniz varsa, içe aktarma sırasında referans bütünlüğünün bozulmadığını doğrulayın:

SET FOREIGN_KEY_CHECKS = 1;
-- Then attempt a JOIN across related tables to confirm linkage
SELECT COUNT(*) FROM orders o JOIN customers c ON o.customer_id = c.id;

Karakter Kodlaması Doğrulaması

Uygulamanız çok dilli içerik depoluyorsa, özel karakterlerin bozulmadığını doğrulayın:

SELECT column_name FROM table_name WHERE column_name LIKE '%ü%' LIMIT 5;

Sonuçlar olması gerektiği hâlde boşsa, büyük olasılıkla döküm ile hedef şema arasında bir karakter seti uyumsuzluğu vardır.

Büyük Yedek Dosyalarını Yönetme ve Performans Değerlendirmeleri

Birkaç yüz megabaytı aşan veritabanlarında Workbench GUI pratik olmaktan çıkar. Şu yaklaşımları göz önünde bulundurun:

Dökümü tabloya göre bölün: Yalnızca belirli tabloları geri yüklemeniz gerekiyorsa, bunları döküm dosyasından çıkarın:

grep -n "Table structure for table" /path/to/backup.sql

Bu, her tablo bloğu için satır numaralarını gösterir ve sed veya awk ile belirli bir aralığı çıkarmanıza olanak tanır.

CSV tabanlı geri yüklemeler için mysqlimport kullanın: Yedeğiniz CSV formatındaysa (SELECT ... INTO OUTFILE aracılığıyla dışa aktarıldıysa), mysqlimport SQL ifadelerini satır satır işlemekten önemli ölçüde daha hızlıdır.

İçe aktarma sırasında indeksleri devre dışı bırakın: Çok büyük veri kümeleri için, indeks güncellemelerini geçici olarak devre dışı bırakmak içe aktarma süresini %50–80 oranında azaltabilir:

ALTER TABLE large_table DISABLE KEYS;
-- (import data)
ALTER TABLE large_table ENABLE KEYS;

InnoDB için özellikle, içe aktarmadan önce oturumunuzda innodb_autoinc_lock_mode = 0 ve foreign_key_checks = 0 ayarlayın:

SET SESSION foreign_key_checks = 0;
SET SESSION unique_checks = 0;

MySQL’i yüksek G/Ç verimine sahip bir Dedicated Server üzerinde çalıştırıyorsanız, verileri sürekli diske yazmak yerine bellekte tutarak içe aktarmayı hızlandırmak için innodb_buffer_pool_size değerini geçici olarak artırabilirsiniz.

MySQL Workbench Veri İçe Aktarma ile Komut Satırı Geri Yükleme: Karşılaştırma

KriterMySQL Workbench GUI`mysql` CLI / `mysqldump`
Kullanım kolaylığıYüksek — tıkla ve kullanOrta — CLI deneyimi gerektirir
Büyük dosya yönetimi~500 MB üzerinde zayıf (GUI donuyor)Mükemmel — doğrudan akış sağlar
İlerleme görünürlüğüLog paneli, sınırlı ayrıntı--verbose bayrağıyla ayrıntılı
Seçici tablo geri yüklemeDestekleniyor (proje klasörü modu)Manuel dosya düzenleme veya --tables bayrağı gerektirir
Otomasyon / betiklemeMümkün değilcron/bash aracılığıyla tam betiklenebilir
SSH tünel desteğiYerleşikManuel SSH port yönlendirmesi gerekli
Karakter seti kontrolüSınırlı--default-character-set aracılığıyla tam kontrol
En iyi kullanımGeçici geri yüklemeler, geliştirme ortamlarıÜretim, CI/CD, büyük veritabanları

Yaygın Tuzaklar ve Bunlardan Kaçınma Yolları

DEFINER ifadeleri içeren bir dökümü geri yükleme: Saklı prosedürler ve görünümler genellikle DEFINER='original_user'@'original_host' içerir. Bu kullanıcı hedef sunucuda mevcut değilse, içe aktarma başarılı olur ancak bu nesneleri çalıştırmak ERROR 1449 hatasıyla başarısız olur. İçe aktarmadan önce DEFINER ifadelerini kaldırın veya değiştirin:

sed 's/DEFINER=[^ ]* / /g' original_backup.sql > cleaned_backup.sql

Saat dilimi uyumsuzlukları: Uygulamanız DATETIME değerleri depoluyorsa ve kaynak ile hedef sunucular farklı saat dilimlerindeyse, veriler kaymış görünecektir. Geri yüklemeden önce her zaman @@global.time_zone değerinin kaynak ve hedef arasında eşleştiğini doğrulayın.

Çoğaltmalı bir ortama geri yükleme: Hedef MySQL sunucusu bir çoğaltma birinciliyse, içe aktarma ifadeleri ikili günlüğe yazılacak ve tüm kopyalara çoğaltılacaktır. Bu genellikle tam geri yükleme için istenen bir durumdur, ancak kopyalar zaten ileride veya geride ise sorunlara yol açabilir. Büyük bir geri yükleme işleminden önce kopyalardaki çoğaltmayı duraklatın.

İkili günlük şişmesi: Büyük içe aktarmalar devasa ikili günlük dosyaları oluşturur. Disk alanı kısıtlıysa, oturum için ikili günlüğü geçici olarak devre dışı bırakın:

SET SQL_LOG_BIN = 0;
-- (perform import)
SET SQL_LOG_BIN = 1;

Not: bu SUPER veya BINLOG ADMIN ayrıcalığını gerektirir ve yalnızca bağımsız sunucularda yapılmalıdır, kopyaların ikili günlüğe bağlı olduğu çoğaltma birincillerinde asla yapılmamalıdır.

Gelecekteki Veri Kayıplarını Önlemek İçin Otomatik Yedeklemeleri Ayarlama

Bir geri yükleme prosedürü, onu besleyen yedek kadar iyidir. MySQL sunucunuzu kendiniz yönetiyorsanız — ister cPanel’li VPS üzerinde ister yalın bir Linux VPS üzerinde — yedeklerinizi bir cron işiyle otomatikleştirin:

# Daily mysqldump backup with timestamp, retained for 7 days
0 2 * * * /usr/bin/mysqldump -u backup_user -p'StrongPassword' 
  --single-transaction 
  --routines 
  --triggers 
  --hex-blob 
  --default-character-set=utf8mb4 
  your_database | gzip > /backups/db_$(date +%F).sql.gz 
  && find /backups -name "db_*.sql.gz" -mtime +7 -delete

Temel bayraklar açıklandı:

  • --single-transaction — InnoDB tablolarının tutarlı bir anlık görüntüsünü kilitlemeden alır, canlı veritabanları için zorunludur
  • --routines — saklı prosedürleri ve fonksiyonları içerir (varsayılan olarak atlanır)
  • --triggers — tetikleyicileri içerir (varsayılan olarak dahildir, ancak açık belirtmek daha iyidir)
  • --hex-blob — BLOB sütunlarını onaltılık dizeler olarak döker, ikili veri bozulmasını önler

Yedekleri sunucu dışında saklayın. Koruduğu veritabanıyla aynı diskte bulunan bir yedek, yedek değildir — yanlış bir güvenlik hissidir. Uzak depolama, nesne depolama veya ikincil bir sunucu kullanın. Barındırma ortamınız VPS Kontrol Panellerini destekliyorsa, çoğu panel kopyaları otomatik olarak uzak hedeflere gönderebilen yerleşik zamanlanmış yedekleme özellikleri içerir.

Teknik Temel Çıkarımlar Kontrol Listesi

Herhangi bir MySQL geri yüklemesi yapmadan önce şu karar matrisini gözden geçirin:

  • [ ] Yedek dosya türünün .sql (metin tabanlı döküm) olduğunu doğrulayın — XtraBackup ikili formatı değil
  • [ ] Kaynak ve hedef arasında MySQL sunucu ana sürümlerini eşleştirin
  • [ ] Kullanıcının hedef şema üzerinde CREATE, DROP, INSERT, ALTER, INDEX ayrıcalıklarına sahip olduğunu doğrulayın
  • [ ] max_allowed_packet ve zaman aşımı değişkenlerini kontrol edin; döküm BLOB içeriyorsa veya büyükse artırın
  • [ ] CREATE DATABASE / USE ifadelerinin mevcut olup olmadığını belirlemek için dökümün ilk 50 satırını inceleyin
  • [ ] Karar verin: mevcut şemaya geri yükleme (veri birleşme riski) mi yoksa yeni şema (temiz başlangıç) mı
  • [ ] Farklı kullanıcı hesaplarına sahip farklı bir sunucuya geri yüklüyorsanız DEFINER ifadelerini kaldırın
  • [ ] Döküm ile hedef şema arasında karakter setlerinin eşleştiğini doğrulayın (evrensel olarak utf8mb4 önerilir)
  • [ ] Üretim geri yüklemeleri için: çoğaltmayı devre dışı bırakın, uygunsa ikili günlüğü devre dışı bırakın, geri yükleme öncesi anlık görüntü alın
  • [ ] İçe aktarma sonrası: satır sayılarını doğrulayın, CHECK TABLE çalıştırın, uygulama bağlantısını test edin
  • [ ] 500 MB üzerindeki veritabanları için: Workbench GUI’yi atlayın ve doğrudan mysql CLI kullanın

SSS

S: MySQL Workbench sıkıştırılmış bir .sql.gz yedek dosyasını doğrudan geri yükleyebilir mi?

Hayır. MySQL Workbench’in Veri İçe Aktarma sihirbazı gzip ile sıkıştırılmış dosyaları kabul etmez. Önce dosyayı gunzip backup.sql.gz ile açın veya doğrudan CLI aracılığıyla iletin: gunzip -c backup.sql.gz | mysql -u user -p database_name.

S: İçe aktarma hatasız tamamlanıyor ancak bazı tablolar neden eksik?

En yaygın neden, dökümün --no-tablespaces ile oluşturulmuş olması veya belirli tabloları dışlayan kısmi bir dışa aktarım olmasıdır. .sql dosyasını açın ve eksik tabloların döküme hiç dahil edilip edilmediğini doğrulamak için CREATE TABLE table_name ifadesini arayın.

S: Workbench’te “Import from Self-Contained File” ile “Import from Dump Project Folder” arasındaki fark nedir?

Bağımsız dosya, tüm veritabanı için tüm DDL ve DML’yi içeren tek bir monolitik .sql dosyasıdır. Döküm proje klasörü ise her tablonun şeması ve verilerinin ayrı dosyalarda depolandığı bir dizin yapısıdır — bu format, Workbench’in Veri Dışa Aktarma özelliğini “Export to Dump Project Folder” seçeneğiyle kullandığınızda üretilir. Proje klasörü formatı, seçici tablo düzeyinde geri yüklemelere daha kolay olanak tanır.

S: Geri yüklemem ERROR 1215: Cannot add foreign key constraint hatasıyla başarısız oluyor. Nasıl düzeltirim?

Bu, tablolar yabancı anahtar bağımlılıklarını ihlal eden bir sırayla oluşturulduğunda yaşanır — alt tablo oluşturulduğunda başvurulan üst tablo henüz mevcut değildir. Çözüm, içe aktarma oturumu için yabancı anahtar kontrollerini devre dışı bırakmaktır. SET FOREIGN_KEY_CHECKS=0; ifadesini .sql dosyanızın başına, SET FOREIGN_KEY_CHECKS=1; ifadesini ise sonuna ekleyin ve içe aktarmayı yeniden çalıştırın.

S: Önce anlık görüntü almadan doğrudan canlı bir üretim veritabanına yedek geri yüklemek güvenli midir?

Hayır. Canlı veritabanının üzerine yazmadan önce her zaman mevcut bir yedeğini alın. Yedek dosyasına güvenseniz bile, yarıda başarısız olan bir geri yükleme işlemi şemayı kısmen değiştirilmiş bir durumda bırakabilir. Ardından geri yüklemeye devam etmeden önce mevcut durumu saniyeler içinde ve kesinti olmadan yakalamak için mysqldump --single-transaction kullanın.

15%

Tüm Hosting Hizmetlerinde %15 indirim

Becerilerini test et ve herhangi bir hosting planında İndirim kazan

Kodu kullanın:

Skills
Başlayın