mysql 大量打开的表——这是什么意思,我该如何减少?

Chr*_*nch 8 mysql

我有 300 个数据库,每个数据库最多 59 个表。我的托管服务提供商说我有很多打开的表。我没有任何性能问题;但它会导致备份问题(我使用了使用 Percona XtraBackup 的 rackspace 云数据库)

什么会导致大量开放表,我该如何减少这种情况?我没有太多的流量,性能很好。我也不确定我是否完全理解打开的表是什么。

我确实table_definition_cache设置为,4096因为在我增加它之前我无法对视图运行查询。

mysql> SHOW GLOBAL STATUS LIKE 'Open_%';
mysql> +--------------------------+----------+
    -> | Variable_name            | Value    |
    -> +--------------------------+----------+
    -> | Open_files               | 7        |
    -> | Open_streams             | 0        |
    -> | Open_table_definitions   | 4102     |
    -> | Open_tables              | 4096     |
    -> | Opened_files             | 44025318 |
    -> | Opened_table_definitions | 1660409  |
    -> | Opened_tables            | 1857375  |
    -> +--------------------------+----------+
Run Code Online (Sandbox Code Playgroud)

以下是请求的命令:

https://gist.github.com/blasto333/aa4241a4e37447961188356719ea6984

Ric*_*mes 7

table_open_cache 是最有可能让主人失望的设置。

SHOW VARIABLES LIKE '%open%';STATUS被捕获 时系统已经运行了多长时间?(需要“每秒”,而不是绝对计数。)

给我提供 ram 大小,SHOW VARIABLES以及SHOW GLOBAL STATUS;我会批评几十件事。

有表PARTITIONed吗?(每个“分区”实际上是一个单独的“表”。)

另外,重新考虑您的 300x59;这些是相当大的数字。

变量和状态分析

观察: 版本:5.6.17-log;4 GB 内存;正常运行时间 = 145d 22:45:14; 您不是在 Windows 上运行;运行64位版本;您似乎完全(或大部分)在运行 InnoDB。

更重要的问题

key_buffer_size -- 降低到 20M;您的 400M 正在浪费 RAM。

table_open_cache 似乎做得很好。所以,我认为没有必要增加打开文件限制。(也没有任何伤害。)

大量的表扫描等。建议您将long_query_time 降低到1 并打开slow_query_log。然后我们可以查看慢日志中哪些查询需要改进——通过复合索引或其他技术。

expire_logs_days 当前为 1。这意味着您只有一天的时间才能在丢失信息之前发现复制和/或二进制日志中的某些内容已损坏。

删除大部分或所有 OPTIMIZE TABLE 调用。

细节和其他观察

( Opened_tables ) = 0.15/second -- 这是一个相当低且相当可观的速率。毕竟,您已经上涨了 20 周,这是一个“计数器”。向托管服务提供商指出 20 周。table_open_cache 是缓存中“打开”表的条目数。也许在备份期间有一阵打开,但其余时间没有打开?至于“我确实将 table_definition_cache 设置为 4096,因为在增加它之前我无法对视图运行查询。” -- 您的 VIEW 是否涉及数百或数千个表?(哎呀!)

( (key_buffer_size - 1.2 * Key_blocks_used * 1024) / _ram ) = (400M - 1.2 * 4180 * 1024) / 4096M = 9.6% -- 在 key_buffer 中浪费的 RAM 百分比。-- 减少 key_buffer_size。

( Key_blocks_used * 1024 / key_buffer_size ) = 4,180 * 1024 / 400M = 1.0% -- key_buffer 使用的百分比。高水位。-- 降低 key_buffer_size 以避免不必要的内存使用。

( innodb_buffer_pool_size / _ram ) = 2,306,867,200 / 4096M = 53.7% -- 用于 InnoDB buffer_pool 的 RAM 百分比 -- 对于仅 4GB 的 RAM,这可能没问题,除非您在同一服务器中有其他应用程序。

( table_open_cache ) = 4,096 -- 要缓存的表描述符的数量 -- 通常几百个就可以了。但是,您有很多表,因此,这可能没问题,甚至太小。

( table_open_cache_instances ) = 1 -- 建议改为8。

Table_open_cache_overflows 和 _misses 均小于 0.1/秒。-- table_open_cache 足够大。

( Open_tables / table_open_cache ) = 100% -- 但是,既然你已经 Up 几个月了,这不一定是坏事。

( (Com_show_create_table + Com_show_fields) / Questions ) = (153314 + 9291657) / 543294681 = 1.7% -- Naughty 框架 -- 花费大量精力重新发现模式。-- 向第 3 方供应商投诉。

查询缓存 - 各种 STATUS 值表明它目前相当不错。

( Created_tmp_disk_tables / (Created_tmp_disk_tables + Created_tmp_tables) ) = 10,616,310 / (10616310 + 13112655) = 44.7% -- 溢出到磁盘的临时表百分比 -- 可能会增加 tmp_heap_size; 避免斑点等。

( Com_rollback / Com_commit ) = 646,634 / 1329015 = 48.7% -- 回滚:提交率 -- 回滚成本高;改变应用逻辑

( Select_scan ) = 16,557,535 / 12609914 = 1.3 /sec -- 全表扫描 -- 添加索引/优化查询(除非它们是小表)

( Select_scan / Com_select ) = 16,557,535 / 57256550 = 28.9% -- 执行全表扫描的选择百分比。(可能会被存储例程所迷惑。) -- 添加索引/优化查询

( ( Com_stmt_prepare - Com_stmt_close ) / ( Com_stmt_prepare + Com_stmt_close ) ) = ( 1587 - 1526 ) / ( 1587 + 1526 ) = 2.0% -- 你要关闭准备好的语句吗?-- 添加关闭。

( binlog_format ) = MIXED -- 语句/行/混合。ROW 优先;它可能会成为默认值。

( expire_logs_days ) = 1 -- 多久自动清除binlog(这么多天后) -- 太大(或零)=消耗磁盘空间;太小 = 需要快速响应网络/机器崩溃。

( slow_query_log ) = OFF -- 是否记录慢查询。(5.1.12)

( long_query_time ) = 10.000000 = 10 -- 定义“慢”查询的截止时间(秒)。-- 建议 2

( max_connect_errors ) = 10,000 -- 针对黑客的小保护。——也许不超过200。

( Connections ) = 28,367,185 / 12609914 = 2.2 /sec -- Connections -- 增加wait_timeout; 使用池化?

( Max_used_connections / max_connections ) = 167 / 410 = 41% -- 建议将 max_connections 降低到,比如说,200。

( innodb_io_capacity_max ) = 800 -- 这相当低,但也许还可以。

( report_port ) = 1 -- 这可能很糟糕,但我没有更具体的经验。大多数人将其留在 3306。

Com_create_db 每 4 分钟一次, Com_drop_db 每 2 分钟一次 -- 非常高;这是怎么回事?

Com_optimize = 4.9/hour -- OPTIMIZE 几乎没用,尤其是在 InnoDB 上。


mys*_*ser 1

如果您使用的是 MyISAM,请转换为 InnoDB,您可能会看到此计数有所下降。除非您停止查询它们,否则没有其他方法可以减少这种情况。

增加 table_open_cache 和 table_definition_cache 并观察统计数据...尽可能提高此值!可能您还需要增加系统文件处理程序,这是一种可行的方法。