Mempercepat konversi MyISAM ke InnoDB

15

Saya punya server mysql 5.1 dengan database sekitar 450 tabel, mengambil 4GB. Sebagian besar dari tabel ini (semuanya kecuali 2) adalah MyIsam. Ini sebagian besar baik-baik saja (tidak perlu transaksi), tetapi aplikasi telah mendapatkan lalu lintas dan tabel tertentu telah terpengaruh karena penguncian tabel pada pembaruan. Itulah alasan 2 dari tabel tersebut adalah InnoDB sekarang.

Konversi pada tabel yang lebih kecil (baris 100rb) tidak butuh waktu lama, menyebabkan downtime minimal. Namun beberapa tabel pelacakan saya mendekati 50 juta baris. Apakah ada cara untuk mempercepat ALTER TABLE...ENGINE InnoDBdi meja besar? Dan jika tidak, adakah metode lain untuk mengonversi meminimalkan waktu henti pada tabel tulis-berat ini?

Derek Downey
sumber
1
Sesuatu yang perlu diingat: beberapa pertanyaan dalam satu posting cenderung membuat orang-orang yang bisa menjawab salah satu pertanyaan tidak memposting jawaban.
BenV
Saya VtC karena ini agak rumit untuk dijawab. Anda harus membuka beberapa pertanyaan secara terpisah.
jcolebrand
saya dengan senang hati akan mengambil saran untuk membuatnya menjadi satu pertanyaan, tetapi apakah disarankan untuk menghapus pertanyaan ini dan hanya membuka yang baru? penulisan ulang sebagian besar akan menghapus 2 peluru kedua dan mengubah yang pertama (saya memperbarui judul juga untuk mencerminkan mesin penyimpanan mana)
Derek Downey
Baik akan baik-baik saja. Biasanya lebih mudah menulis dua pertanyaan lain dan menghapus satu pertanyaan. Namun, Anda dapat dengan mudah meninggalkan yang satu ini untuk "referensi" dan meminta dua yang lain merujuknya kembali, sebagai pertanyaan "ini adalah tujuan keseluruhan saya".
jcolebrand
edit yang satu ini menjadi satu bullet, lalu posting pertanyaan selanjutnya.
Brian Ballsun-Stanton

Jawaban:

10

Biarkan saya mulai dengan mengatakan, saya benci ALTER. Itu jahat, IMHO.

Katakan, ini skema tabel Anda saat ini -

CREATE TABLE my_table_of_love (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
my_value VARCHAR(40),
date_created DATE,
PRIMARY KEY(id)
) ENGINE=MyISAM CHARSET=utf8;

Inilah jalan yang saya rekomendasikan -

Buat objek tabel baru yang akan menggantikan yang lama:

CREATE TABLE my_table_of_love_NEW (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
my_value VARCHAR(40),
date_created DATE,
PRIMARY KEY(id)
) ENGINE=InnoDB CHARSET=utf8

Masukkan semua baris dari tabel lama dengan nama ke tabel baru:

INSERT INTO my_table_of_love_NEW (id,my_value,date_created)
SELECT id,my_value,date_created FROM my_table_of_love;

Uji asap migrasi Anda:

SELECT COUNT(*) FROM my_table_of_love_NEW;
SELECT COUNT(*) FROM my_table_of_love;
SELECT a.id,a.my_value,a.date_created FROM my_table_of_love_NEW a
LEFT JOIN my_table_of_love b ON (b.id = a.id)
WHERE a.my_value != b.my_value;

Tukar nama tabel sehingga Anda dapat mempertahankan cadangan jika Anda perlu mengembalikan.

RENAME TABLE my_table_of_love TO my_table_of_love_OLD;
RENAME TABLE my_table_of_love_NEW TO my_table_of_love;

Lanjutkan ke pengujian regresi.

Pendekatan ini menjadi lebih dan lebih disukai dengan tabel dengan banyak indeks dan jutaan baris.

Pikiran?

randomx
sumber
1
Setuju ... meskipun jika ini sangat transaksional, Anda mungkin perlu menurunkan database saat melakukan ini. (tapi kemungkinan tabel alter akan memberi Anda periode waktu henti yang lebih lama)
Joe
Ya, saya pikir itu akan membutuhkan downtime untuk tabel yang lebih aktif. Saya harus menjalankan beberapa tes, tetapi mengapa ALTER TABLEperlu lebih dari INSERT INTO...SELECT50 juta baris?
Derek Downey
Tidak akan. Pada dasarnya MySQL melakukan secara internal persis seperti yang disarankan poster ini. Ini membuat salinan definisi dan meneteskan banyak beban ke dalam salinan.
Morgan Tocker
Saya suka metode ini karena melompati bagian "copy to tmp", yang bisa memakan waktu cukup lama untuk tabel besar.
Haluk
Biarkan saya tambahkan sekarang, bahwa di MySQL 5.7, ALTER jauh lebih cepat dan lebih mudah untuk mengatasinya.
randomx
7

1) Perlindungan kerugian adalah fungsi dari paranoia. Selalu buat cadangan. Jika Anda benar-benar paranoid, buat cadangan lalu pulihkan dari cadangan.

2) Halaman manual MySQL ini memiliki instruksi untuk mengonversi tipe tabel.

Cara tercepat untuk mengubah tabel ke InnoDB adalah dengan melakukan sisipan langsung ke tabel InnoDB. Yaitu, gunakan ALTER TABLE ... ENGINE = INNODB, atau buat tabel InnoDB kosong dengan definisi yang identik dan masukkan baris dengan INSERT INTO ... SELECT * FROM ....

3) PostgreSQL melakukan pencarian teks lengkap , The Sphinx Engine tampaknya melakukannya untuk MySQL

Brian Ballsun-Stanton
sumber
saya pasti akan melihat ke sphinx, karena saya baru saja mendengarnya.
Derek Downey
3

Ini X kali lebih mudah untuk mengoptimalkan seluruh server (konfigurasi memori, cache, indeks) ketika Anda hanya memiliki satu mesin yang digunakan. Memadukan myisam dengan innodb pada basis data besar akan selalu macet di beberapa titik yang dipaksakan oleh beberapa komproise agar kedua mesin bekerja dengan baik (tapi tidak unggul :)

Saya sarankan Anda untuk tertarik pada beberapa mesin pencari teks lengkap khusus seperti sphinx , lucene ( solr ) dan singkirkan dari lapisan basis data.

sbczk
sumber