news 2026/7/9 8:07:29

华为云DWS磁盘使用率超90%后集群只读

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
华为云DWS磁盘使用率超90%后集群只读

一、故障现象

凌晨作业调度时段,ETL任务连续报错:

二、根因分析

DWS集群规则:单数据盘使用率 ≥ 90%时,集群自动进入只读模式,default_transaction_read_only被强制打开,所有INSERT/UPDATE/DELETE/DDL全部cancel

实际排查发现:大量中间临时表(dm_tmp_*mid_*dws_tmp_*)未清理,累计占用 2TB+,单表最大超过 180GB。凌晨ETL集中写入时,磁盘使用率突破90%阈值,触发集群只读。

三、排错过程

Step 1:确认集群状态

SHOW transaction_read_only;

Step 2:扫描大表,定位"大块头"

单表大小查询:

SELECT pg_size_pretty(pg_total_relation_size('tmp.tmp_test'));

全库大表扫描(>10GB):

WITH all_table_size AS ( SELECT n.nspname AS schema_name, c.relname AS table_name, c.reltuples::BIGINT AS estimate_rows, pg_total_relation_size(c.oid)/1024/1024/1024 AS total_bytes, pg_table_size(c.oid)/1024/1024/1024 AS table_only_bytes, pg_indexes_size(c.oid)/1024/1024/1024 AS index_bytes, pg_size_pretty(pg_total_relation_size(c.oid)) AS total_size_pretty, pg_size_pretty(pg_table_size(c.oid)) AS table_size_pretty, pg_size_pretty(pg_indexes_size(c.oid)) AS index_size_pretty FROM pg_class c LEFT JOIN pg_namespace n ON c.relnamespace = n.oid WHERE c.relkind = 'r' AND n.nspname NOT IN ('pg_catalog','information_schema','pg_toast','cstore','pmk') AND n.nspname !~ '^pg_temp_' ) SELECT * FROM all_table_size WHERE total_bytes > 10 ORDER BY total_bytes DESC;

Step 3:解除只读 + 清理

必须在事务内执行,否则SET transaction_read_only = off会被集群级只读参数拦截。

方式一:显示事务关闭只读

START TRANSACTION READWRITE; DROP TABLE IF EXISTS dm.dm_tmp_xxx; TRUNCATE TABLE dm.dm_tmp_yyy; COMMIT;

方式二:设置事务只读关闭

START TRANSACTION; SET transaction_read_only = off; DROP/TRUNCATE 目标表; COMMIT;

Step 4:清理优先级

优先级清理对象动作风险P0临时表(tmp_、mid_、dm_tmp_)DROP TABLE无P1业务已废弃的备份表(_bak、_v1)DROP TABLE低P2大表历史分区DROP PARTITION中

清理目标:磁盘使用率降至80% 以下,集群自动退出只读模式。

四、踩坑记录

坑1:临时表不会自动释放

CREATE TEMP TABLE(会话级临时表)才会随连接断开释放;

CREATE TABLE dm.dm_tmp_xxx AS ...物理表,永远不会自动删除。

命名带tmp不等于临时表。

坑2:TRUNCATE不立即释放空间

DWS列存下TRUNCATE释放空间依赖底层存储回收,存在延迟;

大量数据要彻底释放,必须用DROP TABLE

坑3:VACUUM FULL会临时占更多空间

VACUUM FULL执行期间需要额外空间 ≈ 表大小 × (1 - 脏页率),最高磁盘使用率 > 70% 时必须串行清理(一张一张来),否则会再次打满磁盘。

坑4:单SQL可写满整盘

未设置sql_use_spacelimit时,单条SQL可无限制写入磁盘,是定时炸弹。

五、调优方案

作业结尾强制清理(最关键)

所有ETL作业模板末尾追加:

-- 显式删除已知临时表 DROP TABLE IF EXISTS dm.dm_tmp_step1_{biz_date}; DROP TABLE IF EXISTS dm.dm_tmp_step2_{biz_date}; -- 模糊匹配清理(兜底) DO $$ DECLARE r RECORD; BEGIN FOR r IN SELECT n.nspname, c.relname FROM pg_class c JOIN pg_namespace n ON c.relnamespace = n.oid WHERE n.nspname = 'dm' AND c.relname ~ '^dm_tmp_' AND c.relname LIKE '%{biz_date}%' LOOP EXECUTE format('DROP TABLE IF EXISTS %I.%I', r.nspname, r.relname); END LOOP; END $$;

使用真正的TEMP TABLE

中间结果只在当前会话使用时:

-- 事务级临时表(COMMIT后自动释放,最严格) CREATE TEMP TABLE tmp_step1 ON COMMIT DROP AS SELECT ...;

兜底清理作业(每日巡检)

清理>7天未访问的疑似临时表:

SELECT n.nspname || '.' || c.relname AS full_name, pg_size_pretty(pg_total_relation_size(c.oid)) AS size FROM pg_class c JOIN pg_namespace n ON c.relnamespace = n.oid JOIN pg_stat_user_tables s ON s.schemaname = n.nspname AND s.relname = c.relname WHERE n.nspname NOT IN ('pg_catalog','information_schema','pg_toast','cstore','pmk') AND (c.relname ~ '^(tmp_|temp_|mid_|dm_tmp_|dws_tmp_)' OR c.relname ~ '(_bak|_old|_v1)$') AND GREATEST(s.last_analyze, s.last_autoanalyze, s.last_vacuum, s.last_autovacuum) < (CURRENT_TIMESTAMP - INTERVAL '7 days') ORDER BY pg_total_relation_size(c.oid) DESC;

SQL空间管控参数

-- 单SQL最大可用空间(建议=磁盘总容量×10%) ALTER DATABASE dm SET sql_use_spacelimit TO '500GB'; -- 会话级临时文件限制 ALTER DATABASE dm SET temp_file_limit TO '100GB'; -- 紧急一次性写入可临时关闭 SET sql_use_spacelimit = 0;

VACUUM回收脏页

8.1.3+ 版本用智能运维(控制台 → 智能运维 → 添加 Vacuum 周期任务)。

低版本手动:

VACUUM FULL ANALYZE dm.dm_pur_pe_unclear_amount;

注意:会锁表,需低峰执行,且最高磁盘使用率 > 70% 时必须串行

六、SQL空间管控参数

重复一下,这块最重要

参数作用建议值sql_use_spacelimit单SQL最大可用空间磁盘总容量 × 10%temp_file_limit会话临时文件上限100GB

设置:

ALTER DATABASE dm SET sql_use_spacelimit TO '500GB'; ALTER DATABASE dm SET temp_file_limit TO '100GB';

七、总结

核心问题:临时表生命周期失控,凌晨ETL集中写入打爆磁盘。

三板斧

  1. 排错:显示事务START TRANSACTION READWRITE+ 删临时表,腾出空间。
  2. 踩坑:临时表要DROP不用TRUNCATE;命名带tmp不等于临时表;KILL 任务时清理语句不执行。
  3. 调优:作业末尾强制清理 + 优先用TEMP TABLE+ 每日兜底作业 + 设置sql_use_spacelimit

参考:DWS磁盘空间满处理方案

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/9 8:06:25

Windows右键菜单终极清理教程:3个简单步骤让电脑右键菜单变清爽

Windows右键菜单终极清理教程&#xff1a;3个简单步骤让电脑右键菜单变清爽 【免费下载链接】ContextMenuManager &#x1f5b1;️ 纯粹的Windows右键菜单管理程序 项目地址: https://gitcode.com/gh_mirrors/co/ContextMenuManager 你是否曾经因为右键菜单里塞满了各种…

作者头像 李华
网站建设 2026/7/9 8:04:31

大华SDK NetSDK-2.0.0.1 低延迟视频流获取:从YUV420解码到RGB转换的3步优化

大华SDK NetSDK-2.0.0.1低延迟视频流处理实战&#xff1a;从YUV420解码到RGB转换的深度优化在计算机视觉和视频监控领域&#xff0c;实时视频流处理一直是一个关键挑战。许多开发者在使用OpenCV直接拉取RTSP流时&#xff0c;常常遇到高达2秒的延迟问题&#xff0c;这对于需要实…

作者头像 李华
网站建设 2026/7/9 8:01:07

UE4SS游戏脚本工具快速实战指南:如何为游戏添加脚本功能

UE4SS游戏脚本工具快速实战指南&#xff1a;如何为游戏添加脚本功能 【免费下载链接】RE-UE4SS Injectable LUA scripting system, SDK generator, live property editor and other dumping utilities for UE4/5 games 项目地址: https://gitcode.com/gh_mirrors/re/RE-UE4SS…

作者头像 李华
网站建设 2026/7/9 7:59:51

vtkDefaultPass代码解析

vtkDefaultPass 是 VTK 渲染管线中最基础、最核心的渲染通道(Render Pass)。它实现了 VTK 标准的渲染顺序逻辑,负责将场景中的各种几何体(Props)按照正确的透明度和类型顺序绘制到屏幕上。 以下是该类的详细解析: 1. 核心职责 vtkDefaultPass 的主要任务是执行标准的“…

作者头像 李华
网站建设 2026/7/9 7:56:53

UVa 634 Polygon

题目描述 给定一个简单多边形&#xff08;边与坐标轴平行&#xff0c;但算法适用于任意简单多边形&#xff09;及其顶点坐标&#xff08;按顺序给出&#xff0c;可能是顺时针或逆时针&#xff09;&#xff0c;以及一个待检测的点 PPP。要求判断点 PPP 是否位于多边形内部&#…

作者头像 李华