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

Apa yang Harus Diperiksa jika Pemanfaatan Memori MySQL Tinggi?

Salah satu faktor kunci dari server database MySQL yang berkinerja baik adalah memiliki alokasi dan pemanfaatan memori yang baik, terutama saat menjalankannya di lingkungan produksi. Tapi bagaimana Anda bisa menentukan apakah pemanfaatan MySQL dioptimalkan? Apakah masuk akal untuk memiliki pemanfaatan memori yang tinggi atau apakah itu memerlukan penyetelan yang baik? Bagaimana jika saya menghadapi kebocoran memori?

Mari kita bahas topik ini dan tunjukkan hal-hal yang dapat Anda periksa di MySQL untuk menentukan jejak penggunaan memori yang tinggi.

Alokasi Memori di MySQL

Sebelum kita membahas judul subjek tertentu, saya hanya akan memberikan informasi singkat tentang bagaimana MySQL menggunakan memori. Memori memainkan sumber daya yang signifikan untuk kecepatan dan efisiensi saat menangani transaksi bersamaan dan menjalankan kueri besar. Setiap utas di MySQL membutuhkan memori yang digunakan untuk mengelola koneksi klien, dan utas ini berbagi memori dasar yang sama. Variabel seperti thread_stack (tumpukan untuk utas), net_buffer_length (untuk buffer koneksi dan buffer hasil), atau dengan max_allowed_packet di mana koneksi dan hasil akan secara dinamis memperbesar hingga nilai ini bila diperlukan, adalah variabel yang memengaruhi penggunaan memori. Ketika utas tidak lagi diperlukan, memori yang dialokasikan untuk itu dilepaskan dan dikembalikan ke sistem kecuali utas kembali ke cache utas. Dalam hal ini, memori tetap dialokasikan. Penggabungan kueri, cache kueri, pengurutan, cache tabel, definisi tabel memang memerlukan memori di MySQL tetapi ini dikaitkan dengan variabel sistem yang dapat Anda konfigurasi dan atur.

Dalam kebanyakan kasus, variabel khusus memori yang ditetapkan untuk konfigurasi ditargetkan pada konfigurasi khusus berbasis penyimpanan seperti MyISAM atau InnoDB. Ketika instance mysqld muncul di dalam sistem host, MySQL mengalokasikan buffer dan cache untuk meningkatkan kinerja operasi database berdasarkan nilai yang ditetapkan pada konfigurasi tertentu. Misalnya, variabel paling umum yang akan ditetapkan setiap DBA di InnoDB adalah variabel innodb_buffer_pool_size dan innodb_buffer_pool_instances yang keduanya terkait dengan alokasi memori kumpulan buffer yang menyimpan data cache untuk tabel InnoDB. Sebaiknya jika Anda memiliki memori besar dan mengharapkan untuk menangani transaksi besar dengan mengatur innodb_buffer_pool_instances untuk meningkatkan konkurensi dengan membagi kumpulan buffer menjadi beberapa contoh kumpulan buffer.

Sementara untuk MyISAM, Anda harus berurusan dengan key_buffer_size untuk menangani jumlah memori yang akan ditangani oleh buffer kunci. MyISAM juga mengalokasikan buffer untuk setiap utas bersamaan yang berisi struktur tabel, struktur kolom untuk setiap kolom, dan buffer ukuran 3 * N dialokasikan (di mana N adalah panjang baris maksimum, tidak termasuk kolom BLOB). MyISAM juga mempertahankan satu buffer baris tambahan untuk penggunaan internal.

MySQL juga mengalokasikan memori untuk tabel sementara kecuali jika menjadi terlalu besar (ditentukan oleh tmp_table_size dan max_heap_table_size). Jika Anda menggunakan tabel MEMORY dan variabel max_heap_table_size disetel sangat tinggi, ini juga dapat mengambil memori yang besar karena variabel sistem max_heap_table_size menentukan seberapa besar tabel dapat berkembang, dan tidak ada konversi ke format di disk.

MySQL juga memiliki Performance Schema yang merupakan fitur untuk memonitor aktivitas MySQL pada level rendah. Setelah ini diaktifkan, ia secara dinamis mengalokasikan memori secara bertahap, menskalakan penggunaan memorinya ke beban server yang sebenarnya, alih-alih mengalokasikan memori yang diperlukan selama startup server. Setelah memori dialokasikan, itu tidak dibebaskan sampai server di-restart.

MySQL juga dapat dikonfigurasi untuk mengalokasikan area memori yang besar untuk kumpulan buffernya jika menggunakan Linux dan jika kernel diaktifkan untuk dukungan halaman yang besar, yaitu menggunakan HugePages.

Yang Harus Diperiksa Setelah Memori MySQL Tinggi

Periksa Kueri yang Berjalan

Sangat umum bagi DBA MySQL untuk menyentuh dasar terlebih dahulu apa yang terjadi dengan server MySQL yang sedang berjalan. Prosedur paling dasar adalah memeriksa daftar proses, memeriksa status server, dan memeriksa status mesin penyimpanan. Untuk melakukan hal-hal tersebut, pada dasarnya Anda tinggal menjalankan rangkaian query dengan login ke MySQL. Lihat di bawah:

Untuk melihat kueri yang sedang berjalan,

mysql> SHOW [FULL] PROCESSLIST;

Melihat daftar proses saat ini mengungkapkan kueri yang sedang berjalan secara aktif atau bahkan proses idle atau tidur. Sangat penting dan merupakan rutinitas yang signifikan untuk memiliki catatan kueri yang sedang berjalan. Sebagaimana disebutkan tentang cara MySQL mengalokasikan memori, menjalankan kueri akan menggunakan alokasi memori dan secara drastis dapat menyebabkan masalah kinerja jika tidak dipantau.

Melihat variabel status server MySQL,

mysql> SHOW SERVER STATUS\G

atau filter variabel tertentu seperti

mysql> SHOW SERVER STATUS WHERE variable_name IN ('<var1>', 'var2'...);

Variabel status MySQL berfungsi sebagai informasi statistik Anda untuk mengambil data metrik guna menentukan kinerja MySQL Anda dengan mengamati penghitung yang diberikan oleh nilai status. Ada nilai tertentu di sini yang memberi Anda pandangan yang memengaruhi penggunaan memori. Misalnya, memeriksa jumlah utas, jumlah cache tabel, atau penggunaan kumpulan buffer,

...

| Created_tmp_disk_tables                 | 24240 |

| Created_tmp_tables                      | 334999 |

…

| Innodb_buffer_pool_pages_data           | 754         |

| Innodb_buffer_pool_bytes_data           | 12353536         |

...

| Innodb_buffer_pool_pages_dirty          | 6         |

| Innodb_buffer_pool_bytes_dirty          | 98304         |

| Innodb_buffer_pool_pages_flushed        | 30383         |

| Innodb_buffer_pool_pages_free           | 130289         |

…

| Open_table_definitions                  | 540 |

| Open_tables                             | 1024 |

| Opened_table_definitions                | 540 |

| Opened_tables                           | 700887 |

...

| Threads_connected                             | 5 |

...

| Threads_cached    | 2 |

| Threads_connected | 5     |

| Threads_created   | 7 |

| Threads_running   | 1 |

Melihat status monitor mesin, misalnya, status InnoDB

mysql> SHOW ENGINE INNODB STATUS\G

Status InnoDB juga mengungkapkan status transaksi saat ini yang sedang diproses oleh mesin penyimpanan. Ini memberi Anda ukuran tumpukan transaksi, indeks hash adaptif yang mengungkapkan penggunaan buffernya, atau menampilkan informasi kumpulan buffer innodb seperti contoh di bawah ini:

---TRANSACTION 10798819, ACTIVE 0 sec inserting, thread declared inside InnoDB 1201

mysql tables in use 1, locked 1

1 lock struct(s), heap size 1136, 0 row lock(s), undo log entries 8801

MySQL thread id 68481, OS thread handle 139953970235136, query id 681821 localhost root copy to tmp table

ALTER TABLE NewAddressCode2_2 ENGINE=INNODB



…

-------------------------------------

INSERT BUFFER AND ADAPTIVE HASH INDEX

-------------------------------------

Ibuf: size 528, free list len 43894, seg size 44423, 1773 merges

merged operations:

 insert 63140, delete mark 0, delete 0

discarded operations:

 insert 0, delete mark 0, delete 0

Hash table size 553193, node heap has 1 buffer(s)

Hash table size 553193, node heap has 637 buffer(s)

Hash table size 553193, node heap has 772 buffer(s)

Hash table size 553193, node heap has 1239 buffer(s)

Hash table size 553193, node heap has 2 buffer(s)

Hash table size 553193, node heap has 0 buffer(s)

Hash table size 553193, node heap has 1 buffer(s)

Hash table size 553193, node heap has 1 buffer(s)

115320.41 hash searches/s, 10292.51 non-hash searches/s

...

----------------------

BUFFER POOL AND MEMORY

----------------------

Total large memory allocated 2235564032

Dictionary memory allocated 3227698

Internal hash tables (constant factor + variable factor)

    Adaptive hash index 78904768        (35404352 + 43500416)

    Page hash           277384 (buffer pool 0 only)

    Dictionary cache    12078786 (8851088 + 3227698)

    File system         1091824 (812272 + 279552)

    Lock system         5322504 (5313416 + 9088)

    Recovery system     0 (0 + 0)

Buffer pool size   131056

Buffer pool size, bytes 2147221504

Free buffers       8303

Database pages     120100

Old database pages 44172

Modified db pages  108784

Pending reads      0

Pending writes: LRU 2, flush list 342, single page 0

Pages made young 533709, not young 181962

3823.06 youngs/s, 1706.01 non-youngs/s

Pages read 4104, created 236572, written 441223

38.09 reads/s, 339.46 creates/s, 1805.87 writes/s

Buffer pool hit rate 1000 / 1000, young-making rate 12 / 1000 not 5 / 1000

Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s

LRU len: 120100, unzip_LRU len: 0

I/O sum[754560]:cur[8096], unzip sum[0]:cur[0]

…

Hal lain untuk ditambahkan, Anda juga dapat menggunakan Skema Kinerja dan skema sistem untuk memantau konsumsi dan penggunaan memori oleh server MySQL Anda. Secara default, sebagian besar instrumentasi dinonaktifkan secara default sehingga ada hal-hal manual yang harus dilakukan untuk menggunakan ini.

Periksa Swappiness 

Bagaimanapun, kemungkinan MySQL menukar memorinya ke disk. Ini seringkali merupakan situasi yang sangat umum terutama ketika server MySQL dan perangkat keras yang mendasarinya tidak diatur secara optimal secara paralel dengan persyaratan yang diharapkan. Ada kasus tertentu di mana permintaan lalu lintas belum diantisipasi, memori dapat bertambah terutama jika kueri buruk dijalankan yang menyebabkan penggunaan atau penggunaan banyak ruang memori yang menyebabkan penurunan kinerja karena data diambil di disk alih-alih di buffer. Untuk memeriksa swappiness, jalankan saja perintah freemem atau vmstat seperti di bawah ini,

[[email protected] ~]# free -m

              total        used free      shared buff/cache available

Mem:           3790 2754         121 202 915         584

Swap:          1535 39        1496

[[email protected] ~]# vmstat 5 5

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----

 r  b swpd   free buff  cache si so    bi bo in cs us sy id wa st

 2  0 40232 124100      0 937072 2 3 194  1029 477 313 7 2 91 1  0

 0  0 40232 123912      0 937228 0 0   0 49 1247 704 13 3 84  0 0

 1  0 40232 124184      0 937212 0 0   0 35 751 478 6 1 93  0 0

 0  0 40232 123688      0 937228 0 0   0 15 736 487 5 1 94  0 0

 0  0 40232 123912      0 937220 0 0   3 74 1065 729 8 2 89  0 0

Anda juga dapat memeriksa menggunakan procfs dan mengumpulkan informasi seperti membuka /proc/vmstat atau /proc/meminfo.

Menggunakan Perf, gdb, dan Valgrind dengan Massif

Menggunakan alat seperti perf, gdb, dan valgrind membantu Anda menggali metode yang lebih maju untuk menentukan penggunaan memori MySQL. Ada kalanya hasil yang menarik menjadi misteri pemecahan konsumsi memori yang menyebabkan kebingungan Anda di MySQL. Hal ini menyebabkan kebutuhan untuk lebih skeptis dan menggunakan alat ini membantu Anda menyelidiki bagaimana MySQL menggunakan memori penanganan mulai dari mengalokasikannya hingga menggunakannya untuk memproses transaksi atau proses. Ini berguna misalnya jika Anda mengamati MySQL berperilaku tidak normal yang dapat menyebabkan konfigurasi yang buruk atau dapat menyebabkan temuan kebocoran memori.

Misalnya, menggunakan perf di MySQL mengungkapkan lebih banyak informasi dalam laporan tingkat sistem:

[[email protected] ~]# perf report --input perf.data --stdio

# To display the perf.data header info, please use --header/--header-only options.

#

#

# Total Lost Samples: 0

#

# Samples: 54K of event 'cpu-clock'

# Event count (approx.): 13702000000

#

# Overhead  Command Shared Object        Symbol                                                                                                                                                                                             

# ........  ....... ...................  ...................................................................................................................................................................................................

#

    60.66%  mysqld [kernel.kallsyms]    [k] _raw_spin_unlock_irqrestore

     2.79%  mysqld   libc-2.17.so         [.] __memcpy_ssse3

     2.54%  mysqld   mysqld             [.] ha_key_cmp

     1.89%  mysqld   [vdso]             [.] __vdso_clock_gettime

     1.05%  mysqld   mysqld             [.] rec_get_offsets_func

     1.03%  mysqld   mysqld             [.] row_sel_field_store_in_mysql_format_func

     0.92%  mysqld   mysqld             [.] _mi_rec_pack

     0.91%  mysqld   [kernel.kallsyms]    [k] finish_task_switch

     0.90%  mysqld   mysqld             [.] row_search_mvcc

     0.86%  mysqld   mysqld             [.] decimal2bin

     0.83%  mysqld   mysqld             [.] _mi_rec_check

….

Karena ini bisa menjadi topik khusus untuk digali, kami sarankan Anda melihat ke blog eksternal yang sangat bagus ini sebagai referensi Anda, dasar-dasar perf untuk Profil MySQL, Menemukan Masalah Penskalaan MySQL Menggunakan perf, atau pelajari cara debug menggunakan valgrind dengan massif.

Cara Efisien Untuk Memeriksa Penggunaan Memori MySQL

Menggunakan ClusterControl mengurangi rutinitas yang merepotkan seperti menelusuri runbook Anda atau bahkan membuat playbook Anda sendiri yang akan mengirimkan laporan untuk Anda. Di ClusterControl, Anda memiliki Dasbor (menggunakan SCUMM) di mana Anda dapat memiliki gambaran singkat tentang node MySQL Anda. Misalnya, melihat dasbor Umum MySQL,

Anda dapat menentukan kinerja node MySQL,

Anda melihat bahwa gambar di atas mengungkapkan variabel yang memengaruhi penggunaan memori MySQL. Anda dapat memeriksa bagaimana metrik untuk cache pengurutan, tabel sementara, utas terhubung, cache kueri, atau mesin penyimpanan innodb buffer pool atau buffer kunci MyISAM.

Menggunakan ClusterControl menawarkan alat utilitas lengkap tempat Anda juga dapat memeriksa kueri yang berjalan untuk menentukan proses (kueri) yang dapat memengaruhi penggunaan memori yang tinggi. Lihat di bawah untuk contoh,

Melihat variabel status MySQL sangat mudah,

Anda bahkan dapat pergi ke Performance -> Status Innodb juga untuk mengungkapkan status InnoDB saat ini dari node database Anda. Selain itu, di ClusterControl, sebuah insiden terdeteksi, ia akan mencoba mengumpulkan insiden dan menampilkan riwayat sebagai laporan yang memberi Anda status InnoDB seperti yang ditunjukkan di blog kami sebelumnya tentang MySQL Freeze Frame.

Ringkasan

Memecahkan masalah dan mendiagnosis database MySQL Anda saat mencurigai penggunaan memori yang tinggi tidaklah sulit selama Anda mengetahui prosedur dan alat yang digunakan. Menggunakan alat yang tepat memberi Anda lebih banyak fleksibilitas dan produktivitas lebih cepat untuk memberikan perbaikan atau solusi dengan peluang hasil yang lebih besar.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Apa operator <=> ini di MySQL?

  2. MySQL - Batasan Kunci Asing Bersyarat

  3. Bagaimana cara memulai MySQL dengan --skip-grant-tables?

  4. cara menghapus baris duplikat dari tabel di mysql

  5. SQL SERVER – Salah Satu Trik Menangani SQL Dinamis untuk Menghindari Serangan Injeksi SQL?