MySQL'de REPAIR TABLE komutu nasıl kullanılır?
Selamlar, bu yazımda MySQL'in REPAIR TABLE komutuna bir göz atalım. Konu çok da popüler değil çünkü çoğumuz artık InnoDB kullanıyoruz, ama eski bir projeye dokunduğunuzda ya da loglama için MyISAM tutmuş bir sistemle karşılaştığınızda bu komut işinize yarıyor. Lafı uzatmadan başlayayım.
REPAIR TABLE nedir?
REPAIR TABLE, bozulmuş tablo dosyalarını onarmaya yarayan bir MySQL ifadesidir. Esas olarak MyISAM, ARCHIVE ve CSV depolama motorlarıyla (storage engine) çalışır. InnoDB'yi doğrudan desteklemez; orada ya crash recovery devreye girer ya da ALTER TABLE ... ENGINE=InnoDB ile tabloyu yeniden oluşturursunuz.
Tablonun bozulma sebepleri genelde tanıdıktır: beklenmedik sunucu kapanması, disk I/O hataları, donanım arızası, dosya sistemi tutarsızlığı. Yani büyük çoğunlukla yazılımın değil, altındaki katmanın hatası.
Önce kontrol, sonra onarım
Bir tabloya doğrudan tamir komutu sokmadan önce gerçekten bozulup bozulmadığına bakalım. CHECK TABLE bunun için var:
CHECK TABLE orders;
Çıktıda status: error ya da Corrupt görüyorsanız onarıma ihtiyaç var demektir. OK görüyorsanız zaten dokunmaya gerek yok.
Temel sözdizimi
REPAIR TABLE table_name [QUICK] [EXTENDED] [USE_FRM];
Tek seferde birden fazla tabloyu da onarabilirsiniz:
REPAIR TABLE orders, customers, payments;
Seçenekler
Üç tane bayrağımız var ve her biri farklı bir senaryoya bakıyor:
- QUICK: Sadece index dosyasını onarır, veri dosyasına dokunmaz. Hızlıdır, büyük tablolarda canınızı kurtarır. Sadece index bozulduğundan eminseniz tercih edin.
- EXTENDED: Index'i tek seferde sıralamak yerine satır satır yeniden inşa eder. Yavaş ama daha kapsamlı;
QUICKçözmediğinde devreye girer. - USE_FRM: Index dosyası tamamen kaybolduğunda ya da ciddi bozuksa tablo tanımından index'i yeniden kurar. MySQL 5.7 ve öncesinde
.frmdosyasını okur, MySQL 8.0+'ta data dictionary'i kullanır. Son çare niteliğinde.
Basit bir onarım
Sadeyağ kullanımı şöyle:
REPAIR TABLE orders;
Tipik çıktı şu şekildedir:
+------------------+--------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+------------------+--------+----------+----------+
| mydb.orders | repair | status | OK |
+------------------+--------+----------+----------+
Msg_text sütununda OK görüyorsanız iş tamam.
QUICK ve EXTENDED ne zaman?
Bence en çok kafa karıştıran nokta bu. Genel kuralım şu: CHECK TABLE size 'index hatası' gösteriyorsa önce QUICK deneyin. Bir-iki dakikada büyük tabloyu kurtarabiliyor.
REPAIR TABLE orders QUICK;
Eğer QUICK yetmediyse ve hâlâ tutarsızlık varsa EXTENDED'e geçin:
REPAIR TABLE orders EXTENDED;
EXTENDED saatlerce sürebilir, o yüzden production'da çalıştırmadan önce bakım penceresi planlamak işinize yarar.
Sunucu çalışmıyorken: myisamchk
Bazen MySQL servisi hiç açılmıyor, çünkü tablo açılışta bile patlıyor. Bu durumda myisamchk komut satırı aracı işe yarar; ama önemli bir nokta var: MySQL durdurulmadan kullanılmaz. Çalışan bir sunucunun MyISAM dosyasına dışarıdan dokunmak yeni bozulmalar yaratır.
sudo systemctl stop mysql
myisamchk --recover /var/lib/mysql/mydb/orders.MYI
sudo systemctl start mysql
Sunucu çalışıyorken çoklu tablo onarımı için mysqlcheck daha rahat:
mysqlcheck --repair --databases mydb -u root -p
InnoDB için durum farklı
InnoDB tablolarında REPAIR TABLE çalışmaz, hata döner. InnoDB'nin kendi crash recovery mekanizması vardır; gerçekten ciddi bir bozulma varsa my.cnf'e innodb_force_recovery = 1 (gerekirse 2, 3 ile yukarı çıkarsınız) ekleyip sunucuyu kaldırır, mysqldump ile veriyi alır, temiz bir şemaya geri yüklersiniz. Daha hafif vakalarda tablonun motorunu yeniden uygulamak yetiyor:
ALTER TABLE orders ENGINE = InnoDB;
Sık karşılaşılan hatalar
- Yedek almadan onarıma başlamak: Onarım sürecinde durum daha da kötüye gidebilir. Komutu çalıştırmadan önce en azından
.MYDve.MYIdosyalarının kopyasını alın. - InnoDB'ye REPAIR TABLE çalıştırmaya kalkışmak: Hata mesajını görüp paniğe kapılmayın; doğru yol crash recovery ya da
ALTER TABLE ... ENGINE=InnoDB. - MySQL çalışırken
myisamchkkullanmak: En sık tuzaklardan biri. Tablo dosyasına aynı anda iki taraftan dokunulduğu için bozulma katlanır. Önce servisi durdurun. - Hep
EXTENDEDile başlamak: Saatler kaybedersiniz. ÖnceQUICKdeneyin, yetmezse genişletin.
Kapanış
REPAIR TABLE, MyISAM ve ARCHIVE motorlarıyla çalışan eski sistemler için hâlâ çok pratik bir kurtarma aracı. Bana sorarsanız, komutun kendisinden çok 'ne zaman hangi seçeneği kullanacağım' kısmı önemli; bir de yedek almayı unutmamak. InnoDB tarafındaysanız zaten farklı bir yol haritanız var. Umarım faydalı olur, bir sonraki yazıda görüşmek üzere.
