如何查看 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_size
和 tmp_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_size
和 tmp_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 -- TEXT
、BLOB
、@variables
、UNION
,等等(更多细节在 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%,我建议降低它,即使它会伤害一些查询。
我看到有大量 internal temporary disk tables 被写入。我可以通过 SHOW GLOBAL STATUS where Variable_name like 'Created_tmp_disk_tables'
.
我知道我可以更新 max_heap_table_size
和 tmp_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_size
和 tmp_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 -- TEXT
、BLOB
、@variables
、UNION
,等等(更多细节在 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%,我建议降低它,即使它会伤害一些查询。