apakah mungkin (dan bagaimana) untuk mengubah tabel MyISAM yang besar menjadi InnoDB tanpa menjadikan aplikasi offline. Perlu memasukkan beberapa baris ke dalam tabel itu setiap detik tetapi dimungkinkan untuk menangguhkannya selama sekitar 2 menit.
Jelas ALTER TABLE ... engine = innodb tidak akan berfungsi. Karenanya saya punya rencana untuk membuat tabel baru dengan mesin innodb dan menyalin konten ke dalamnya. Dan pada akhirnya, tunda thread log aplikasi dan RENAME TABLE.
Sayangnya bahkan melakukan penyalinan dalam batch kecil 100 baris menghasilkan kelambatan yang signifikan setelah beberapa waktu.
Sunting : Baris yang ada tidak pernah diubah, tabel ini digunakan untuk pencatatan.
Jawaban:
Buat pengaturan Master-Master sebagai berikut:
logTable
logTable_new
sebagai innodbINSERT INTO logTable_new SELECT * FROM logTable
(psuedocode) pada MasterB, yang mengirimkan replikasi ke MasterAlogTable_new
pada MasterA selesai menyinkronkan, tukar tabel tersebutsumber
Mengingat kendala:
Saat Anda melakukan pencatatan, jika Anda memiliki beberapa cara yang baik untuk mengatur penanda sehingga Anda dapat mengetahui apa yang Anda mulai prosesnya, sehingga Anda kemudian dapat menerapkan kembali log apa pun, atau meminta log dituliskan ke file teks sehingga nanti Anda bisa menelannya
LOAD DATA INFILE
Sebagian dari masalahnya adalah bahwa menulis dalam batch yang lebih kecil berarti bahwa indeks harus dihitung ulang berulang kali; Anda lebih baik menjalankannya sekaligus, tetapi ini mungkin menyebabkan kelambatan 'yang terlihat' pada sistem .. tetapi Anda tidak harus melakukannya di server produksi Anda.
LOAD DATA INFILE
)sumber
Apakah Anda menambahkan penundaan antara setiap batch, atau hanya menumpuk pembaruan dan menjalankan setiap batch langsung setelah yang sebelumnya?
Jika demikian maka cobalah skrip konversi dalam bahasa favorit Anda dengan sesuatu seperti:
Ini harus memastikan bahwa konversi tidak memakan lebih dari atau kurang dari setengah kapasitas server Anda, bahkan memungkinkan perbedaan beban yang dikenakan karena penggunaan sistem bervariasi sesuai waktu.
Atau jika Anda ingin menggunakan waktu sebanyak mungkin ketika layanan ini relatif tidak digunakan tetapi mundur (berpotensi berhenti untuk waktu yang cukup lama) ketika database perlu melakukan beberapa pekerjaan untuk para penggunanya, ganti
sleep for as long as the update took
denganif the server's load is above <upper measure>, sleep for some seconds then check again, loop around the sleep/check until the load drops below <lower measure>
. Ini berarti ia dapat bergerak maju dalam waktu tenang tetapi akan berhenti sepenuhnya ketika server sedang sibuk melakukan itu beban kerja normal. Menentukan beban akan bergantung pada OS Anda - di Linux dan sejenisnya, nilai rata-rata beban 1 menit dari/proc/loadavg
atau keluaran yanguptime
seharusnya dilakukan.<lower measure>
dan<upper measure>
mungkin nilainya sama, meskipun biasanya pada kontrol seperti ini memiliki perbedaan sehingga proses Anda tidak terus berjalan maka segera berhenti karena memulai kembali sendiri memiliki pengaruh pada ukuran beban.Tentu saja ini tidak akan berfungsi untuk tabel di mana baris lama dapat dimodifikasi, tetapi akan berfungsi dengan baik untuk tabel log seperti yang Anda gambarkan.
Anda akan ingin mengabaikan kebijaksanaan membuat indeks setelah mengisi tabel baru dalam kasus ini. Walaupun hal itu memang lebih efisien ketika Anda ingin segala sesuatunya menjadi secepat mungkin (efeknya pada sistem yang lain terkutuk), dalam hal ini Anda tidak ingin beban yang besar pada akhir proses sebagai indeks dibuat sepenuhnya dalam sekali jalan karena ini adalah proses yang tidak dapat Anda hentikan saat segala sesuatunya menjadi sibuk.
sumber
Apakah sesuatu seperti ini berfungsi?
$auto_increment
tabel pencatatanmytable
Anda tidak berubah).$auto_increment
nilainya menggunakanSHOW TABLE STATUS LIKE 'mytable'
.CREATE TABLE mytable_new LIKE mytable
ALTER TABLE mytable_new AUTO_INCREMENT=$auto_increment ENGINE=Innodb
RENAME TABLE mytable TO mytable_old, mytable_new TO mytable
INSERT INTO mytable SELECT * FROM mytable_old
.Anda dapat melakukan langkah 7 dalam batch atau dalam satu pernyataan karena seharusnya tidak memblokir ke pencatatan normal.
sumber