MySQL 多个表的内存使用情况

MySQL Memory Usage with many Tables

我有一个 MySQL 有几个 100,000 tables。这是目前我系统的最佳设计,因为这些 table 彼此不相关,并且 select 查询只会在单个 table 上关闭。此外,用户很可能不会经常访问相同的 table。

我有 16GB RAM,但大约一天后,MySQL 消耗了大约 90%,系统的总内存使用率为 99-100%。我尝试了很多东西,但就是无法降低内存使用量。

我的 innodb_buffer_pool_size 目前是 8GB,但我的是 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

有人知道如何有效地处理这数千个 table 吗?

附加信息

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

B) 显示全局状态:https://pastebin.com/K4sCmvFz

C) 显示全局变量:https://pastebin.com/Cc64BAUw

D) MySQL调谐器:https://pastebin.com/zLzayi56

E) 显示引擎创新状态:https://pastebin.com/hHDuw6gY

F) 顶部:https://pastebin.com/6WYnSnPm

服务器重启后测试(消耗的内存很少):

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

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

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

D) MySQL调谐器:https://pastebin.com/T3DYDLg8

要删除的第一个块将在 Linux 命令行中, ulimit -n 124000 超过 1024 个打开文件的当前限制 现在可以完成,不需要 Linux 的 shutdown/restart 即可激活。

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 需要服务,因为您在 MySQL 中被限制为 open_files_limit,即使您请求 100,000 ulimit 导致运行时将您限制为 1024。

如果您将块复制粘贴到 MySQLD 部分的末尾, 仅删除 MYSQLD 部分中块上方的相同命名变量, 您将为下一位分析师摆脱 'multiple variable confusion'。

请查看个人资料以获取联系信息并取得联系。