Mungkinkah membuat MySQL menggunakan lebih dari satu inti?

131

Saya telah disajikan dengan beberapa server MySQL khusus yang tidak pernah menggunakan lebih dari satu inti. Saya lebih pengembang daripada DBA untuk MySQL jadi butuh bantuan

Mempersiapkan

Server-servernya lumayan kuat dengan jenis beban OLAP / DataWarehouse (DW):

  • Utama: RAM 96GB, 8 core + satu array RAID 10
  • Tes: RAM 32GB dengan 4 core
  • DB terbesar adalah 540 GB, totalnya sekitar 1.1TB dan sebagian besar tabel InnoDB
  • Solaris 10 Intel-64
  • MySQL 5.5.x

Catatan: DB terbesar adalah yang direplikasi dari server OLTP DR dan DW dimuat dari ini. Ini bukan DW lengkap: hanya bertahan 6 bulan hingga 6 minggu sehingga lebih kecil dari OLTP DB.

Pengamatan pada server uji

  • 3 koneksi terpisah
  • masing-masing memiliki bersamaan (dan berbeda) ALTER TABLE...DROP KEY...ADD INDEX
  • 3 tabel memiliki baris 2,5, 3,8 dan 4,5 juta
  • Penggunaan CPU meningkat hingga 25% (satu inti sudah maksimal) dan tidak lebih tinggi
  • 3 ALTER memakan waktu 12-25 menit (satu untuk yang terkecil membutuhkan 4,5)

Pertanyaan

  1. Pengaturan atau tambalan apa yang diperlukan untuk memungkinkan lebih dari satu inti digunakan?
    Artinya, mengapa MySQL tidak menggunakan semua core yang tersedia? (seperti RDBMS lainnya)
  2. Apakah ini konsekuensi dari replikasi?

Catatan lain

  • Saya mengerti perbedaan antara "utas" RDBMS dan "utas" OS
  • Saya tidak bertanya tentang segala bentuk paralelisme
  • Beberapa variabel sistem untuk InnoDB dan utas bersifat kurang optimal
    (mencari kemenangan cepat)
  • Jangka pendek, saya tidak dapat mengubah tata letak disk
  • OS dapat di-tweak jika perlu
  • Satu ALTER TABLE di meja terkecil membutuhkan waktu 4,5 menit (IMO mengejutkan)

Edit 1

  • innodb_thread_concurrency diatur ke 8 pada keduanya. Ya, itu salah tetapi tidak akan membuat MySQL menggunakan banyak core
  • innodb_buffer_pool_size adalah 80GB pada primer, 10GB pada tes (contoh lain dimatikan). Ini OK untuk saat ini.
  • innodb_file_per_table = ON

Edit 2

Untuk menguji

  • innodb_flush_method tidak ditampilkan sebagai O_DIRECT kapan seharusnya
  • akan mengikuti pengaturan RolandoMySQLDBA

Beri tahu saya jika saya melewatkan sesuatu yang penting

Tepuk tangan

Memperbarui

Mengubah innodb_flush_method + 3 x pengaturan ulir dalam jawaban RolandoMySQLDBA
Hasil:> 1 inti digunakan untuk pengujian = hasil positif

gbn
sumber
@Dest: innodb_file_per_table = ON. SHOW ENGINE INNODB STATUS \ G adalah hanya command line?
gbn
@ Percobaan: Saya tidak mendapatkan output dalam SQLyog dan perlu meminta seseorang untuk menjalankan ini dari command line
gbn
1
webyog.com/forums/index.php?showtopic=1290 seharusnya berfungsi tanpa \G. Juga, saya pikir SHOW INNODB STATUSsudah usang mendukung SHOW ENGINE INNODB STATUSdi 5,5 (saya mendapatkan kesalahan menjalankan mantan di command-line.
Derek Downey
1
Meskipun semua jawaban lain baik, karena Anda adalah seorang pengembang, saya akan merekomendasikan untuk melihat kode Shard Query.google.com/p/shard-query. Ini dapat membantu Anda, terutama di lingkungan datawarehouse.
Jonathan
Terima kasih, ini adalah salah satu opsi yang kami pikirkan. Saya = m juga mengambil peran DBA juga.
gbn

Jawaban:

123

Saya benar-benar membahas innodb_thread_concurrency dengan Ahli MySQL di konferensi NYC Percona Live pada Mei 2011 .

Saya belajar sesuatu yang mengejutkan: Terlepas dari dokumentasinya, yang terbaik adalah meninggalkan innodb_thread_concurrencypada 0 (infinite concurrency). Dengan begitu, InnoDB memutuskan jumlah terbaik innodb_concurrency_ticketsuntuk membuka untuk pengaturan instance MySQL yang diberikan.

Setelah Anda menetapkan innodb_thread_concurrencyke 0, Anda dapat mengatur innodb_read_io_threadsdan innodb_write_io_threads(keduanya sejak MySQL 5.1.38) ke nilai maksimum 64. Ini harus melibatkan lebih banyak core.

RolandoMySQLDBA
sumber
Akan coba ini. Saya akan menetapkan Innodb_thread_concurrency ke 0 berdasarkan pada hal-hal yang saya baca juga
gbn
9
+1 untuk innodb_thread_concurrency = 0
randomx
3
@ gbn - Berasal dari pria # 1 di DBA.SE, terima kasih adalah pendongkrak kepercayaan diri dan sangat dihargai. Terima kasih dan sama-sama !!!
RolandoMySQLDBA
atur global innodb_read_io_threads = 8 Kode Kesalahan: 1238. Variabel 'innodb_read_io_threads' adalah variabel hanya baca
wgq3g23g
2
@ wgq3g23g Jika Anda melakukan RDS, ubah itu di Grup Parameter DB dan reboot instance. Jika Anda melakukan EC2 atau bare metal, tambahkan opsi itu untuk my.cnfdan restart mysqld. silahkan.
RolandoMySQLDBA
29

MySQL akan secara otomatis menggunakan banyak inti, sehingga beban Anda sebesar 25% adalah kebetulan 1 atau kemungkinan kesalahan konfigurasi pada Solaris. Saya tidak akan berpura-pura tahu cara menyetem solaris, tapi di sini ada artikel yang membahas beberapa informasi penyetelan khusus solaris .

Halaman tuning InnoDB telah dirombak di MySQL 5.5, jadi ada beberapa info bagus di sana. Dari tips IO disk InnoDB :

Jika alat teratas Unix atau Windows Task Manager menunjukkan bahwa persentase penggunaan CPU dengan beban kerja Anda kurang dari 70%, beban kerja Anda mungkin terikat dengan disk. Mungkin Anda membuat terlalu banyak komitmen transaksi, atau buffer pool terlalu kecil. Membuat kolam penyangga lebih besar dapat membantu, tetapi jangan atur sama dengan lebih dari 80% memori fisik.

Beberapa hal lain yang perlu diperiksa:

  • Mengalihkan innodb_flush_method ke O_DIRECT layak untuk diuji. Jika ini membantu, Anda mungkin perlu me-mount sistem file dengan forcedirectioopsi

  • Ubah innodb_flush_log_at_trx_commit dari 1 menjadi 0 (jika Anda tidak keberatan kehilangan detik terakhir pada mysql crash) atau 2 (jika Anda tidak keberatan kehilangan detik terakhir pada OS crash).

  • Periksa nilai innodb_use_sys_malloc . Artikel ini memiliki informasi lebih lanjut tentang variabel.

    Pada saat itu, tidak ada perpustakaan pengalokasi memori yang disetel untuk CPU multi-core. Oleh karena itu, InnoDB mengimplementasikan pengalokasi memorinya sendiri dalam subsistem mem. Pengalokasi ini dijaga oleh satu mutex, yang dapat menjadi hambatan.

    Tetapi ada beberapa peringatan di akhir bagian tentang apa artinya menghidupkan variabel (diaktifkan secara default di 5.5).

    Perhatikan bahwa ketika pengalokasi memori InnoDB dinonaktifkan, InnoDB akan mengabaikan nilai parameter innodb_additional_mem_pool_size.

  • Ada kemungkinan bahwa replikasi menyebabkan beberapa masalah. Saya menyadari Anda tidak tertarik dengan paralelisme, tetapi dari deskripsi worklog ini :

    Saat ini, replikasi tidak skala dengan baik pada mesin multi-core. Single slave thread mengeksekusi peristiwa replikasi satu per satu dan mungkin tidak mengatasi beban yang dihasilkan oleh beberapa koneksi klien bersamaan yang dilayani oleh CPU server master terpisah.

Pada akhirnya, InnoDB mungkin bukan mesin terbaik untuk penyimpanan dataware, karena operasi berbasis disk yang terjadi. Anda dapat mempertimbangkan mengubah tabel datawarehouse menjadi Compressed MyISAM .

1 Secara kebetulan, maksud saya ada bottleneck yang mencegah beban Anda meningkat di atas 25%, tetapi tidak selalu merupakan masalah inti tunggal yang dipaksakan.

Derek Downey
sumber
Terima kasih. Bagian pengaturan ditambahkan ke pertanyaan. Masalahnya adalah beberapa pertanyaan intensif menggunakan inti tunggal: belum pengaturan memori atau utas. Lebih banyak utas masih berjalan pada inti yang sama
gbn
@ GBN terima kasih untuk pembaruannya, masih mencari. Saya berpikir itu adalah 'kebetulan'. Saya ingin tahu apakah ini masalah solaris saja ( developers.sun.com/solaris/articles/mysql_perf_tune.html ), tetapi tidak tahu banyak tentang sistem itu.
Derek Downey
1
@Dest: Saya akan membuang artikel itu ke admin Solaris juga. Beberapa hal bagus di sana
gbn
1
Sekarang, replikasi adalah (opsional) multi-threaded pada Slave. InnoDB telah membaik sejak Jawaban ini ditulis. Saya tidak akan menyarankan menggunakan MyISAM, terutama jika tidak dikompresi.
Rick James
15

Koneksi tunggal hanya akan menggunakan inti tunggal. (Oke, InnoDB menggunakan utas lain, karenanya inti, untuk beberapa pemrosesan I / O, tetapi itu tidak signifikan.)

Anda memiliki 3 ALTER, jadi Anda tidak menggunakan nilai lebih dari 3 inti.

Sayangnya, bahkan PARTISI tidak menggunakan banyak core.

Sampai saat ini, banyak koneksi akan maksimal setelah 4-8 core. Xtradb Percona (termasuk dalam MariaDB) lebih baik menggunakan banyak core, tetapi masih hanya satu per thread. Mereka maksimal sekitar 32 core.

Rick James
sumber
(Pembaruan pada tahun 2015 :) Beberapa koneksi dengan 5,6 maxes sekitar 48 core. 5.7 berjanji untuk menjadi lebih baik. (Demikian kata tolok ukur Oracle.) Tetapi masih tidak menggunakan beberapa core untuk satu koneksi.
Rick James
Pembaruan (setelah pergi ke OpenWorld Oracle): versi baru 8.x tidak akan memiliki paralelisme.
Rick James
9

IMHO dan dalam use case yang dijelaskan, Anda tidak akan pernah menggunakan lebih dari satu inti. Alasannya adalah bahwa beban kerja Anda terikat IO, bukan terikat CPU. Karena 3 koneksi Anda membuat Indeks baru, masing-masing dari mereka perlu membaca seluruh tabel dari disk: inilah yang memerlukan waktu, bukan menghitung Indeks.

jfg956
sumber
8

Pertimbangkan bahwa bottleneck Anda bisa menjadi kinerja IO sistem file Anda.

Selain pengaturan yang disarankan oleh @RandooMySQLDBA , saya juga mengatur noatimepengaturan mount /etc/fstabuntuk partisi yang menyimpan direktori data mysql saya ( /data01/mysqldalam kasus saya, dengan /dev/sdb1mount ke /data01).

Secara default linux mencatat waktu akses untuk SETIAP disk membaca atau menulis yang secara negatif mempengaruhi kinerja IO, terutama untuk aplikasi IO tinggi seperti database. Ini berarti bahwa bahkan membaca data dari file memicu penulisan ke disk ... WAT!

Untuk menonaktifkan ini, tambahkan noatimeopsi mount /etc/fstabuntuk titik mount yang diinginkan sebagai berikut (contoh dalam kasus saya):

/dev/sdb1  /data01  ext4  defaults,noatime  0  2

Kemudian pasang kembali partisi:

mount -o,remount /data01

Ini harus meningkatkan kinerja aplikasi baca / tulis menggunakan partisi itu. TAPI ... tidak ada yang mengalahkan semua data Anda dalam memori.

OkezieE
sumber