0

我有一个包含 100,000 个表的 MySQL。这是目前对我的系统来说最好的设计,因为这些表彼此不相关,并且选择查询只会在单个表上关闭。此外,用户很可能不会经常访问相同的表。

我有 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

有人知道如何有效地处理这数千张桌子吗?

附加信息

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

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

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

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

E) 显示引擎 INNODB 状态: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) MySQLTuner:https ://pastebin.com/T3DYDLg8

4

1 回答 1

1

要删除的第一个块将在 Linux 命令行中,ulimit -n 124000 以超过 1024 个打开文件的当前限制,这可以立即完成,无需关闭/重新启动 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 更改。需要停止/启动服务,因为您在 MySQL 中被限制为 open_files_limit,即使您请求 100,000 ulimit 导致运行时将您限制为 1024。

如果您将块复制粘贴到 MySQLD 部分的 END,仅删除 MYSQLD 部分中块上方的相同命名变量,您将为下一位分析师摆脱“多变量混淆”。

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

于 2018-06-27T20:26:07.677 回答