Использование памяти MySQL со многими таблицами

0

У меня есть MySQL с несколькими 100 000 таблицами. В настоящее время это лучший дизайн для моей системы, поскольку эти таблицы не связаны друг с другом, и выбор запросов будет только на одной таблице. Кроме того, пользователи, скорее всего, не будут обращаться к тем же таблицам очень часто.

У меня 16 ГБ оперативной памяти, но примерно через день MySQL потребляет около 90%, при этом общая память используется системой на 99-100%. Я пробовал много вещей, но просто не могу использовать память.

Мой innodb_buffer_pool_size в настоящее время составляет 8 ГБ, но я имел его в 1G с той же проблемой. Я также попытался уменьшить open_files_limit но это тоже не помогло.

Вот мой вывод для

SHOW GLOBAL STATUS LIKE '%Open_%';
+----------------------------+----------+
| Variable_name              | Value    |
+----------------------------+----------+
| Com_show_open_tables       | 0        |
| Innodb_num_open_files      | 431      |
| Open_files                 | 0        |
| Open_streams               | 0        |
| Open_table_definitions     | 615      |
| Open_tables                | 416      |
| Opened_files               | 4606655  |
| Opened_table_definitions   | 4598528  |
| Opened_tables              | 4661002  |
| Slave_open_temp_tables     | 0        |
| Table_open_cache_hits      | 30024782 |
| Table_open_cache_misses    | 4661002  |
| Table_open_cache_overflows | 4660579  |
+----------------------------+----------+

И вот моя конфигурация mysqld:

sql-mode=''
innodb_buffer_pool_size = 8G
open_files_limit=100000
user        = mysql
pid-file    = /var/run/mysqld/mysqld.pid
socket  = /var/run/mysqld/mysqld.sock
port        = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir  = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
bind-address        = 127.0.0.1
key_buffer_size     = 16M
max_allowed_packet  = 16M
thread_stack        = 192K
thread_cache_size       = 8
myisam-recover-options  = BACKUP
query_cache_limit   = 1M
query_cache_size        = 16M
log_error = /var/log/mysql/error.log
expire_logs_days    = 10
max_binlog_size   = 100M

Кто-нибудь знает, как эффективно обрабатывать эти тысячи таблиц?

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ

A) Mysqld: https://pastebin.com/PTiz6uRD

B) SHOW GLOBAL STATUS: https://pastebin.com/K4sCmvFz

C) SHOW GLOBAL VARIABLES: https://pastebin.com/Cc64BAUw

D) MySQLTuner: https://pastebin.com/zLzayi56

E) SHOW ENGINE INNODB STATUS: https://pastebin.com/hHDuw6gY

F) вверху: https://pastebin.com/6WYnSnPm

ИСПЫТАНИЕ ПОСЛЕ СЕРВЕРА REBOOT (ПОЛУЧЕНА МАЛЕНЬКИЙ ПАМЯТИ):

A) ulimit -a: https://pastebin.com/FmPrAKHU

B) iostat -x: https://pastebin.com/L0G7H8s4

C) df -h: https://pastebin.com/d3EttR19

D) MySQLTuner: https://pastebin.com/T3DYDLg8

  • 1
    Когда вы говорите «несколько 100 000 таблиц», вы действительно имеете в виду 300 000 таблиц? У вас проблема XY . Вы должны спросить о любой проблеме, которую вы пытаетесь решить с этим дизайном. Там, вероятно, лучший способ решить эту проблему.
  • 0
    Таблицы имеют одинаковую структуру, но пользователи выбирают все строки в таблице. Поэтому вместо одной очень большой таблицы с (миллионами записей), которая требует фильтрации с использованием WHERE для получения подмножества, я предпочитаю иметь много таблиц (каждая с несколькими тысячами записей). Затем мне нужно только выбрать таблицу и вывести все строки за один раз, без необходимости в части WHERE. Так что операторы select должны быть намного быстрее, используя вместо этого много таблиц.
Показать ещё 4 комментария
Теги:
memory-consumption

1 ответ

1
Лучший ответ

Первый блок для удаления будет в командной строке Linux, ulimit -n 124000, чтобы преодолеть текущий предел 1024 Open Files, это можно сделать СЕЙЧАС, для этого не требуется выключение/перезагрузка Linux.

Предложения по рассмотрению вашего раздела my.cnf [mysqld]

table_open_cache=10000  # from 431 available today to a practical upper limit
table_definition_cache=10000  # from 615 available today to a practical upper limit
thread_cache_size=100  # from 8 for V8 refman CAP suggested to avoid OOM
max_heap_table_size=64M  # from 16M to reduce created_tmp_disk_tables
tmp_table_size=64M  # from 16M should always be equal to max_heap_table_size
innodb_lru_scan_depth=100  # from 1024 to reduce CPU workload every SECOND
innodb_log_buffer_size=512M  # from 50M to avoid log rotation every 7 minutes

Учитывая вашу ситуацию, я бы пропустил однодневное правило и отслеживал до следующего изменения глобальной переменной. Внесите все изменения cnf. Службы Stop/start необходимы, потому что вы ограничены open_files_limit в MySQL, хотя вы запросили 100 000 ulimit, что вызвало время выполнения, чтобы ограничить вас до 1024.

Если вы скопируете вставить блок в END раздела MySQLD, удалите одинаковые именованные переменные над блоком в разделе MYSQLD, вы избавитесь от "множественной путаницы переменных" для следующего аналитика.

Пожалуйста, просмотрите профиль для контактной информации и свяжитесь с нами.

  • 0
    Я выяснил, что на моем сервере было открытое реле, и кто-то использовал его для спама. Я думаю, что это наполнило мою память MySQL. Я исправил реле, и теперь кажется, что mysql ограничен моим пределом innodb_buffer_pool_size. Будем продолжать наблюдать за этим некоторое время, чтобы увидеть, так ли это на самом деле. Спасибо за помощь.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню