InnoDB tablo bozulması nasıl kurtarılır? MySQL veya MariaDB’de görülen “table is corrupted”, “InnoDB: page corruption”, “index is corrupt” ya da “crashed table” benzeri kayıtlar; tek bir tabloyu, bir şemayı veya tüm veritabanı sunucusunu etkileyebilir. Doğru yaklaşım, doğrudan onarım komutu çalıştırmak değil; önce disk ve hata günlüklerini incelemek, yazmaları durdurmak, erişilebilen veriyi güvenli biçimde dışa aktarmak ve temiz bir InnoDB ortamına geri yüklemektir. Bu rehber, Linux üzerinde çalışan MySQL ve MariaDB servislerinde InnoDB hasarını veri kaybı riskini büyütmeden teşhis ve kurtarma sürecine odaklanır.
Belirti ve kapsam: InnoDB bozulması ne zaman düşünülmelidir?
InnoDB, MySQL’in işlem günlükleri ve çökme kurtarma mekanizmaları bulunan varsayılan depolama motorudur. Bu nedenle her uygulama hatası fiziksel tablo bozulması anlamına gelmez. Önce sorunun yalnızca sorgu, yetki, bağlantı veya disk alanı kaynaklı olmadığını ayırmak gerekir.
Aşağıdaki belirtiler gerçek ya da olası bir InnoDB hasarına işaret edebilir:
- MySQL/MariaDB servisinin açılmaması veya açılışta tekrar kapanması.
- Hata günlüğünde
InnoDB: Database page corruption,Cannot find table,assertion failureya da okuma hataları görülmesi. - Belirli bir tablodaki sorguların hata vermesi, sunucunun takılması veya bağlantının kesilmesi.
CHECK TABLEya damysqlchecksonucunda hata alınması.- Beklenmeyen kapatma sonrası çökme kurtarmanın tamamlanamaması.
Önemli: InnoDB tablolar için klasik REPAIR TABLE komutunu çözüm olarak kullanmayın. Bu komut MyISAM ve bazı diğer motorlar içindir; InnoDB verisini güvenli biçimde onarmaz. InnoDB’de amaç, mümkün olan veriyi okumak, mantıksal yedek almak ve temiz veri dosyalarına geri dönmektir.
Hızlı teşhis özeti
- Uygulamadaki yazma trafiğini durdurun veya bakım moduna alın.
- Disk alanı, çekirdek I/O hataları ve MySQL/MariaDB hata günlüklerini kontrol edin.
- Servis çalışıyorsa etkilenen şema ve tabloyu
CHECK TABLEile belirleyin. - Önce erişilebilen verinin mantıksal dump’ını alın.
- Normal açılış mümkün değilse, yalnızca dump almak amacıyla düşük seviyeden başlayarak
innodb_force_recoverykullanın. - Yeni ve temiz bir veri dizininde veya ayrı bir kurtarma sunucusunda dump’ı geri yükleyin.
- Uygulama sorguları, tablo denetimleri ve hata günlükleriyle sonucu doğrulayın.
Olası nedenler ve ilk kontroller
| Olası neden | Tipik belirti | İlk güvenli işlem |
|---|---|---|
| Disk doluluğu veya dosya sistemi hatası | Yazma hataları, I/O error, servis kapanması | Alanı ve sistem günlüklerini inceleyin |
| Beklenmeyen kapanma | Açılışta uzun crash recovery | Servisin kurtarmayı tamamlamasına izin verin |
| Depolama veya sanallaştırma katmanı sorunu | Tekrarlayan I/O hataları, salt okunur dosya sistemi | Altyapı sağlığını doğrulayın, yazmaları kesin |
| Bozuk ikincil indeks veya sayfa | Belirli tabloda sorgu ya da tarama hatası | Dump alın, temiz ortamda geri yükleyin |
| Hatalı dosya kopyalama / eksik yedek | .ibd ve veri sözlüğü uyuşmazlıkları |
Tutarlı yedek veya özgün sunucuya dönün |
Sistem ve disk günlüklerini inceleyin
Önce boş alanı ve çekirdek mesajlarını kontrol edin. Kök dosya sistemi veya MySQL veri bölümünün dolu olması, kurtarma sürecini de başarısız kılabilir.
df -h
df -i
dmesg -T | tail -n 100
journalctl -k -b | tail -n 100
dmesg veya journalctl çıktısındaki I/O error, filesystem error, read-only filesystem ve disk sıfırlama kayıtları öncelikli altyapı sorunudur. Bu durumda veritabanını tekrar tekrar başlatmak yerine depolama katmanını inceleyin ve mümkünse blok düzeyinde bir kopya veya altyapı anlık görüntüsü alın.
MySQL veya MariaDB hata günlüğünü bulun
Günlük konumu dağıtıma ve kuruluma göre değişir. systemd kullanan sistemlerde en güvenilir ilk kaynak servis günlüğüdür:
systemctl status mysql --no-pager
journalctl -u mysql -b --no-pager | tail -n 200
# MariaDB servis adı kullanan dağıtımlarda
systemctl status mariadb --no-pager
journalctl -u mariadb -b --no-pager | tail -n 200
Servis ayarlarında tanımlı hata günlüğünü görmek için, servis çalışıyorsa aşağıdaki sorgu kullanılabilir:
mysql -u root -p -e "SHOW VARIABLES LIKE 'log_error';"
mysql -u root -p -e "SHOW VARIABLES LIKE 'datadir';"
Bu kontroller sırasında veri dizinindeki ibdata, ib_logfile* veya tabloya ait .ibd dosyalarını elle silmeyin, taşımayın ve başka bir sunucudan rastgele kopyalamayın. Dosya düzeyindeki tutarsız müdahaleler hasarı kalıcılaştırabilir.
InnoDB tablo bozulması nasıl kurtarılır: güvenli adımlar
1. Bakım penceresi ve geri dönüş noktası oluşturun
Bu işlemler veri kaybı riski taşır. Uygulama yazmalarını durdurun; kuyruk tüketicileri, cron görevleri ve entegrasyonların veritabanına yazmasını engelleyin. Ardından mevcut durumun geri dönüş noktasını alın. Sanal makine anlık görüntüsü tek başına veritabanı yedeği değildir; yine de depolama tutarlılığı doğrulandıysa ek koruma sağlayabilir. Tercih edilen yöntem, çalışan sistemden mantıksal yedek ve altyapı prosedürünüze uygun tutarlı yedektir.
Servis erişilebiliyorsa, önce kritik şemayı dışa aktarın. Aşağıdaki örnekte veritabani_adi kısmını kendi şemanızla değiştirin:
mysqldump -u root -p --quick --routines --events --triggers \
--databases veritabani_adi > /guvenli/yedek/yolunda/veritabani_adi.sql
Bozuk tablo, dump sırasında hataya neden oluyorsa sağlam tabloları önce ayrı ayrı veya seçili biçimde dışa aktarın. Kurtarma modunda alınan dump, tutarlı bir anlık görüntü garantisi vermeyebilir; bu nedenle uygulama yazmalarını kesmek kritik önem taşır.
2. Etkilenen tabloyu kontrol edin
Sunucu normal çalışıyorsa incelemeyi önce hedef tabloyla sınırlayın. Tablo ve şema adlarını ters tırnakla kullanın:
mysql -u root -p -e "CHECK TABLE \`veritabani_adi\`.\`tablo_adi\`;"
mysqlcheck -u root -p --check veritabani_adi tablo_adi
CHECK TABLE, sorunun varlığını gösterebilir ancak her InnoDB bozulmasını onaramaz veya her fiziksel hatayı yakalayamaz. Sonucu hata günlüğüyle birlikte değerlendirin. Servis açılıyor ve tablo okunabiliyorsa, öncelik onarım denemesi değil dışa aktarımdır.
3. Servis başlamıyorsa innodb_force_recovery ile yalnızca veri okuyun
innodb_force_recovery, bozuk sayfaları veya kurtarma adımlarını atlayarak sunucunun açılmasına yardımcı olabilen acil durum parametresidir. Bu bir onarım yöntemi değildir. Amaç, sunucuyu geçici olarak açıp dump almaktır. Değer yükseldikçe veri tutarsızlığı ve ek kayıp riski artar.
Önce servisi durdurun ve aktif yapılandırmanın yedeğini alın. Yapılandırma dosyasının konumu dağıtıma göre değişebilir; etkin dosyayı doğrulamak için servis tanımını inceleyin:
systemctl cat mysql
# veya
systemctl cat mariadb
MySQL/MariaDB sunucu yapılandırmasındaki [mysqld] bölümüne geçici olarak aşağıdaki satırı ekleyin:
[mysqld]
innodb_force_recovery=1
Servisi başlatın ve hata günlüğünü izleyin:
systemctl start mysql
journalctl -u mysql -f
MariaDB kullanan sistemlerde mysql yerine mariadb servis adını kullanın. Seviye 1 ile açılmazsa servisi durdurun, değeri yalnızca bir kademe artırın ve tekrar deneyin. 1’den 6’ya kadar değerler vardır; en düşük çalışan değer tercih edilmelidir. Seviye 4, 5 ve 6; işlem geri alma ve arka plan işlemlerini önemli ölçüde sınırlar, verinin mantıksal tutarlılığını etkileyebilir. Bu seviyelerde kesinlikle yazma, DDL veya tablo silme işlemi yapmayın.
Sunucu açılır açılmaz önce veri alın:
mysqldump -u root -p --quick --skip-lock-tables \
--routines --events --triggers --databases veritabani_adi \
> /guvenli/yedek/yolunda/veritabani_adi-kurtarma.sql
Tüm şema dump edilemiyorsa hata veren tabloyu belirleyin, sağlam tabloları dışa aktarın ve kritik tablodan mümkünse seçili veriyi alın. Örneğin yalnızca okunabilen kayıtları uygulama mantığınıza uygun sorgularla dışa aktarmak gerekebilir. Bu aşamada alınan her dump dosyasını boyut, hata çıktısı ve geri yükleme testi açısından ayrıca kontrol edin.
4. Temiz InnoDB ortamına geri yükleyin
Dump tamamlandıktan sonra geçici innodb_force_recovery satırını kaldırın. Bozuk üretim veri dizinini yerinde yeniden oluşturmaya çalışmak yerine, tercihen ayrı bir kurtarma sunucusu veya temiz hazırlanmış bir MySQL/MariaDB örneği kullanın. Hedef sunucuda kaynakla uyumlu ana sürüm ve mümkün olduğunca yakın sürüm tercih edin.
Yeni ortamda önce veritabanını oluşturup dump’ı içe aktarın. Dump --databases ile alındıysa oluşturma komutu dosyada bulunur:
mysql -u root -p < /guvenli/yedek/yolunda/veritabani_adi-kurtarma.sql
En güvenli alternatif, kurtarma planınıza uygun doğrulanmış fiziksel veya mantıksal yedekten dönmektir. Yedek, bozulma anından önceki sağlıklı noktaya aitse; eksik kayıtları uygulama günlükleri, ikincil kaynaklar veya sonradan alınan seçili dump ile uzlaştırın.
Geri yükleme sonrası doğrulama
Geri yükleme bittiğinde uygulama trafiğini açmadan önce tablo sayısını, temel sorguları ve hata günlüklerini kontrol edin:
mysql -u root -p -e "SHOW TABLES FROM \`veritabani_adi\`;"
mysqlcheck -u root -p --check veritabani_adi
mysql -u root -p -e "CHECK TABLE \`veritabani_adi\`.\`tablo_adi\`;"
journalctl -u mysql -b --no-pager | tail -n 100
Ardından uygulamanın kritik okuma sorgularını, kayıt oluşturma akışını ve varsa yabancı anahtar ilişkilerini kontrollü biçimde test edin. Test başarılıysa yazma trafiğini kademeli açın. Kurtarma parametresinin yapılandırmada kalmadığını ve servisin normal modda yeniden başladığını mutlaka doğrulayın.
Tekrarını önleme
- Mantıksal yedekleri düzenli alın; geri yükleme testlerini ayrı bir ortamda periyodik yapın.
- Disk doluluk, inode kullanımı, I/O hataları ve SMART/depolama alarmları için izleme kurun.
- Veritabanı sunucusunu güç kesintilerine karşı uygun altyapıyla koruyun; zorla kapatma ve kontrolsüz yeniden başlatmalardan kaçının.
- MySQL/MariaDB sürüm yükseltmelerini üretime almadan önce test edin; uyumlu yedek ve geri dönüş planı hazırlayın.
- Dosya seviyesinde kopyalama yapılacaksa, yalnızca veritabanına uygun tutarlı yedekleme prosedürlerini kullanın.
Sonuç
InnoDB tablo bozulması nasıl kurtarılır sorusunun güvenli yanıtı; REPAIR TABLE çalıştırmak değil, hasarın kaynağını doğrulamak, mümkün olan veriyi salt okunur yaklaşımla dump almak ve temiz bir InnoDB ortamına ya da doğrulanmış yedeğe dönmektir. Özellikle innodb_force_recovery geçici bir veri çıkarma aracıdır; normal çalışma ayarı değildir. Disk veya depolama hatısı devam ediyorsa, veritabanı kurtarılmış görünse bile kök neden çözülmeden üretim trafiği açılmamalıdır.
Sık sorulan sorular
InnoDB için REPAIR TABLE kullanılabilir mi?
Hayır. REPAIR TABLE, InnoDB bozulmasını güvenli biçimde onaran bir yöntem değildir. InnoDB için dump alma, temiz ortama geri yükleme veya doğrulanmış yedekten dönüş tercih edilir.
innodb_force_recovery veri kaybına neden olur mu?
Parametrenin kendisi veri onarımı yapmaz; yüksek seviyelerde bazı kurtarma işlemlerini atlayarak mantıksal tutarsızlığa yol açabilir. Bu nedenle yalnızca en düşük gerekli değerle, yazma yapmadan ve dump almak için kullanılmalıdır.
CHECK TABLE sonucu OK ise tablo kesinlikle sağlam mıdır?
Hayır. Sonuç yararlı bir göstergedir ancak tüm fiziksel depolama ve uygulama tutarlılığı sorunlarını kapsamaz. Hata günlüğü, disk sağlığı ve uygulama testleriyle birlikte değerlendirilmelidir.
Bozuk .ibd dosyasını başka sunucuya kopyalamak yeterli olur mu?
Genellikle hayır. InnoDB tabloları veri sözlüğü, tablolar alanı ve sürüm uyumluluğuna bağlıdır. Rastgele dosya kopyalama veri kaybını veya erişim sorunlarını artırabilir.