Bagaimana Anda mengidentifikasi korupsi tabel InnoDB?

24

Saya memiliki beberapa tabel yang dipartisi dan memiliki beberapa indeks pada budak yang direplikasi. Setelah menyalin snap shot (diverifikasi aman) ke budak baru dan meningkatkan mysqld dari 5.1.42 ke 5.5.15 dan memulai kembali replikasi, saya mendapatkan InnoDB crash dengan pesan kesalahan "Invalid pointer ..."

Kesalahan ini terjadi di 2 server dengan perangkat keras dan O / S yang berbeda. Setelah berlari:

ALTER TABLE .... COALESCE PARTION n;

masalahnya hilang untuk tabel itu.

Namun, pertanyaan saya lebih besar cakupannya, dan itu adalah "Bagaimana Anda mengidentifikasi tabel InnoDB korupsi?" atau diulang lagi "Bagaimana Anda menilai kesehatan tabel InnoDB?" Apakah "PERIKSA TABEL" satu-satunya alat yang tersedia untuk mengidentifikasi masalah sebelum kecelakaan?

Tidak yakin apakah itu penting, tetapi crash terjadi berjalan: Versi: '5.5.15-55-log' socket: '/opt/mysql.sock' port: 3306 Server Percona (GPL), Rilis rel21.0, Revisi 158

randomx
sumber
2
Hai Randy! Saya pikir tanggapan di sini kredibel - InnoDB mengidentifikasi korupsi sendiri. Mungkin Anda harus mengulangi pertanyaan Anda, mengapa apa yang Anda lakukan menyebabkan InnoDB menjadi korup?
Morgan Tocker

Jawaban:

18

Morgan memberi petunjuk dalam komentarnya bahwa InnoDB terus-menerus memeriksa halaman yang rusak dengan melakukan checksum pada halaman yang dibacanya. Jika InnoDB menemukan ketidakcocokan checksum, itu akan crash menghentikan server.

Jika Anda ingin mempercepat proses itu (alih-alih menunggu InnoDB membaca halaman yang rusak), Anda dapat menggunakan innochecksum:

Karena ketidakcocokan checksum akan menyebabkan InnoDB sengaja mematikan server yang sedang berjalan, lebih baik menggunakan alat ini daripada menunggu server dalam penggunaan produksi menemukan halaman yang rusak.

Peringatan yang menarik:

innochecksum tidak dapat digunakan pada file tablespace yang sudah dibuka oleh server. Untuk file seperti itu, Anda harus menggunakan CHECK TABLE untuk memeriksa tabel dalam tablespace.

Jadi ya, untuk tabel online CHECK TABLEmungkin adalah alat (atau seperti yang ditunjukkan dalam jawaban lain mysqlcheck jika Anda ingin melakukan lebih dari satu database sekaligus).

Jika Anda dapat mematikan basis data Anda, Anda dapat memaksanya menggunakan checksum innochecksum

Anekdotal: Pada tablespace innodb 29GB (dengan innodb_file_per_table=1), skrip ini memakan waktu sekitar 2 menit

#!/bin/bash
for i in $(ls /var/lib/mysql/*/*.ibd)
do
  innochecksum -v $i
done

Sebagai bonus, karena Anda menjalankan Percona, mereka menerapkan metode baru untuk checksum innodb cepat . Saya tidak pernah menggunakannya, tetapi mungkin mempercepat prosesnya.

Derek Downey
sumber
1
Akan mencobanya di sini, sepertinya solusi @randymelder sedang mencari +1
marcio
2
Percona server memiliki beberapa fitur bagus lainnya. Lihat innodb_corrupt_table_action percona.com/doc/percona-server/5.5/randalan/… (!!)
Morgan Tocker
@Dest: innochecksum adalah cara untuk pergi. Yang satu ini adalah penjaga. 1 !!!
RolandoMySQLDBA
@Dest: Angkat topi hari ini untukmu !!!!
RolandoMySQLDBA
@MorganTocker menarik. Akan harus mendapatkan vakum pengetahuan saya dan melakukan penelitian ke Percona
Derek Downey
6

PERINGATAN: sebelum mencoba salah satu instruksi ini, sangat disarankan untuk memverifikasi bahwa ada cadangan yang sehat dari database Anda di tangan, untuk berjaga-jaga. (terima kasih kepada @Nick untuk peringatannya)

Coba gunakan mysqlcheckperintah. Di terminal:

mysqlcheck -u username -p --databases database1 database2

Perintah ini akan menampilkan daftar semua tabel dan status yang memberi tahu Anda jika ada beberapa jenis korupsi:

table1  OK
table2  OK
table3  OK
tableN  OK

Dengan itu di tangan Anda sudah tahu tabel mana yang harus Anda perbaiki. Untuk berjaga-jaga jika Anda ingin memperbaiki semuanya sekaligus:

mysqlcheck -u username -p --auto-repair --databases database1 database2 

Lebih lanjut tentang mysqlcheck: http://dev.mysql.com/doc/refman/5.0/id/mysqlcheck.html

Catatan: Anda menandai pertanyaan Anda dengan . Saya tidak tahu apa itu, jadi saya mencari di Google. Tampaknya menjadi garpu dari MySQL, tapi saya tidak punya alasan untuk percaya bahwa perintahnya tidak kompatibel (semoga saja).


Seseorang menunjuk saya ke panduan ini yang memiliki instruksi lebih spesifik untuk pemulihan database InnoDB untuk situasi yang lebih kritis di mana seluruh database tidak dimulai: http://www.softwareprojects.com/resources/programming/t-how-to-fix-mysql -database-myisam-innodb-1634.html

marcio
sumber
1
mysqlcheck adalah sinonim untuk 'check table ...' -1
randomx
Tidak benar. Pertama, mysqlcheck adalah utilitas baris perintah dan PERIKSA TABEL adalah pernyataan SQL (seperti membandingkan jeruk dengan lemon). Juga, Anda TIDAK BISA memeriksa seluruh database dengan LIHAT TABEL tanpa menyertakan SEMUA nama tabel dalam pernyataan SQL ( itu tidak akan terlalu produktif)
marcio
Dan mysqlcheck memiliki opsi untuk --memperbaiki tabel yang rusak sementara PERIKSA TABEL hanya memeriksa apakah tabel rusak atau tidak, tetapi tidak dapat melakukan perbaikan.
marcio
2
@randymelder - Anda salah mengatakan mysqlcheck adalah sinonim untuk CHECK TABLE. Dokumentasi Anda terhubung ke negara-negara: " mysqlcheckmenggunakan pernyataan SQL CHECK TABLE, REPAIR TABLE, ANALYZE TABLE, dan OPTIMIZE TABLEdengan cara yang nyaman bagi pengguna Ini menentukan pernyataan untuk digunakan untuk operasi Anda ingin melakukan, dan kemudian mengirimkan laporan ke server untuk dieksekusi.. " Itu bukan sinonim; itu adalah antarmuka pengguna ke kumpulan pernyataan.
Nick Chammas
6

Menurut Panduan Studi Sertifikasi MySQL 5.0, Bagian 30.4 :

Anda dapat memeriksa tabel InnoDB dengan menggunakan perintah CHECK TABLE atau menggunakan program klien untuk mengeluarkan pernyataan untuk Anda. Namun, jika tabel InnoDB memiliki masalah, Anda tidak dapat memperbaikinya dengan menggunakan REPAIR TABLE karena pernyataan itu hanya berlaku untuk MyISAM.

Jika pemeriksaan tabel menunjukkan bahwa tabel InnoDB memiliki masalah, Anda harus dapat mengembalikan tabel ke kondisi yang konsisten dengan membuangnya dengan mysqldump, menjatuhkannya, dan membuatnya kembali dari dump itu.

Jika terjadi crash pada Server MySQL atau pada host yang menjalankannya, beberapa tabel InnoDB mungkin perlu diperbaiki. Biasanya, cukup untuk me-restart server karena mesin penyimpanan InnoDB melakukan pemulihan otomatis sebagai bagian dari urutan startup-nya. Dalam kasus yang jarang terjadi, server mungkin tidak memulai karena kegagalan pemulihan otomatis InnoDB. Jika itu terjadi, gunakan prosedur berikut:

  • Mulai ulang server dengan opsi --innodb_force_recovery diatur ke nilai dalam kemarahan dari 1 menjadi 6. Nilai-nilai ini menunjukkan peningkatan tingkat kehati-hatian dalam menghindari kecelakaan, dan peningkatan tingkat toleransi untuk kemungkinan inkonsistensi dalam tabel yang dipulihkan. Nilai yang baik untuk memulai adalah 4.

  • Ketika Anda memulai server dengan --innodb_force_recovery diatur ke nilai non-nol, InnoDB memperlakukan tablespace sebagai read-only. Akibatnya, Anda harus membuang tabel InnoDB dengan mysqldump dan kemudian menjatuhkannya saat opsi berlaku. Kemudian restart server tanpa opsi --innodb_force_recovery. Ketika server muncul, pulihkan tabel InnoDB dari file dump.

  • Jika langkah-langkah sebelumnya gagal, perlu untuk mengembalikan tabel InnoDB dari cadangan sebelumnya.

Silakan baca MySQL Docs di InnoDB Forced Recovery  

RolandoMySQLDBA
sumber
3
FWIW, panduan sertifikasi memiliki jawaban yang sangat benar secara politis :) Jika Anda MEMERIKSA TABEL di tabel InnoDB dan sebenarnya korup, itu tidak akan pernah kembali sebagai "korup", itu akan crash server. Pernyataan ini hampir usang di InnoDB, karena setiap kali Anda membaca halaman InnoDB itu memeriksa korupsi (melalui halaman checksum).
Morgan Tocker
2

Saya ingin tahu apa yang terjadi jika ada yang menggunakan data InnoDB yang dibuat melalui Plugin InnoDB dan kemudian beralih ke versi lain dari InnoDB. Itu bisa membuat kemungkinan halaman rusak di mata mysqld.

Perhatikan apa yang dikatakan oleh Dokumentasi MySQL tentang Format File InnoDB tentang kemungkinan ini:

Secara umum, versi InnoDB yang lebih baru dapat membuat tabel atau indeks yang tidak dapat dengan aman dibaca atau ditulis dengan versi InnoDB sebelumnya tanpa risiko crash, hang, hasil yang salah atau korupsi. Plugin InnoDB memperkenalkan mekanisme baru untuk menjaga dari kondisi ini, dan untuk membantu menjaga kompatibilitas antara file database dan versi InnoDB.

Saya akan memo data pada budak. Bahkan, saya hanya akan menggunakan kekerasan dengan mendapatkan dump logis (mysqldump) dari data:

  • Jatuhkan semua basis data menggunakan InnoDB pada slave
  • Matikan mysql pada slave
  • ibdata1 Delete, ib_logfile0, dan ib_logfile1 pada budak
  • Mulai mysql pada budak, membiarkan ibdata1, ib_logfile0, dan ib_logfile1 diciptakan kembali
  • mysqldump data dari master ke slave

anwser asli saya diposting dianggap 'jadul'. Namun, dalam hal ini, saya pasti akan melihat ke dalam format file yang digunakan oleh .ibd dan / atau ibdata1.

RolandoMySQLDBA
sumber