Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Buat indeks pada tabel produksi MySQL besar tanpa penguncian tabel

[2017] Pembaruan:MySQL 5.6 memiliki dukungan untuk pembaruan indeks online

https://dev.mysql.com/doc/refman/8.0/en/innodb-online-ddl-operations.html#online-ddl-index-syntax-notes

Di MySQL 5.6 dan yang lebih tinggi, tabel tetap tersedia untuk operasi baca dan tulis saat indeks sedang dibuat atau dijatuhkan. Pernyataan CREATE INDEX atau DROP INDEX hanya selesai setelah semua transaksi yang mengakses tabel selesai, sehingga status awal indeks mencerminkan isi tabel yang paling baru. Sebelumnya, memodifikasi tabel saat indeks sedang dibuat atau dijatuhkan biasanya mengakibatkan kebuntuan yang membatalkan pernyataan INSERT, UPDATE, atau DELETE pada tabel.

[2015] Memperbarui indeks tabel memblokir penulisan di MySQL 5.5

Dari jawaban di atas:

"Jika Anda menggunakan versi yang lebih besar dari 5.1, indeks dibuat saat database online. Jadi jangan khawatir Anda tidak akan mengganggu penggunaan sistem produksi."

Ini ****FALSE**** (setidaknya untuk tabel MyISAM / InnoDB, yang digunakan 99,999% orang di luar sana. Edisi Cluster berbeda.)

Melakukan operasi UPDATE pada tabel akan BLOCK saat indeks sedang dibuat. MySQL benar-benar bodoh dalam hal ini (dan beberapa hal lainnya).

Skrip Tes:

(   
  for n in {1..50}; do
    #(time mysql -uroot -e 'select  * from website_development.users where id = 41225\G'>/dev/null) 2>&1 | grep real;
    (time mysql -uroot -e 'update website_development.users set bio="" where id = 41225\G'>/dev/null) 2>&1 | grep real;
  done
) | cat -n &
PID=$!
sleep 0.05
echo "Index Update - START"
mysql -uroot website_development -e 'alter table users add index ddopsonfu (last_name, email, first_name, confirmation_token, current_sign_in_ip);'
echo "Index Update - FINISH"
sleep 0.05
kill $PID
time mysql -uroot website_development -e 'drop index ddopsonfu on users;'

Server Saya (InnoDB):

Server version: 5.5.25a Source distribution

Keluaran (perhatikan bagaimana operasi ke-6 memblokir ~400 mdtk yang diperlukan untuk menyelesaikan pembaruan indeks):

 1  real    0m0.009s
 2  real    0m0.009s
 3  real    0m0.009s
 4  real    0m0.012s
 5  real    0m0.009s
Index Update - START
Index Update - FINISH
 6  real    0m0.388s
 7  real    0m0.009s
 8  real    0m0.009s
 9  real    0m0.009s
10  real    0m0.009s
11  real    0m0.009s

Vs operasi baca yang tidak memblokir (tukar komentar baris dalam skrip):

 1  real    0m0.010s
 2  real    0m0.009s
 3  real    0m0.009s
 4  real    0m0.010s
 5  real    0m0.009s
Index Update - START
 6  real    0m0.010s
 7  real    0m0.010s
 8  real    0m0.011s
 9  real    0m0.010s
...
41  real    0m0.009s
42  real    0m0.010s
43  real    0m0.009s
Index Update - FINISH
44  real    0m0.012s
45  real    0m0.009s
46  real    0m0.009s
47  real    0m0.010s
48  real    0m0.009s

Memperbarui Skema MySQL tanpa downtime

Sejauh ini, hanya ada satu metode yang saya ketahui untuk memperbarui skema MySql dan tidak mengalami gangguan ketersediaan. Master melingkar:

  • Master A menjalankan database MySQL Anda
  • Membawa Master B ke dalam layanan dan membuatnya meniru penulisan dari Master A ( B adalah budak dari A)
  • Lakukan pembaruan skema pada Master B. Ini akan tertinggal selama peningkatan
  • Biarkan Master B menyusul. Invarian:Perubahan skema Anda HARUS mampu memproses perintah yang direplikasi dari skema downversion. Perubahan pengindeksan memenuhi syarat. Penambahan kolom sederhana biasanya memenuhi syarat. Menghapus kolom? mungkin tidak.
  • secara ATOMIS menukar semua klien dari Master A ke Master B. Jika Anda ingin aman (percayalah, Anda melakukannya), Anda harus memastikan bahwa penulisan terakhir ke A direplikasi ke B SEBELUM B melakukan penulisan pertamanya. Jika Anda mengizinkan penulisan serentak ke 2+ master, ... Anda lebih memahami replikasi MySQL pada tingkat DEEP atau Anda menuju dunia yang menyakitkan. Rasa sakit yang luar biasa. Seperti, apakah Anda memiliki kolom yang AUTOINCREMENT??? Anda kacau (kecuali jika Anda menggunakan angka genap pada satu master dan odds di sisi lain). JANGAN percaya replikasi MySQL untuk "melakukan hal yang benar". Ini TIDAK pintar dan tidak akan menyelamatkan Anda. Ini hanya sedikit kurang aman daripada menyalin log transaksi biner dari baris perintah dan memutar ulang dengan tangan. Namun, memutuskan semua klien dari master lama dan mengembalikannya ke master baru dapat dilakukan dalam hitungan detik, jauh lebih cepat daripada menunggu upgrade skema beberapa jam.
  • Sekarang Master B adalah master baru Anda. Anda memiliki skema baru. Hidup itu baik. Minum bir; yang terburuk sudah berakhir.
  • Ulangi proses dengan Master A, perbarui skemanya sehingga ia menjadi master sekunder Anda yang baru, siap untuk mengambil alih jika master utama Anda (master B sekarang) kehilangan kekuatan atau hanya berdiri dan mati pada Anda.

Cara mudah untuk memperbarui skema ini bukan. Dapat diterapkan dalam lingkungan produksi yang serius; ya itu. Tolong, tolong, tolong, jika ada cara yang lebih mudah untuk menambahkan indeks ke tabel MySQL tanpa memblokir penulisan, beri tahu saya.

Googling membawa saya ke artikel ini yang menjelaskan teknik serupa. Bahkan lebih baik, mereka menyarankan minum pada titik yang sama dalam prosedur (Perhatikan bahwa saya menulis jawaban saya sebelum membaca artikel)!

pt-online-schema-change dari Percona

artikel Saya menautkan pembicaraan di atas tentang alat, pt -perubahan-skema-online , yang berfungsi sebagai berikut:

  • Buat tabel baru dengan struktur yang sama seperti aslinya.
  • Perbarui skema pada tabel baru.
  • Tambahkan pemicu pada tabel asli agar perubahan tetap sinkron dengan salinan
  • Salin baris dalam kumpulan dari tabel asli.
  • Pindahkan tabel asli dan ganti dengan tabel baru.
  • Jatuhkan meja lama.

Saya sendiri belum pernah mencoba alat itu. YMMV

RDS

Saat ini saya menggunakan MySQL melalui RDS Amazon . Ini adalah layanan yang sangat bagus yang membungkus dan mengelola MySQL, memungkinkan Anda menambahkan replika baca baru dengan satu tombol dan secara transparan memutakhirkan database di seluruh SKU perangkat keras. Ini sangat nyaman. Anda tidak mendapatkan akses SUPER ke database, jadi Anda tidak dapat mengacaukan replikasi secara langsung (apakah ini berkah atau kutukan?). Namun, Anda dapat menggunakan Baca Promosi Replika untuk membuat skema Anda berubah pada budak hanya-baca, kemudian promosikan budak itu menjadi master baru Anda. Trik yang sama persis seperti yang saya jelaskan di atas, hanya jauh lebih mudah untuk dieksekusi. Mereka masih tidak berbuat banyak untuk membantu Anda dengan cut-over. Anda harus mengonfigurasi ulang dan memulai ulang aplikasi Anda.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ketidakcocokan MySQL PHP

  2. JSON_VALID() – Tes untuk JSON yang Valid di MySQL

  3. MySQL:Tidak dapat membuat tabel (errno:150)

  4. Pendekatan sharding MySQL?

  5. Menggunakan Suka Di MySQL untuk Operasi Pencarian Menggunakan Pola