it-swarm.asia

Mengapa MySQL mengatakan saya kehabisan memori?

Saya mencoba menjalankan INSERT...SELECT Yang cukup besar di MySQL dengan JDBC, dan saya mendapat pengecualian berikut:

Exception in thread "main" Java.sql.SQLException: Out of memory (Needed 1073741824 bytes)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.Java:1073)

Karena saya tidak benar-benar mengembalikan objek ResultSet, saya pikir ruang heap Java seharusnya tidak menjadi masalah. Namun, saya tetap mencoba untuk meningkatkannya dan itu tidak baik. Saya kemudian mencoba untuk menjalankan pernyataan di MySQL Workbench dan pada dasarnya saya mendapatkan hal yang sama:

Error Code 5: Out of memory (Needed 1073741816 bytes)

Saya seharusnya memiliki banyak RAM untuk menyelesaikan operasi ini (cukup untuk memenuhi seluruh tabel yang saya pilih), tetapi saya menduga ada berbagai pengaturan yang perlu saya Tweak untuk memanfaatkan semua memori saya. Saya sedang menjalankan Amazon EC2 Memori Tinggi Dua Kali Ekstra Besar Besar dengan Windows Server 2008 AMI. Saya sudah mencoba mengutak-atik file my.ini untuk menggunakan pengaturan yang lebih baik, tetapi untuk semua Saya tahu saya mungkin membuat segalanya lebih buruk.

[client]
port=3306
[mysql]
default-character-set=latin1
[mysqld]
port=3306
basedir="C:/Program Files/MySQL/MySQL Server 5.5/"
datadir="C:/ProgramData/MySQL/MySQL Server 5.5/Data/"
character-set-server=latin1
default-storage-engine=INNODB
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
max_connections=100
query_cache_size=1024M
table_cache=256
tmp_table_size=25G
thread_cache_size=8
myisam_max_sort_file_size=100G
myisam_repair_threads = 2
myisam_sort_buffer_size=10G
key_buffer_size=5000M
bulk_insert_buffer_size = 4000M
read_buffer_size=8000M
read_rnd_buffer_size=8000M
sort_buffer_size=1G
innodb_additional_mem_pool_size=26M
innodb_flush_log_at_trx_commit=2
innodb_log_buffer_size=13M
innodb_buffer_pool_size=23G
innodb_log_file_size=622M
innodb_thread_concurrency=18
innodb_file_per_table=TRUE
join_buffer_size=4G
max_heap_table_size = 10G

Jadi apakah ini hanya masalah mengubah pengaturan di atas agar berfungsi lebih baik untuk lingkungan saya? Jika demikian, pengaturan apa yang harus saya gunakan? Saya satu-satunya yang pernah menggunakan instance ini; Saya menggunakannya untuk proyek hobi pribadi saya yang melibatkan analisis statistik dataset besar. Karena itu, saya bebas untuk membiarkannya menghabiskan semua sumber daya yang tersedia untuk pertanyaan saya sendiri.

Jika ini bukan masalah mengubah pengaturan itu, apa masalahnya? Terima kasih atas bantuan yang dapat Anda tawarkan untuk cara mengkonfigurasi semuanya dengan lebih baik.

9
Michael McGowan

Mengingat ini adalah instalasi Windows, @DTest masih memberikan arahan awal yang tepat.

Terapkan rumus berikut:

Kebanyakan orang menggunakan ini:

Maximum MySQL Memory Usage = innodb_buffer_pool_size + key_buffer_size + (read_buffer_size + sort_buffer_size) X max_connections

Saya lebih memilih ini:

Maximum MySQL Memory Usage = innodb_buffer_pool_size + key_buffer_size + ((read_buffer_size + read_rnd_buffer_size + sort_buffer_size + join_buffer_size) X max_connections)

Variabel-variabel ini adalah yang perlu Anda sesuaikan hingga formula menghasilkan 80% dari RAM yang diinstal atau kurang.

sort_buffer_size
read_buffer_size
read_rnd_buffer_size
join_buffer_size
max_connections
9
RolandoMySQLDBA

Saya akan mencoba menurunkan ukuran buffer Anda. Membuatnya sebesar yang Anda miliki akan menimbulkan masalah. Berapa banyak memori yang Anda miliki untuk menjalankan nilai-nilai ini:

query_cache_size=1024M
myisam_max_sort_file_size=100G
myisam_sort_buffer_size=10G
key_buffer_size=5000M
bulk_insert_buffer_size = 4000M
read_buffer_size=8000M
read_rnd_buffer_size=8000M
sort_buffer_size=1G
innodb_buffer_pool_size=23G

Beberapa ukuran buffer dialokasikan per-utas, misalnya myisam_sort_buffer_size dari 10G mengalokasikan 10G untuk setiap utas.

Pertama-tama saya akan mengurangi nilai-nilai itu secara dramatis, dan kemudian menyelidiki nilai-nilai mana yang benar-benar Anda butuhkan untuk mengalokasikan sebanyak ini RAM (jika ada).

4
Derek Downey

Cara cepat untuk menentukan berapa banyak memori yang menurut MySQL dapat dialokasikan adalah sebagai berikut:

wget mysqltuner.pl

Perl mysqltuner.pl

Ketika Anda menjalankan skrip ini, ia akan memberi tahu Anda berapa persen dari RAM yang dipasang menurut MySQL dapat dengan aman dialokasikan. Jika jawaban yang diberikan lebih dari 100%, Anda pasti perlu menurunkan ukuran buffer Anda. Yang utama untuk fokus adalah:

sort_buffer_size
read_buffer_size
read_rnd_buffer_size
join_buffer_size
max_connections
key_buffer_size (tidak terlalu efektif melewati 4G)

@Dest sudah menetapkan arah untuk Anda dalam jawabannya, jadi +1 untuk anwser-nya. Skrip Perl akan memberi tahu Anda apa yang terjadi jika Anda tidak menyetelnya atau jika Anda mengubah nilai apa pun. Berikut ini sebuah contoh:

Seorang klien saya punya
read_buffer_size = 128K
read_rnd_buffer_size = 256 ribu
sort_buffer_size = 2M
join_buffer_size = 128K
max_connections = 1050

Berikut ini adalah output dari mysqltuner.pl:

MySQLTuner 1.2.0 - Mayor Hayden
Laporan bug, permintaan fitur, dan unduhan di http://mysqltuner.com/
Jalankan dengan '--help' untuk opsi tambahan dan penyaringan keluaran
Silakan masukkan login administratif MySQL Anda: lwdba
Silakan masukkan kata sandi administratif MySQL Anda:

-------- Statistik Umum ---------------------------------------- ----------
[-] Versi tidak diperiksa untuk skrip MySQLTuner
[OK] Saat ini sedang berjalan didukung versi MySQL 5.0.51a-komunitas-log
[!!] Beralih ke OS 64-bit - MySQL saat ini tidak dapat menggunakan semua RAM Anda

-------- Statistik Mesin Penyimpanan --------------------------------------- ----
[-] Status: + Arsip -BDB + Federasi + InnoDB -ISAM -NDBCluster
[-] Data dalam tabel MyISAM: 319M (Tabel: 108)
[-] Data dalam tabel InnoDB: 2M (Tabel: 5)
[!!] Total tabel terfragmentasi: 22

-------- Metrik Kinerja ---------------------------------------- ---------
[-] Naik untuk: 52d 23j 15j 57d (72M q [15.875 qps], 241K samb, TX: 2B, RX: 1B)
[-] Membaca/Menulis: 59%/41%
[-] Total buffer: 34.0M global + 2.7M per utas (1050 maks utas)
[!!] Mengalokasikan> 2GB RAM pada sistem 32-bit dapat menyebabkan ketidakstabilan sistem
[!!] Penggunaan memori maksimum yang mungkin: 2.8G (72% dari RAM terpasang)
[OK] Permintaan lambat: 0% (54/72M)
[OK] Penggunaan tertinggi koneksi yang tersedia: 6% (65/1050)
[OK] Ukuran buffer kunci/total indeks MyISAM: 8.0M/82.1M
[OK] Tingkat hit buffer kunci: 100.0% (4B di-cache/1M dibaca)
[!!] Cache permintaan dinonaktifkan
[Oke] Beragam yang membutuhkan tabel sementara: 0% (0 temp macam/948 ribu macam)
[OK] Tabel sementara dibuat di disk: 3% (11K pada disk/total 380K)
[!!] Thread cache dinonaktifkan
[!!] Rasio hit cache tabel: 0% (64 terbuka/32K dibuka)
[OK] Buka batas file yang digunakan: 2% (125/5K)
[Oke] Kunci tabel diperoleh dengan segera: 99% (30M langsung/30M kunci)
[Oke] Ukuran data/buffer pool InnoDB: 2,7M/8,0M

-------- Rekomendasi ----------------------------------------- ------------
Rekomendasi umum:
Jalankan OPTIMIZE TABLE ke tabel defragment untuk kinerja yang lebih baik
Aktifkan log kueri lambat untuk memecahkan masalah kueri buruk
Setel thread_cache_size ke 4 sebagai nilai awal
Tingkatkan table_cache secara bertahap untuk menghindari batasan deskriptor file
Variabel yang akan disesuaikan:
query_cache_size (> = 8M)
thread_cache_size (mulai dari 4)
table_cache (> 64)

Harap perhatikan dalam metrik kinerja

[-] Total buffer: 34.0M global + 2.7M per utas (1050 maks utas)

bahwa MySQL dapat mengalokasikan hingga 72% dari terpasang RAM berdasarkan pengaturan di /etc/my.cnf.

34M didasarkan pada innodb_buffer_pool_size dan key_buffer_size digabungkan

2,7M per utas didasarkan pada read_buffer_size + read_rnd_buffer_size + sort_buffer_size + join_buffer_size.

Kelipatan 2.7M didasarkan pada max_connections.

Oleh karena itu, Anda harus mengubah parameter ini hingga laporan metrik Kinerja mengatakan Anda memiliki di bawah 100% (lebih disukai di bawah 80%) dari RAM yang terpasang.

4
RolandoMySQLDBA

Anda tidak mengatakan berapa banyak RAM yang Anda miliki? Saya berasumsi itu setidaknya 32GB.

innodb_buffer_pool_size - 23G

Bagus untuk RAM sebesar itu.

query_cache_size = 1G

Terlalu besar. Itu tidak efisien ketika itu besar. Rekomendasikan tidak lebih dari 50 juta.

key-buffer_size = 5G

Mungkin ada batas keras 4G (masih) di Windows, punya batas keras 4G. 5G Anda mungkin telah berubah menjadi 1G. Lagi pula, jika semua meja Anda adalah InnoDB, mengapa buang domba jantan itu. Atur ke 50 juta.

Karena pesan kesalahannya persis 1G, baunya seperti sort_buffer_size. 32M mungkin masuk akal.

1
Rick James