Penggunaan memori maksimum MySQL

111

Saya ingin tahu bagaimana cara menetapkan batas atas jumlah memori yang digunakan MySQL di server Linux.

Saat ini, MySQL akan terus menggunakan memori dengan setiap permintaan baru yang diminta sehingga akhirnya kehabisan memori. Apakah ada cara untuk membatasi agar tidak lebih dari jumlah tersebut yang digunakan oleh MySQL?

shilovk.dll
sumber
4
MySQL tidak "menggunakan memori untuk setiap permintaan baru dan pada akhirnya akan habis". Penggunaan memori jauh lebih kompleks dari itu.
Rick James

Jawaban:

183

Penggunaan memori maksimum MySQL sangat bergantung pada perangkat keras, pengaturan Anda, dan database itu sendiri.

Perangkat keras

Perangkat keras adalah bagian yang jelas. Semakin banyak RAM semakin baik, disk lebih cepat ftw . Namun, jangan percaya surat berita bulanan atau mingguan itu. MySQL tidak berskala linier - bahkan pada perangkat keras Oracle. Ini sedikit lebih rumit dari itu.

Intinya adalah: tidak ada aturan umum tentang apa yang direkomendasikan untuk pengaturan MySQL Anda . Itu semua tergantung pada penggunaan saat ini atau proyeksi.

Pengaturan & database

MySQL menawarkan variabel dan sakelar yang tak terhitung jumlahnya untuk mengoptimalkan perilakunya. Jika Anda mengalami masalah, Anda benar-benar perlu duduk dan membaca manual (f'ing).

Adapun database - beberapa kendala penting:

  • mesin meja ( InnoDB, MyISAM, ...)
  • ukuran
  • indeks
  • pemakaian

Kebanyakan tips MySQL tentang stackoverflow akan memberi tahu Anda tentang 5-8 yang disebut pengaturan penting. Pertama, tidak semuanya penting - misalnya mengalokasikan banyak sumber daya ke InnoDB dan tidak menggunakan InnoDB tidak masuk akal karena sumber daya tersebut terbuang percuma.

Atau - banyak orang menyarankan untuk menaikkan max_connectionvariabel - yah, sedikit yang mereka ketahui itu juga menyiratkan bahwa MySQL akan mengalokasikan lebih banyak sumber daya untuk memenuhi itu max_connections- jika diperlukan. Solusi yang lebih jelas mungkin menutup koneksi database di DBAL Anda atau menurunkan wait_timeoutuntuk membebaskan utas tersebut.

Jika Anda memahami maksud saya - benar-benar ada banyak, banyak hal untuk dibaca dan dipelajari.

Mesin

Mesin tabel adalah keputusan yang cukup penting, banyak orang melupakannya sejak awal dan kemudian tiba-tiba menemukan diri mereka berkelahi dengan MyISAMmeja berukuran 30 GB yang mengunci dan memblokir seluruh aplikasi mereka.

Saya tidak bermaksud mengatakan MyISAM menyebalkan , tetapi InnoDBdapat diubah untuk merespons hampir atau hampir secepat MyISAMdan menawarkan hal seperti penguncian baris UPDATEsementara MyISAMmengunci seluruh tabel saat ditulis.

Jika Anda bebas menjalankan MySQL di infrastruktur Anda sendiri, Anda mungkin juga ingin memeriksa server percona karena di antara termasuk banyak kontribusi dari perusahaan seperti Facebook dan Google (mereka tahu dengan cepat), itu juga termasuk drop- sebagai pengganti InnoDB, dipanggil XtraDB.

Lihat inti saya untuk pengaturan percona-server (dan -client) (di Ubuntu): http://gist.github.com/637669

Ukuran

Ukuran database sangat, sangat penting - percaya atau tidak, kebanyakan orang di Intarwebs tidak pernah menangani pengaturan MySQL yang besar dan menulis secara intens tetapi itu benar-benar ada. Beberapa orang akan mengolok-olok dan mengatakan sesuatu seperti, "Gunakan PostgreSQL !!! 111", tapi mari kita abaikan mereka untuk saat ini.

Intinya adalah: dilihat dari ukuran, keputusan tentang perangkat keras harus dibuat. Anda tidak dapat benar-benar membuat database 80 GB berjalan cepat pada RAM 1 GB.

Indeks

Bukan: semakin banyak, semakin meriah. Hanya indeks yang diperlukan yang harus ditetapkan dan penggunaan harus diperiksa EXPLAIN. Tambahkan ke bahwa MySQL EXPLAINsangat terbatas, tetapi ini adalah permulaan.

Konfigurasi yang disarankan

Tentang ini my-large.cnfdan my-medium.cnffile - saya bahkan tidak tahu untuk siapa itu ditulis. Gulung milik Anda sendiri.

Tuning primer

Awal yang baik adalah tuning primer . Ini script bash (petunjuk: Anda harus linux) yang mengambil output dari SHOW VARIABLESdan SHOW STATUSdan membungkus menjadi rekomendasi semoga bermanfaat. Jika server Anda sudah berjalan lama, rekomendasinya akan lebih baik karena akan ada data untuk dijadikan dasar.

Primer tuning bukanlah saus ajaib. Anda tetap harus membaca semua variabel yang disarankan untuk diubah.

Bacaan

Saya sangat merekomendasikan mysqlperformanceblog . Ini adalah sumber yang bagus untuk semua jenis tip terkait MySQL. Dan bukan hanya MySQL, mereka juga tahu banyak tentang perangkat keras yang tepat atau merekomendasikan penyiapan untuk AWS, dll. Orang-orang ini memiliki pengalaman bertahun-tahun.

Sumber daya hebat lainnya adalah planet-mysql , tentu saja.

Sampai
sumber
Saya tidak tahu tentang tuning primer, bagaimana cara membandingkannya mysqltuner?
greg0ire
38

Kami menggunakan pengaturan ini:

etc/my.cnf
innodb_buffer_pool_size = 384M
key_buffer = 256M
query_cache_size = 1M
query_cache_limit = 128M
thread_cache_size = 8
max_connections = 400
innodb_lock_wait_timeout = 100

untuk server dengan spesifikasi sebagai berikut:

Dell Server
CPU cores: Two
Processor(s): 1x Dual Xeon
Clock Speed: >= 2.33GHz
RAM: 2 GBytes
Disks: 1×250 GB SATA
Ignacio Pascual
sumber
16
Saya pikir Anda (dan penulis yang Anda tautkan) memiliki query_cache_size dan query_cache_limit dengan cara yang salah. Anda memberi tahu MySQL: alokasikan cache 1MB tetapi jangan masukkan kueri apa pun di dalamnya yang lebih besar dari 128MB. dev.mysql.com/doc/refman/5.0/en/query-cache-configuration.html
agtb
Saya akan menurunkan max_connections. Saya akan memutuskan mesin mana yang akan digunakan, dan tidak mengalokasikan banyak ruang untuk keduanya.
Rick James
19

Penggunaan memori database adalah topik yang kompleks. The MySQL Kinerja Blog melakukan pekerjaan yang baik yang meliputi pertanyaan Anda, dan daftar banyak alasan mengapa hal itu sangat tidak praktis untuk memori "cadangan".

Jika Anda benar-benar ingin memaksakan batasan keras, Anda dapat melakukannya, tetapi Anda harus melakukannya di tingkat OS karena tidak ada pengaturan bawaan. Di linux, Anda dapat menggunakan ulimit , tetapi Anda mungkin harus memodifikasi cara MySQL memulai untuk menerapkannya.


Solusi terbaik adalah menurunkan server Anda, sehingga kombinasi dari pengaturan memori MySQL biasa akan menghasilkan penggunaan memori yang lebih rendah secara umum oleh instalasi MySQL Anda. Ini tentu saja akan berdampak negatif pada kinerja database Anda, tetapi beberapa pengaturan yang dapat Anda atur my.iniadalah:

key_buffer_size
query_cache_size
query_cache_limit
table_cache
max_connections
tmp_table_size
innodb_buffer_pool_size

Saya akan mulai dari sana dan melihat apakah Anda bisa mendapatkan hasil yang Anda inginkan. Ada banyak artikel di luar sana tentang menyesuaikan pengaturan memori MySQL.


Edit:

Perhatikan bahwa beberapa nama variabel telah berubah di rilis 5.1.x MySQL yang lebih baru .

Sebagai contoh:

table_cache

Sekarang:

table_open_cache
zombat
sumber
2
Hai! Terima kasih atas jawaban anda. Saya perhatikan bahwa persamaan yang dikutip orang adalah sebagai berikut: key_buffer_size + (read_buffer_size + sort_buffer_size) * max_connections = Total Memory. Saya telah menetapkan yang berikut ini: key_buffer_size = 128M, read_buffer_size = 1M, sort_buffer_size = 2M, max_connections = 120, dan total memori di server adalah 512M. Namun, setelah banyak pertanyaan, memori bebas menjadi serendah 12 juta dan mungkin akan terus turun dengan penggunaan lebih lanjut. Adakah alasan mengapa demikian dan dapatkah dicegah? Terima kasih!
Atau mungkin saya perlu mempertimbangkan bukan total memori di server (512M) tetapi memori bebas (yaitu memori yang tersedia setelah memuat semua OS yang terkait dan program lainnya)?
1
Jika Anda akan memodifikasi tmp_table_size dengan maksud untuk meningkatkan ukuran tabel temp yang dapat disimpan dalam RAM, ingatlah untuk juga meningkatkan max_heap_table_size - karena MySQL menggunakan minimal dua ...
Dave Rix
1
@TimothyMilsud - Tidak ada formula seperti itu yang benar-benar berhasil. Dan sebagian besar server berjalan cukup baik ketika rumus mengklaim terlalu banyak RAM yang digunakan.
Rick James
19

mysqld.exe menggunakan 480 mb di RAM. Saya menemukan bahwa saya menambahkan parameter ini ke my.ini

table_definition_cache = 400

yang mengurangi penggunaan memori dari 400.000+ kb menjadi 105.000 kb

Sarvar Nishonboev
sumber
Di bagian apa ini berada? Saya menambahkannya ke milik saya dan layanan menolak untuk memulai.
Kesalahan Sintaks
Tidak masalah, saya memindahkannya ke bawah [wampmysqld] dan berfungsi dengan baik serta mengurangi memori yang saya gunakan secara signifikan. Saya pikir itu mungkin telah mempercepat pemuatan halaman hosting lokal saya dalam prosesnya juga, mereka tampak lebih cepat sekarang.
Kesalahan Sintaks
Meskipun default dan minimumnya 400, apa yang membuatnya lebih tinggi dari 400 dalam kasus Anda?
Wadih M.
5

di /etc/my.cnf:

[mysqld]
...

performance_schema = 0

table_cache = 0
table_definition_cache = 0
max-connect-errors = 10000

query_cache_size = 0
query_cache_limit = 0

...

Kerja bagus di server dengan Memori 256MB.

shilovk.dll
sumber
Mengapa table_definition_cache= 0? Beberapa penjelasan akan menyenangkan. Dan pada dasarnya Anda tidak menyimpan kueri dalam cache ... efek yang sama jika Anda query_cache_type = 0:)
Khom Nazid
0

Jika Anda mencari untuk mengoptimalkan kontainer mysql buruh pelabuhan Anda maka perintah di bawah ini dapat membantu. Saya dapat menjalankan kontainer buruh pelabuhan mysql dari 480mb default menjadi hanya 100 mbs

buruh pelabuhan menjalankan -d -p 3306: 3306 -e MYSQL_DATABASE = uji -e MYSQL_ROOT_PASSWORD = tooor -e MYSQL_USER = uji -e MYSQL_PASSWORD = uji -v / mysql: / var / lib / mysql --name mysqldb mysql --table_definition_cache = 100 --performance_schema = 0 --default-authentication-plugin = mysql_native_password

Rohit Salecha
sumber