Baris hilang setelah konversi online dari MyISAM ke InnoDB


16

Kami memiliki basis data yang cukup kecil yang ingin kami konversi dari MyISAM ke InnoDB. Menjadi noobs basis data, kami baru saja mengkonversi (menggunakan tabel alter) bahkan tanpa menurunkan situs.

Sekarang setelah konversi selesai, banyak baris yang terputus-putus tampaknya hilang. Apakah ini mungkin karena operasi selama konversi? Atau apakah masalahnya di tempat lain?


Tabel mana yang tidak berisi baris? Yang Anda konversi atau tabel lainnya?
longneck

Jawaban:


20

Melakukan ALTER untuk mengubah mesin penyimpanan tidak akan membuat baris menghilang. Namun, izinkan saya menawarkan beberapa saran karena Anda mengatakan Anda 'noobs basis data' dalam pertanyaan Anda.

Saat memodifikasi skema yang ada atau melakukan apa pun yang dapat memengaruhi data, berikut adalah beberapa saran dasar:

  1. Buat cadangan terlebih dahulu.
  2. Miliki rencana perubahan.
  3. Uji paket Anda pada host offline.
  4. Memiliki rencana pengujian untuk membandingkan sebelum dan sesudah data.
  5. Jadwalkan dan luangkan waktu istirahat.
  6. Ambil cadangan dan snapshot segera setelah waktu henti Anda mulai berlaku dan Anda memverifikasi lalu lintas telah berhenti.
  7. Jika Anda menjalankan MYISAM, gunakan 'CHECK TABLE' untuk mengevaluasi apa yang Anda hadapi sebelum Anda ALTER.
  8. Salin tabel secara lokal di samping cadangan Anda, untuk berjaga-jaga.
  9. Lanjutkan dengan hati-hati, aktifkan "--show warning" dan output lainnya sehingga Anda memiliki gambaran lengkap saat Anda melakukan perubahan.
  10. Jika data penting bagi Anda, sewalah DBA, meskipun hanya untuk berkonsultasi selama migrasi sehingga Anda memiliki veteran berpengalaman di sisi Anda.

Mungkin ada banyak lagi yang bisa saya bahas, tetapi hal di atas akan memberi Anda opsi ketika ada masalah.

Sejauh data / baris Anda hilang, tidak ada cara untuk mengetahui dengan snapshot sebelum / sesudah "untuk membandingkan. Anda dapat membandingkan dengan cadangan terbaru Anda untuk setidaknya memverifikasi sebanyak itu.


Saya membaca ini. Rencana DR yang bagus. Jawaban Anda mendapat +1 karena lebih sensitif terhadap pertanyaan daripada saya selain rencana ke depan.
RolandoMySQLDBA

1
@randy Menandai ini sebagai pertanyaan favorit karena jawaban Anda yang bagus
techExplorer

8

Salah satu cara terbaik untuk mengonversi MyISAM ke InnoDB tanpa banyak waktu henti hanya memiliki satu prasyarat: Gunakan Replication Slave.

Berikut ini adalah pandangan sekilas dari rencana tersebut

  1. Buat Replication Master / Slave Setup
  2. Konversikan setiap tabel MyISAM pada slave ke InnoDB
  3. Arahkan aplikasi Anda ke Budak

Kedengarannya sederhana? Ada banyak detail di balik ini.

Buat Replication Master / Slave Setup

Ada cara yang cerdik untuk membuat Budak tanpa banyak gangguan pada Master. Saya menulis dua posting:

Daripada merinci cara menggunakan rsync, harap baca dua posting itu.

Konversikan setiap tabel MyISAM pada slave ke InnoDB

Pada DB Slave, Anda dapat Pernyataan SQL berikut:

Untuk MySQL 5.5:

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql','performance_schema');

Versi untuk MySQL sebelum MySQL 5.5

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql');

Menggunakan output dari kueri, Anda memiliki skrip konversi untuk budak.

Anda harus meletakkan dua baris ini di bagian atas skrip:

SET SQL_LOG_BIN = 0;
STOP SLAVE;

Script pertama-tama akan menonaktifkan logging biner (jika Anda mengkonfigurasi slave untuk memiliki log biner), menghentikan replikasi, dan mengonversi setiap tabel MyISAM ke InnoDB.

Berikut ini cara membuat skrip itu dan menjalankannya:

SQLSTMT="SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') FROM information_schema.tables WHERE engine = 'MyISAM' AND table_schema NOT IN ('information_schema','mysql','performance_schema')"
INNODB_CONV_SCRIPT=MassConvertMyISAMTablesToInnoDB.sql
echo "SET SQL_LOG_BIN = 0;" > ${INNODB_CONV_SCRIPT}
echo "STOP SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Master) -u... -p... --skip-column-names -A -e"${SQL}" >> ${INNODB_CONV_SCRIPT}
echo "START SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Slave) -u... -p... --skip-column-names -A < ${INNODB_CONV_SCRIPT}

Arahkan aplikasi Anda ke Budak

Lakukan kueri SELECT dari Slave. Jika Anda puas dengan konten data pada Slave, jangan ragu untuk mengarahkan aplikasi Anda ke slave sebagai berikut:

  1. Di Budak, jalankan SHOW SLAVE STATUS\Gdan pastikan Seconds_Behind_Master adalah 0
  2. Pada Slave, mysqldump -h (IP dari Slave) -u ... -p ... - transaksi tunggal --rutin --trigger --all-database> MySQLBackup.sql (Hei, cadangan akan bagus kan sekitar sekarang)
  3. Pada Master, jalankan service mysql stop(Downtime dimulai)
  4. Ulangi Langkah 1
  5. Arahkan aplikasi Anda ke Budak (Waktu Henti berakhir pada koneksi pertama aplikasi)

Jika Anda sampai pada titik ini tanpa cedera, SELAMAT !!!

BONUS TAMBAHAN : Jika Anda mengatur Master / Master Replication (alias Circular Replication) alih-alih Master / Slave, Anda dapat melakukan ini sebagai gantinya:

  1. Di Budak, jalankan SHOW SLAVE STATUS\Gdan pastikan Seconds_Behind_Master adalah 0
  2. Pada Slave, mysqldump -h (IP dari Slave) -u ... -p ... - transaksi tunggal --rutin --trigger --all-database> MySQLBackup.sql (Hei, cadangan akan bagus kan sekitar sekarang)
  3. Arahkan aplikasi Anda ke Budak (Waktu Henti dimulai dan berakhir pada koneksi pertama aplikasi)
  4. Pada Master baru, jalankan STOP SLAVE;
  5. Pada Master baru, jalankan CHANGE MASTER TO MASTER_HOST='';

Apa yang sekarang Anda miliki adalah Master / Slave secara terbalik. Master Baru memiliki data InnoDB dan Master lama sekarang menjadi budak dengan data MyISAM. Jika Anda membagi baca dan tulis, baca dapat pergi dari Slave (membaca lebih cepat dari MyISAM daripada InnoDB) dan menulis pergi ke Master (dukungan transaksional untuk InnoDB). Seperti Hannah Montana bernyanyi, Anda mendapatkan yang terbaik dari kedua dunia (Ya, saya punya dua anak perempuan yang suka pertunjukan) !!!

BONUS TAMBAH LAIN : Karena Master sekarang InnoDB, Anda dapat melakukan mysqldump dari Master tanpa downtime dan tanpa mengganggu transaksi. Hanya kekurangannya adalah meningkatkan CPU dan disk I / O. Oleh karena itu Anda bisa ke mysqldump struktur tabel hanya pada Master (InnoDB) dan mysqldump data hanya pada slave (dump tersebut tidak akan memiliki referensi ke InnoDB atau MyISAM. Itu hanya akan menjadi data) ditambah mysqldump dari struktur tabel untuk slave memiliki tata letak MyISAM.

Kemungkinan dapat berlanjut karena pengaturan baru ini ...

UPDATE 2011-08-27 19:50 EDT

Permintaan maaf saya. Saya tidak sepenuhnya membaca pertanyaan itu. Anda sudah melakukan konversi .

Hanya jika Anda sudah mengaktifkan pencatatan biner , dan Anda memiliki cadangan sebelumnya, Anda bisa

  • pulihkan / var / lib / mysql ke lokasi lain, seperti / var / lib / mysql2
  • Lari service mysql stop
  • Lari service mysql start --datadir=/var/lib/mysql2
  • mysqldump database dari cadangan itu ke /root/olddata.sql
  • jalankan mysqlbinlog terhadap semua log biner di / var / lib / mysql (bukan / var / lib / mysql2) dari titik waktu sejak cadangan terakhir ke /root/changes.sql
  • Muat perubahan.sql ke mysql (karena masih menunjuk ke / var / lib / mysql2)

Ini harus menangkap semua yang telah direkam dan konversi harus mulai. Sekali lagi, ini semua Anda harus sudah mengaktifkan pencatatan biner sebelum pencadangan terakhir . Kalau tidak, belasungkawa saya.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.