Почему 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 Server 2008 AMI. Я попытался поиграться с файлом 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 Вы вполне можете быть правы, но ваш комментарий никому не поможет без дальнейших объяснений. Не могли бы вы помочь нам, объяснив свои чувства?
— Майкл Макгоуэн

Удобный инструмент для начала работы - tools.percona.com/wizard
— KCD

Ответы:


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 - Отчеты об основных
ошибках Hayden , запросы функций и загрузки по адресу http://mysqltuner.com/
Запустите с «--help» для дополнительных опций и фильтрации выходных данных.
Пожалуйста, введите свой административный логин MySQL: lwdba
Пожалуйста, введите свой административный MySQL пароль:

-------- Общая статистика ---------------------------------------- ----------
[-] Проверка пропущенной версии для сценария MySQLTuner
[OK] В настоящее время работает поддерживаемая версия MySQL 5.0.51a-community-log
[!!] Переключиться на 64-разрядную ОС - MySQL в настоящее время не может использовать вся ваша оперативная память

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

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

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

Пожалуйста, обратите внимание на показатели производительности

[-] Общее количество буферов: 34.0M глобально + 2.7M на поток (максимум 1050 потоков)

что MySQL может выделить до 72% установленной оперативной памяти в зависимости от настроек в /etc/my.cnf.

34M основан на сочетании innodb_buffer_pool_size и key_buffer_size

2.7M на поток основывалось на read_buffer_size + read_rnd_buffer_size + sort_buffer_size + join_buffer_size.

Кратные 2.7M основаны на max_connections.

Поэтому вы должны настроить эти параметры до тех пор, пока в отчете метрик производительности не будет указано, что у вас установлено менее 100% (предпочтительно менее 80%) установленной оперативной памяти.


Я не уверен, что смогу использовать твой инструмент; Я использую Windows. В документации упоминается, что Windows не поддерживается, но я все равно попробовал. Когда я попытался запустить его, он указал, что не может найти mysqladmin в моем $ PATH, но каталог bin в MySQL действительно находится в моем $ PATH.
— Майкл МакГоуэн

Извините, я не заметил данные Windows. Я добавлю другой ответ.
— RolandoMySQLDBA

1

Вы не сказали, сколько у вас оперативной памяти? Я предполагаю, что это по крайней мере 32 ГБ.

innodb_buffer_pool_size - 23G

Хорошо для этого много оперативной памяти.

query_cache_size = 1G

Слишком большой. Это неэффективно, когда оно большое. Рекомендую не более 50М.

key-buffer_size = 5G

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

Поскольку сообщение об ошибке было ровно 1G, оно пахнет как sort_buffer_size. 32M может быть разумным.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.