it-swarm.dev

Dlaczego MySQL mówi, że brakuje mi pamięci?

Próbowałem wykonać dość duży INSERT...SELECT w MySQL z JDBC, i otrzymałem następujący wyjątek:

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

Ponieważ tak naprawdę nie zwracam obiektu ResultSet, pomyślałem, że przestrzeń sterty Java nie powinna być problemem. Jednak mimo to próbowałem ją zwiększyć i nie przyniosło to skutku). aby wykonać instrukcję w MySQL Workbench i otrzymałem zasadniczo to samo:

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

Powinienem mieć dużo RAM, aby wykonać te operacje (wystarczające, aby zmieścić cały stół, z którego wybieram), ale domyślam się, że są różne ustawienia, które muszę dostosować, aby skorzystać całą moją pamięć. Korzystam z Amazon EC2 High Memory Double Extra Large Instance z interfejsem AMI systemu Windows Server 2008. Próbowałem bawić się z plikiem my.ini, aby używać lepszych ustawień, ale dla wszystkich Wiem, że mogłem pogorszyć sytuację. Oto zrzut tego pliku:

[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

Czy to tylko kwestia zmiany powyższych ustawień, aby działały lepiej w moim środowisku? Jeśli tak, jakich ustawień powinienem użyć? Jestem jedynym, który kiedykolwiek korzysta z tego wystąpienia; Używam go do mojego osobistego projektu hobby, który obejmuje analizę statystyczną dużych zbiorów danych. W związku z tym mogę swobodnie zużywać wszystkie dostępne zasoby do własnych zapytań.

Jeśli to nie jest kwestia zmiany tych ustawień, na czym polega problem? Dziękujemy za wszelką pomoc, która może pomóc w lepszym skonfigurowaniu wszystkiego.

9
Michael McGowan

Biorąc pod uwagę, że jest to instalacja systemu Windows, @DTest nadal podał właściwy początkowy kierunek.

Zastosuj następującą formułę:

Większość ludzi korzysta z tego:

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

Wolę to:

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)

Zmienne te należy dostosować, dopóki formuła nie zapewni 80% zainstalowanego RAM lub mniej.

sort_buffer_size
read_buffer_size
read_rnd_buffer_size
join_buffer_size
max_connections
9
RolandoMySQLDBA

Spróbowałbym zmniejszyć twoje rozmiary buforów. Zwiększenie ich rozmiarów, tak jak je masz, spowoduje problemy. Ile masz pamięci do uruchomienia tych wartości:

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

Niektóre rozmiary buforów są przydzielane dla wątków, na przykład myisam_sort_buffer_size 10G przydziela 10G dla każdego wątku.

Najpierw znacznie zmniejszyłbym te wartości, a następnie zbadałem, które wartości naprawdę potrzebujesz, aby mieć tyle RAM przydzielony (jeśli istnieje)).

4
Derek Downey

Szybki sposób na określenie ilości pamięci, którą MySQL myśli, że mogłaby przydzielić, jest następujący:

wget mysqltuner.pl

Perl mysqltuner.pl

Po uruchomieniu tego skryptu dowiesz się, jaki procent zainstalowanego RAM MySQL myśli, że można go bezpiecznie przydzielić. Jeśli podana odpowiedź to ponad 100%, zdecydowanie musisz zmniejszyć rozmiar bufora. Najważniejsze z nich to:

sort_buffer_size
read_buffer_size
read_rnd_buffer_size
join_buffer_size
max_connections
key_buffer_size (niezbyt skuteczne po 4G)

@DTest już określił dla ciebie kierunek w swojej odpowiedzi, więc +1 dla jego odpowiedzi. Skrypt Perla powie ci, co się stanie, jeśli go nie ustawisz lub zmienisz dowolną wartość. Oto przykład:

Mój klient ma
read_buffer_size = 128 KB
read_rnd_buffer_size = 256 KB
sort_buffer_size = 2 mln
join_buffer_size = 128 KB
max_connections = 1050

Oto wyniki z mysqltuner.pl:

MySQLTuner 1.2.0 - Major Hayden
Raporty o błędach, prośby o funkcje i pliki do pobrania na http://mysqltuner.com/
Uruchom z „--help”, aby uzyskać dodatkowe opcje i filtrowanie wyników
Wpisz swój login administratora MySQL: lwdba
Wprowadź hasło administracyjne MySQL:

-------- Statystyki ogólne ---------------------------------------- ----------
[-] Pominięto sprawdzanie wersji skryptu MySQLTuner
[OK] Aktualnie działa obsługiwana wersja MySQL 5.0.51a-dziennik-społeczności
[!!] Przełącz na 64-bitowy system operacyjny - MySQL nie może obecnie korzystać z całej pamięci RAM

-------- Statystyki silnika pamięci masowej --------------------------------------- ----
[-] Status: + Archiwum -BDB + Federated + InnoDB -ISAM -NDBCluster
[-] Dane w tabelach MyISAM: 319M (tabele: 108)
[-] Dane w tabelach InnoDB: 2M (tabele: 5)
[!!] Suma podzielonych tabel: 22

-------- Wskaźniki wydajności ---------------------------------------- ---------
[-] Do: 52d 23h 15m 57s (72M q [15,875 qps], 241K conn, TX: 2B, RX: 1B)
[-] Odczyt/zapis: 59%/41%
[-] Całkowita liczba buforów: 34,0 mln globalnych + 2,7 mln na wątek (maks. 1050 wątków)
[!!] Przydzielanie> 2 GB RAM w systemach 32-bitowych może powodować niestabilność systemu
[!!] Maksymalne możliwe użycie pamięci: 2,8G (72% zainstalowanej pamięci RAM)
[OK] Wolne zapytania: 0% (54/72M)
[OK] Najwyższe wykorzystanie dostępnych połączeń: 6% (65/1050)
[OK] Rozmiar bufora klucza/całkowite indeksy MyISAM: 8,0 mln/82,1 mln
[OK] Współczynnik trafień bufora klucza: 100,0% (pamięć podręczna 4B/odczyt 1M)
[!!] Pamięć podręczna zapytań jest wyłączona
[OK] Sortowanie wymagające tabel tymczasowych: 0% (sortowanie tymczasowe/sortowanie 948K)
[OK] Tabele tymczasowe utworzone na dysku: 3% (11 000 na dysku/380 000 ogółem)
[!!] Pamięć podręczna wątków jest wyłączona
[!!] Współczynnik trafień w pamięci podręcznej tabeli: 0% (64 otwarte/32K otwarte)
[OK] Wykorzystany limit otwartych plików: 2% (125/5K)
[OK] Blokady stołu nabyte natychmiast: 99% (30 mln natychmiastowych/30 mln blokad)
[OK] Rozmiar danych/pula buforów InnoDB: 2,7 mln/8,0 mln

-------- Zalecenia ----------------------------------------- ------------
Ogólne zalecenia:
Uruchom OPTIMIZE TABLE, aby defragmentować tabele w celu uzyskania lepszej wydajności
Włącz dziennik wolnych zapytań, aby rozwiązać problemy z błędnymi zapytaniami
Ustaw rozmiar wątku_cache na 4 jako wartość początkową
Zwiększaj stopniowo table_cache, aby uniknąć limitów deskryptorów plików
Zmienne do dostosowania:
query_cache_size (> = 8M)
thread_cache_size (początek o 4)
table_cache (> 64)

Proszę zwrócić uwagę na wskaźniki wydajności

[-] Całkowita liczba buforów: 34,0 mln globalnych + 2,7 mln na wątek (maks. 1050 wątków)

że MySQL może przydzielić do 72% zainstalowanego RAM na podstawie ustawień w /etc/my.cnf.

34M jest oparty na kombinacjach innodb_buffer_pool_size i key_buffer_size

2,7 mln na wątek oparto na read_buffer_size + read_rnd_buffer_size + sort_buffer_size + join_buffer_size.

Wielokrotność 2,7M jest oparta na max_connections.

Dlatego musisz dostosować te parametry, dopóki raport Metryki wydajności nie wskaże, że masz mniej niż 100% (najlepiej poniżej 80%) zainstalowanej pamięci RAM.

4
RolandoMySQLDBA

Nie powiedziałeś, ile RAM masz? Zakładam, że jest to co najmniej 32 GB.

innodb_buffer_pool_size - 23G

Dobry na tyle pamięci RAM.

query_cache_size = 1G

O wiele za duży. Jest nieefektywny, gdy jest duży. Polecam nie więcej niż 50 mln.

key-buffer_size = 5G

Może być twardy limit 4G (nadal) w systemie Windows, miał twardy limit 4G. Twój 5G mógł zmienić się w 1G. W każdym razie, jeśli wszystkie twoje tabele to InnoDB, po co marnować pamięci RAM. Ustaw na 50M.

Ponieważ komunikat o błędzie miał dokładnie 1G, pachnie jak sort_buffer_size. 32M może być rozsądne.

1
Rick James