in MySql

mysqldump Hareketleri

MaestroPanel’de MySQL Backup/Restore özelliğini çok beğenmiyordum ve refactoring’e karar verdim. Tabi proje gereği refactoring sadece kod üzerinde olmuyor daha geniş bir yelpazede full stack takılmak gerekiyor. Bu da yazılan backup methodlarından, MySQL’in best-practice dump komutuna kadar gidiyor…

Database export işleminin temelinde MySQL’in mysqldump komutunu kullanıyoruz. Daha önce bir kaç component denedik ama version uyuşmazlığından patladı, stabil çalışmadı. Sonra;
Refactoring yaparken MySQL’in MySQL Utility adında bir araç seti çıkarttığını keşfettim. Phyton ile yazmışlar kodlarıda github‘a koymuşlar oh mis!
Yönetimsel olarak güzel araçlar var örneğin benim işime yarayan mysqldbexport ve mysqlimport.
Bunların üzerinde baya bir implementasyon yaptım kendi çapımda fakat gel gelelim export ederken bazı UTF8 karakterlerinde düzgün Insert cümlesi export edemiyor. Örneğin, üstten virgule \’ koymuyor. Çince kararterleri düzgün yazmıyor. Daha önemlisi DROP IF EXISTS veya INSERT IGNORE yapamadığını gördüm. Hal böyle olunca mysqldump’a geri döndüm direkt.
Neyse;

mysqldump MySQL 5.6 sürümü ile birlikte biraz daha güvenlikli olmuş yeni komut satırı parametrelerini öğrenmem gerekti. Hazır öğrenmişkende bu sefer üşenmeyip yazayım dedim.

Daha önceki mysqldump sürümlerinde –password=”Parola” dediğimizde direkt CLI üzerinden parametre geçebiliyorduk artık öyle değil. Bunu derseniz aşağıdaki uyarı çıkıyor.

Warning: Using a password on the command line interface can be insecure.

mysqldump artık “Login Path” veya bir ayar dosyası istiyor. Burada da devreye mysql_config_editor giriyor. Akabinde aşağıdaki komut ile güvenli bir login path oluşturabiliyorsunuz kendinize.

mysql_config_editor set --login-path=local --host=localhost --user=kullanici --password

Bu komut %APPDATA%\MySQL (Widows üzerinde) altına .mylogin.cnf dosyasını açıyor içine de parola bilgisini yazıyor tabi encrypted olarak. Temiz!
Komutla login path oluşturduktan sonra mysqldump’ı aşağıdaki şekilde çalıştırabiliyorsunuz.

mysqldump --login-path=local --databases --result-file=.\dump.sql database_ismi

Bendeki senaryo biraz daha farklı olduğundan –defaults-extra-file parametresini kullandım. Bu parametre default ayarları override ettiğinden daha esneklik sağlıyor.

dosyayı kafama göre bir yere oluşturuyorum ve içerğini aşağıdaki gibi veriyorum, damıtıyorum.

[client]
user = root
password = P@ssw0rd
host = localhost
port = 3306

daha sonra yine mysqldump’ı aşağıdaki şekilde çalıştırabiliyorum.

mysqldump --defaults-extra-file=C:\Configs\root.login.config --databases --result-file=.\dump.sql database_ismi

Artık direkt kod üzerinden mysqldump’ı execute edebildiğime göre esas mysqldump komutunu dizebiliriz.

Burada dikkat edilmesi gereken bir durum var. MySQL dump ile veritabanının SQL Scriptini oluşturduktan sonra, mevcut veritabanının üzerine restore etmekte gerekebiliyor ki shared web hosting ortamlarında çoğu zaman bu senaryo işletiliyor. Bunun için mysqldump’ın –insert-ignore parametresinden ve –force parametresinden yararlanıyoruz.

Toparlarsak aşağıdaki seksi mysqldump örneği çıkıyor;

mysqldump --defaults-extra-file=C:\Configs\root.login.config --skip-set-charset --skip-add-drop-table --no-create-db --tables --events --triggers --routines --extended-insert --complete-insert --insert-ignore --single-transaction --dump-date --databases --add-locks --quick --result-file=.\veritabani_ismi.sql veritabani_ismi

Bu komut ile daha stabil bir restore işlemi gerçekleştiren dump alınabiliyor. Yani benim ulaştığım nokta bu enazından :)

Buradaki avantajlar şöyle;

–extended-insert parametresi ayrı ayrı INSERT INTO cümlesinden ziyade tek bir INSERT INTO cümlesi oluşturuyor. Böyle olunca verilerin tabloya insert edilmesi yarı yarıya hızlanıyor.

–insert-ignore parametresi burada sihiri yapan parametre. Mevcut bir MySQL veritabanına bu yedeği geri yüklediğinizde insert-ignore sayesinde var olan veriler korunuyor ve sadece mevcut olmayan veriler tabloya yazılyor. Uuu!

–no-create-db, parametresini özellikle yazdım. Zaten MaestroPanel bunu create ediyor. Ayrıca create edip Restore işleminin yarıda kalmamasını sağlıyor.

–skip-add-drop-table, parametresinin olması lazım yoksa mevcut tabloyu DROP edip yeniden oluşturuyor bu da veri kaybına nesen oluyor. Ne yazıkki mysqldump CREATE TABLE IF NOT EXISTS gibi bir çıktı üretmiyor. Olsa süper olurdu. O nedenle ya bu paramereyi kullanacağız yada dump bittikten sonra bütün CREATE TABLE stringini CREATE TABLE IF NOT EXISTS olarak değiştireceğiz.

–complete-insert parametresi INSERT cümlesi yazılırken tablonun içindeki alanlarla beraber yazıyor. INSERT’in daha düzgün olmasını sağlıyor. Mevcut veritabanına insert edilirken herhangi bir alan sayısı değişmişse bu parametre durumu kurtarıyor. Eklemekte fayda var.

–add-locks, parametreside stabilite açısından önemli. Backup dosyasını geri yüklerken INSERT sırasında tabloyu WRITE olarak kitlemek lazım ki backup düzgün bir şekilde geri yüklensin.

–no-autocommit parametresi ise yine performans ve stabilite ile alakalı. autocommit olmayınca CRUD işlemleri bir transaction içinde sarmalanmıyor dolayısı ile daha hızlı INSERT yapılıyor.

–quick, parametresi direkt büyük tablolarla alakalı. mysqldump büyük tabloları INSERT ederken veriyi bufferda tutmuyor böylelikle ram veya başka bir limite takılmadan büyük tabloları dışa alabiliyorsunuz.

Elimizde sağlam bir Backup dosyası olduktan sonra bunu usulüne göre mysql’e restore etmek gerekiyor. Restore etmek içinde bir iki trick var.

Tabi dosyamızı yine mysqldump ile restore etmiyoruz. Bu sefer direkt mysql komutunu kullanacağız.

mysql --host=localhost --user=root --password="P@ssw0rd" --port=3306 --database=veritabani_ismi --execute="\. .\veritabani_ismi.sql" --reconnect --compress --force

Şimdi burada önemli olan parametre –force çünkü bu parametre ile mysql, SQL scriptinde herhangi bir hata olduğunda diğerine geçip devam ediyor. Hatırlarsanız export ederken DROP TABLE dememiştik. O nedenle direkt CREATE etmeye çalışacak ve Table ‘*’ already exists diyecek. –force kullanmasaydık ilk CREATE TABLE olayınca geri yükleme hata verir (duru)rdu.

Herkese Selamlar ;)

Yorum Bırak

Comment

  1. Oguzhan Bey,

    Merhaba,

    Daha evvelki bir object dll konusu ile ilgili birşey danışmak istiyordum, noktalar olmadan v e d a t g @ g mail.com ‘a mail atabilir misiniz :) şimdiden teşekkurler