Чому MySQL каже, що у мене немає пам’яті?


9

Я намагався виконати досить великий INSERT...SELECTобсяг у MySQL за допомогою JDBC, і я отримав таке виняток:

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

Оскільки я фактично не повертаю об’єкт ResultSet, я подумав, що пробіл у Java не повинен бути проблемою. Однак я намагався все-таки підняти це, і це нічого не принесло. Потім я спробував виконати оператор у MySQL Workbench, і я отримав по суті те саме:

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

У мене повинно бути достатньо оперативної пам’яті, щоб виконати ці операції (достатньо, щоб вмістити всю таблицю, яку я вибираю), але я здогадуюсь, що існують різні налаштування, які потрібно налаштувати, щоб скористатися всією моєю пам’яттю. Я використовую подвійний надзвичайно великий екземпляр пам'яті Amazon EC2 з великим екземпляром із Windows AMI для Windows Server 2008. Я спробував познайомитися з файлом my.ini, щоб скористатися кращими налаштуваннями, але, наскільки я знаю, я міг погіршити ситуацію. Ось дамп цього файлу:

[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

Тож це лише питання зміни вищевказаних налаштувань, щоб вони краще працювали в моєму середовищі? Якщо так, то які параметри я повинен використовувати? Я єдиний, хто коли-небудь використовує цей екземпляр; Я використовую його для особистого хобі-проекту, який включає статистичний аналіз великих наборів даних. Як такий, я вільний дозволити йому споживати всі наявні ресурси для моїх власних запитів.

Якщо проблема не в зміні цих налаштувань, у чому проблема? Дякуємо за будь-яку допомогу, яку ви можете запропонувати, як краще налаштувати все.


Усі, хто використовує кеш запитів 1g, не мають поняття, що вони роблять.

@winmutt Ви можете дуже правильно, але ваш коментар нікому не допомагає без додаткових пояснень. Чи можете ви допомогти нам, пояснивши свої почуття?
Майкл МакГоуан

Відповіді:


9

Враховуючи, що це інсталяція Windows, @DTest все ж надав початковий правильний напрямок.

Застосовуйте таку формулу:

Більшість людей використовують це:

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

Я вважаю за краще це:

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)

Ці змінні є тими, які потрібно коригувати, поки формула не приведе до 80% встановленої оперативної пам’яті або менше.

sort_buffer_size
read_buffer_size
read_rnd_buffer_size
join_buffer_size
max_connections

4

Я б спробував зменшити розміри буфера. Зробити їх такими великими, як і у вас, це спричинить проблеми. Скільки пам'яті у вас є для запуску цих значень:

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

Деякі розміри буфера виділяються на потік, наприклад, myisam_sort_buffer_size 10G виділяє 10G для кожного потоку.

Я б спершу різко зменшив ці значення, а потім дослідив, яким значенням потрібно насправді виділити стільки оперативної пам’яті (якщо така є).


4

Швидкий спосіб визначити, скільки пам’яті думає MySQL, це наступний:

wget mysqltuner.pl

perl mysqltuner.pl

Запустивши цей скрипт, він підкаже, який відсоток встановленої оперативної пам’яті MySQL вважає, що він може безпечно розподіляти. Якщо наведена відповідь перевищує 100%, вам обов'язково потрібно зменшити розміри буфера. Основний, на якому слід зосередитись, -

sort_buffer_size
read_buffer_size
read_rnd_buffer_size
join_buffer_size
max_connections
key_buffer_size (не дуже ефективний останній 4G)

@DTest вже вказав напрямок для вас у своїй відповіді, тож +1 для свого прихильника. Сценарій perl підкаже вам, що станеться, якщо ви не встановите його або зміните будь-яке значення. Ось приклад:

Мій клієнт
read_buffer_size = 128K
read_rnd_buffer_size = 256K
sort_buffer_size = 2M
join_buffer_size = 128K
max_connections = 1050

Ось вихід з mysqltuner.pl:

MySQLTuner 1.2.0 - Основні Хейден
звіти про помилки, побажання та завантаження в http://mysqltuner.com/
Run з «--help» для додаткових опцій і фільтрації виведення
ласка , введіть ваш логін MySQL адміністративний: lwdba
ласка , введіть ваш MySQL адміністративний пароль:

-------- Загальна статистика ---------------------------------------- ----------
[-] Пропущена перевірка версії для сценарію MySQLTuner
[ОК] На даний момент підтримується підтримувана версія MySQL 5.0.51a-журнал спільноти
[!!] Перехід на 64-бітну ОС - MySQL наразі не може використовувати всю вашу оперативну пам’ять

-------- Статистика двигуна зберігання --------------------------------------- ----
[-] Статус: + Архів -BDB + Federated + InnoDB -ISAM -NDBCluster
[-] Дані в таблицях MyISAM: 319M (Таблиці: 108)
[-] Дані в таблицях InnoDB: 2M (Таблиці: 5)
[!!] Всього фрагментованих таблиць: 22

-------- Показники ефективності ---------------------------------------- ---------
[-] До: 52d 23h 15m 57s (72M q [15.875 qps], 241K conn, TX: 2B, RX: 1B)
[-] Читає / пише: 59% / 41%
[-] Загальна кількість буферів: 34,0 млн глобальних + 2,7 М на потік (1050 максимум потоків)
[!!] Розміщення> 2 ГБ оперативної пам’яті в 32-бітних системах може спричинити нестабільність системи
[!!] Максимально можливе використання пам'яті: 2,8 Г (72% встановленої оперативної пам’яті)
[OK] Повільні запити: 0% (54 / 72M)
[OK] Найвище використання доступних з'єднань: 6% (65/1050)
[OK] Розмір ключового буфера / загальний індекс MyISAM: 8.0M / 82.1M
[ОК] Швидкість звернення до ключового буфера: 100,0% (4B кешування / 1М читання)
[!!] Кеш запитів вимкнено
[ОК] Сортування, що потребують тимчасових таблиць: 0% (0 темп. Сортування / 948К сортування)
[OK] Тимчасові таблиці, створені на диску: 3% (11K на диску / 380K всього)
[!!] Кеш потоку вимкнено
[!!] Швидкість удару кешу таблиці: 0% (відкрито 64 / 32К)
[ОК] Відкрити файл використаний ліміт: 2% (125 / 5К)
[ОК]
Блокування таблиць отримано негайно: 99% (30 М негайні / 30 М блокування) [ОК] Розмір даних / буферний пул InnoDB: 2,7 М / 8,0 М

-------- Рекомендації ----------------------------------------- ------------
Загальні рекомендації:
Запустіть OPTIMIZE TABLE для дефрагментації таблиць для кращої продуктивності.
Увімкніть журнал повільних запитів для усунення несправних запитів.
Встановіть thread_cache_size на 4 як вихідне значення.
Поступово збільшуйте table_cache, щоб уникнути меж дескриптора файлів
Змінні налаштувати:
query_cache_size (> = 8M)
thread_cache_size (початок з 4)
table_cache (> 64)

Зверніть увагу на показники ефективності

[-] Загальна кількість буферів: 34,0 млн. Глобальних + 2,7 М на кожну нитку (1050 максимум потоків)

що MySQL може виділити до 72% встановленої оперативної пам’яті на основі налаштувань в /etc/my.cnf.

34M базується на innodb_buffer_pool_size та key_buffer_size разом

2,7 М на потік базувався на read_buffer_size + read_rnd_buffer_size + sort_buffer_size + join_buffer_size.

Кілька 2.7M засновані на max_connections.

Тому потрібно налаштувати ці параметри до тих пір, поки у звіті про показники продуктивності не буде вказано, що у вас менше 100% (бажано, менше 80%) встановленої оперативної пам’яті.


Я не впевнений, що можу використовувати ваш інструмент; Я використовую Windows. У документації зазначалося, що Windows не підтримується, але я все-таки намагався. Коли я спробував запустити його, це вказувало, що він не може знайти mysqladmin у моєму $ PATH, але каталог бін MySQL справді є в моєму $ PATH.
Майкл МакГоуан

Вибачте, я не помітив даних Windows. Я додам іншу відповідь.
RolandoMySQLDBA

1

Ви не сказали, скільки у вас оперативної пам’яті? Я припускаю, що принаймні 32 Гб.

innodb_buffer_pool_size - 23G

Добре для стільки оперативної пам'яті.

query_cache_size = 1G

Набагато занадто великий. Це неефективно, коли він великий. Рекомендують не більше 50М.

key-buffer_size = 5G

У Windows може бути жорсткий ліміт 4G (все ще), жорсткий ліміт - 4G. Можливо, ваш 5G перетворився на 1G. У будь-якому випадку, якщо всі ваші таблиці є InnoDB, навіщо витрачати таран. Встановіть його на 50М.

Оскільки повідомлення про помилку мала рівно 1G, воно пахне схожим sort_buffer_size. 32М може бути розумним.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.