Ongoing service disruptions
For the most recent update on ongoing service disruptions affecting the AWS Middle East (UAE) Region (ME-CENTRAL-1), refer to the AWS Health Dashboard. For information on AWS Service migration, see How do I migrate my services to another region?
如何对 Amazon Redshift 中磁盘使用率过高或已满的问题进行故障排除?
我在 Amazon Redshift 上遇到了磁盘利用率过高或已满的情况,想对此问题进行故障排除。
解决方法
要解决 Amazon Redshift 的高磁盘利用率问题,请按照以下故障排除步骤进行操作。
分配和排序键
查看表的分配方式、分配键和排序键选择。分配偏斜的表可能会导致磁盘节点占满。如果您的表具有偏斜的分配方式,请将分配方式更改为更均匀的分配。查询运行时,分配和行偏斜可能会影响存储偏斜和中间行集。
要获取分配键的基数,请运行以下查询:
SELECT <distkey column>, COUNT(*) FROM <schema name>.<table with distribution skew> GROUP BY <distkey column> HAVING COUNT(*) > 1 ORDER BY 2 DESC;
**注意:**请将 distkey column、schema name 和 table with distribution skew 替换为您的表变量。
要避免排序步骤,请在 ORDER BY 子句中使用排序键列。排序步骤可能会使用过多的内存并导致磁盘溢出。有关详细信息,请参阅排序键。
在筛选结果集中,选择基数高的列以查看其数据分配。有关详细信息,请参阅选择最佳的分配方式。
查询处理
查看所有分配的查询内存。当查询处理时,中间查询结果可以存储在临时块中。如果没有足够的可用内存,则这些表会导致磁盘溢出。中间结果集不压缩,这会影响可用磁盘空间。有关详细信息,请参阅分配给查询的内存不足。
Amazon Redshift 默认使用分配均匀的表结构,临时表不使用列编码。如果您使用 SELECT...INTO 语法,请使用 CREATE 语句。有关详细信息,请参阅 Top 10 performance tuning techniques for Amazon Redshift(十大 Amazon Redshift 性能优化技术)中的“Tip #6(提示 #6)”。
如果分配给查询的内存不足,则您可能会在 SVL_QUERY_SUMMARY 中看到一个步骤,其中 is_diskbased 显示值 true。以下查询确定了指定时间内前 20 个磁盘泄漏查询:
SELECT q.userid, q.query, q.starttime, q.endtime, m.query_temp_blocks_to_disk, btrim(querytxt) FROM stl_query q JOIN SVL_QUERY_METRICS_SUMMARY m ON m.query = q.query WHERE m.query_temp_blocks_to_disk > 0 AND starttime BETWEEN '2025-01-01 00:00:00' AND '2025-01-02 00:00:00' ORDER BY m.query_temp_blocks_to_disk DESC LIMIT 20;
要解决此问题,请增加查询槽的数量,为查询分配更多内存。
如果您发现利用率突然激增,请运行以下查询来确定前 20 个磁盘泄漏查询:
SELECT a.userid, a.query, a.blocks_to_disk, trim(b.text) as text FROM stv_query_metrics a, stv_inflight b WHERE a.query = b.query AND a.segment = -1 AND a.step_type = -1 AND a.max_blocks_to_disk > 0 ORDER BY 3 DESC LIMIT 20;
在输出中,查询查看列值 blocks_to_disk 以识别磁盘溢出。终止溢出过多的查询,然后为查询分配更多内存,然后再运行它们。
您还可以使用 WLM 查询监控规则来应对繁重的流程负载并识别 I/O 密集型查询。
包含 VARCHAR (MAX) 列的表
检查 VARCHAR 或 CHARACTER VARYING 列中是否存在数据存储在磁盘上时可能会省略的结尾空白。处理查询时,结尾空白会占用内存中的全部长度。VARCHAR 和 CHARACTER VARYING 的最大值为 65535 字节。最佳做法是使用尽可能小的列大小。
要生成具有最大列宽的表列表,请运行以下查询:
SELECT database, schema || '.' || "table" AS "table", max_varchar FROM svv_table_info WHERE max_varchar > 150 ORDER BY 2;
运行以下查询来识别和显示宽 VARCHAR 表列的真实宽度:
SELECT max(octet_length (rtrim(column_name))) FROM table_name;
在此查询的输出中,确认长度是否适合您的使用案例。如果列达到最大长度并超出您的需求,请将其长度调整为所需的最小大小。
有关详细信息,请参阅 Amazon Redshift 设计表的最佳实践。
高列压缩
要对除排序键之外的所有列进行编码,请使用 ANALYZE COMPRESSION 或自动表优化。最佳做法是使用列编码。
维护操作
请务必定期分析和清理您的 Amazon Redshift 数据库中的数据库表。识别针对缺少统计信息的表运行的任何查询。然后,防止对缺少统计信息的表运行查询,这样 Amazon Redshift 就不会扫描不必要的表行。
**注意:**VACUUM 和 DEEP COPY 等维护操作使用临时存储空间进行排序操作,可能会导致磁盘使用量激增。
例如,以下查询会识别 Amazon Redshift 中过时的统计信息:
SELECT table_id, database, schema, "table", stats_off, size FROM svv_table_info WHERE stats_off > 10 ORDER BY size DESC;
此外,使用 ANALYZE 命令查看和分析表统计信息。
带有交叉连接的笛卡尔乘积
使用查询的 EXPLAIN 计划来查找使用笛卡尔乘积的查询。笛卡尔乘积是无关的交叉连接,可能会增加块数。这些交叉连接可能会导致更高的内存利用率以及更多表溢出到磁盘。如果交叉连接不共享 JOIN 条件,则这些连接会生成两个表的笛卡尔乘积。一个表的每一行都连接到另一个表的每一行。
交叉连接也可以作为嵌套循环连接运行,从而导致较长的处理时间。嵌套循环连接会导致总体磁盘使用量激增。有关详细信息,请参阅确定具有嵌套循环的查询。
最小表大小
在不同的集群中,单个表的大小可能是不同的。最小表大小由列数以及表中是否有 SORTKEY 和填充的切片数量决定。如果您最近调整了 Amazon Redshift 集群的大小,则可能会看到由于切片的变化而导致的总体磁盘存储空间变化。Amazon Redshift 还会计算每个表使用的表分段。有关详细信息,请参阅为什么 Amazon Redshift 集群中的表使用的磁盘存储空间高于或低于预期?
墓碑块
当对 Amazon Redshift 表执行 WRITE 事务并存在并发读取操作时,就会生成墓碑块。Amazon Redshift 会在写入操作之前保留块,以保持并发读取操作的一致性。您无法更改 Amazon Redshift 块。每个 Insert、Update 或 Delete 操作都会创建一组新的块,并将旧块标记为墓碑块。
有时,由于表事务长时间运行,墓碑无法在提交阶段清除。当同时运行的 ETL 负载过多时,墓碑也可能无法清除。由于 Amazon Redshift 从事务开始之时起就监控数据库,因此写入数据库的任何表也会保留墓碑块。如果长时间运行的表事务定期发生并跨越多次负载,则会积累足够的墓碑,导致“Disk Full”错误。
如果有长时间运行的查询处于活动状态,请运行 commit 命令以终止查询并释放所有后续块:
begin; create table a (id int); insert into a values(1); commit; drop table a;
运行以下查询以确认墓碑块:
SELECT trim(name) as tablename, count(case when tombstone > 0 then 1 else null end) as tombstones FROM svv_diskusage GROUP BY 1 HAVING count(case when tombstone > 0 then 1 else null end) > 0 ORDER BY 2 DESC;
复制大文件
即使有足够的可用存储空间,COPY 操作也可能会收到“Disk Full”错误。如果排序操作溢出到磁盘并创建临时块,则会出现此错误。
如果您遇到“Disk Full”错误,请检查 STL_DISK_FULL_DIAG 表。检查临时块以及哪个查询 ID 导致了错误:
SELECT '2000-01-01'::timestamp + (currenttime/1000000.0)* interval '1 second' as currenttime, node_num, query_id, temp_blocks FROM stl_disk_full_diag;
有关详细信息,请参阅 Amazon Redshift 加载数据的最佳实践。
使用者集群上的数据共享查询块
当数据共享查询在使用者集群上运行时,与该查询关联的数据块将按 PercentageDiskSpaceUsed 指标进行计数。由于集群重启和其他因素,这些数据块会从 PercentageDiskSpaceUsed 指标中移除。无需对这种预期行为执行进一步的操作。
检查磁盘空间
在 Amazon Redshift 控制台上的 Performance(性能)选项卡下查看磁盘空间的百分比。
相关信息
- 语言
- 中文 (简体)
