跳至内容

如何对 Amazon Redshift 中磁盘使用率过高或已满的问题进行故障排除?

3 分钟阅读
0

我在 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 columnschema nametable 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 列中是否存在数据存储在磁盘上时可能会省略的结尾空白。处理查询时,结尾空白会占用内存中的全部长度。VARCHARCHARACTER 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 就不会扫描不必要的表行。

**注意:**VACUUMDEEP 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 块。每个 InsertUpdateDelete 操作都会创建一组新的块,并将旧块标记为墓碑块。

有时,由于表事务长时间运行,墓碑无法在提交阶段清除。当同时运行的 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(性能)选项卡下查看磁盘空间的百分比

相关信息

Amazon Redshift 性能

AWS 官方已更新 8 个月前