如何查看 MySQL 内部 innodb 临时表的大小

How to see size of MySQL internal innodb temporary tables

我看到有大量 internal temporary disk tables 被写入。我可以通过 SHOW GLOBAL STATUS where Variable_name like 'Created_tmp_disk_tables'.

查看计数

我知道我可以更新 max_heap_table_sizetmp_table_size 来帮助防止这种情况发生,但是在不知道写入磁盘的表的大小的情况下,很难知道要使用什么值。

有人知道如何找到这个值吗?

只是查看文档,假设仅仅知道表的数量是不够的(查看 Created_tmp_tables),变量 tmpdir would give you the location of the directory storing these tables. Lowering tmp_table_size 应该确保在磁盘上创建临时表,所以你可以看看尺码。

这不容易得到。在 Percona Server 中,有一些选项可以在慢速查询日志中添加额外的信息,显示 temp tables 的大小(参见 https://www.percona.com/doc/percona-server/5.7/diagnostics/slow_extended.html

# User@Host: mailboxer[mailboxer] @  [192.168.10.165]
# Thread_id: 11167745  Schema: board
# Query_time: 1.009400  Lock_time: 0.000190  Rows_sent: 4  Rows_examined: 1543719  Rows_affected: 0  Rows_read: 4
# Bytes_sent: 278  Tmp_tables: 0  Tmp_disk_tables: 0  Tmp_table_sizes: 0
# QC_Hit: No  Full_scan: Yes  Full_join: No  Tmp_table: No  Tmp_table_on_disk: No
# Filesort: No  Filesort_on_disk: No  Merge_passes: 0

(上面的示例取自 Percona 文档,显示了扩展字段,尽管该示例是针对未创建临时 tables 的查询,因此大小显示为 0。)

在 Oracle MySQL 中,一些相同的扩展信息在 PERFORMANCE_SCHEMA— 的查询事件中可用,但临时 table 大小不可用。

2014 年,我记录了一个功能请求以提供此信息:https://bugs.mysql.com/bug.php?id=74484 并且此错误已得到确认,但据我所知尚未实施。

有点不清楚这将如何实现,因为任何给定的查询都可以创建 多个 个不同大小的临时 table。我相信 Percona 功能会在这种情况下显示临时 table 大小的总和。

我所能提供的建议是逐步增加 max_heap_table_sizetmp_table_size,并监控 SHOW GLOBAL STATUS 报告的 Created_tmp_disk_tables 的增长率,与 Created_tmp_tables(未使用磁盘的临时 tables 相比)。由于允许的 tmp table 大小能够容纳更大比例的临时 tables 创建,您应该开始查看磁盘上临时 tables 与内存中临时的比率tables 减少。

通常不需要增加 tmp_table_size 来保持 每个 可能的温度 table,无论温度有多大。您希望最大的离群值使用磁盘。但只要 temp tables 在 98% 的时间里使用内存,你应该没问题。这意味着 Created_tmp_disk_tables 与 Created_tmp_tables 的比率应该是 1:50 或更多。

(比尔回答的附录。)

在 5.7 和 8.0 中对 tmp tables 的处理进行了一些重大更改。我不确定它们是否适用于此处,但请注意。

超过 tmp_table_size 并不是使用基于磁盘的临时文件的唯一原因 table -- TEXTBLOB@variablesUNION,等等(更多细节在 https://dev.mysql.com/doc/refman/5.7/en/internal-temporary-tables.html 中)因此,我会质疑 Bill 的 1:50 建议。

Tmp tables(磁盘上或内存中)可以通过大量查询创建;复杂查询可能需要多个 tmp tables。因此,同时 tmp tables 的数量 可能 多于 max_connections。出于这个原因,我建议将 tmp_table_size 保持在可用 RAM 的 1% 以下。如果你确实有一个高设置 并且 需要大量的同步 tmp tables,你可能会导致交换,这对性能来说非常糟糕。

Created_tmp*tables 有很多 "fixes";太多了,无法在这里一一列举。如果您想提出一个查询(以及相关的 SHOW CREATE TABLEs);我们可以讨论那个特殊情况。

analyzing一个客户的系统时,我会寻找诸如

之类的东西
Created_tmp_disk_tables > 1/second
Created_tmp_disk_tables > 4% of queries
Created_tmp_tables > 20/second

在我看来,其中任何一个都表明需要对慢速查询进行审查。但是如果 tmp_table_size 大于 RAM 的 1%,我建议降低它,即使它会伤害一些查询。