当前位置: 首页 > news >正文

Aurora RDS MySQL The table ‘/rdsdbdata/tmp/#sql14b_df16d_1bd‘ is full

关键词:AWS RDS、MySQL、临时表溢出、The table is full、SQL 优化、JOIN 重构、窗口函数性能
适用场景:Java 后端开发、DBA、运维工程师、定时任务系统维护者
环境:AWS RDS for MySQL(5.7/8.0)、Spring Boot + MyBatis、XXL-JOB 定时任务

一个每日执行的发货邮件通知定时任务(WorkDaySendShipmentEmailJob)突然失败。查看日志,发现如下关键错误:

ERROR ... - workDaySendShipmentEmailJob error:
org.springframework.jdbc.UncategorizedSQLException:
### Error querying database.  
Cause: java.sql.SQLException: (conn=913773) The table '/rdsdbdata/tmp/#sql14b_df16d_1bd' is full
...
error code [1114]; (conn=913773) The table '/rdsdbdata/tmp/#sql14b_df16d_1bd' is full

这表示 MySQL 在执行查询时使用的临时表空间(tmpdir)已满,无法继续创建或写入临时表。在 AWS RDS for MySQL 环境中,这是非常典型的性能/资源瓶颈问题。

一、错误原因分析

错误本质:临时表(Temporary Table)溢出

在执行复杂 SQL 时,MySQL 会使用内存或磁盘上的临时表来存储中间结果。当数据量过大,超出 tmpdir 可用空间(RDS 中为 /rdsdbdata/tmp/),就会抛出:

Error 1114: The table ‘xxx’ is full

尤其在以下操作中极易触发:

  • DISTINCT
  • GROUP BY / ORDER BY 非索引字段
  • 多表 JOIN 导致结果集爆炸
  • 窗口函数(如 ROW_NUMBER()
  • 子查询物化(Materialization)

而我们的 SQL 正好“集齐”了所有高危操作!

原始SQL :

SELECT DISTINCT...,CASE WHEN pn.creation_date ... THEN ... END AS paymentStatus,...
FROM task_shipment ts
INNER JOIN task_network_delivery_record tndr ON ...
LEFT JOIN project_network pn ON ...
LEFT JOIN project p ON ...
-- ⚠️ 重复 JOIN 同一张表 5 次!
LEFT JOIN project_network_milestone pnm  ON ... milestone='3A'
LEFT JOIN project_network_milestone pnm2 ON ... milestone='3B'
LEFT JOIN project_network_milestone pnm3 ON ... milestone='3B2'
LEFT JOIN project_network_milestone pnm4 ON ... milestone='3P'
LEFT JOIN milestone_sap_retry msr ON ... milestone='3X'
-- ⚠️ 窗口函数子查询
LEFT JOIN (SELECT ..., ROW_NUMBER() OVER (PARTITION BY network_number, delivery_group ...) AS rnFROM network_delivery_info
) ndi ON ...
WHERE ts.create_time BETWEEN ? AND ?

数据规模:核心表均达 数百万行task_shipmentproject_network_milestone 等)。

即使单表不大,但多重 JOIN + 函数计算 + 无有效过滤,导致中间结果轻松突破千万行,临时表直接撑爆。

优化策略:从“治标”到“治本”

生产保命妙招

扩大 临时表大小:

temptable_max_ram:限制临时表最多可以使用多少内存.

temptable_max_mmap:当内存用尽时,临时表可使用多少磁盘空间作为缓存

【参考文档】:

【1】 https://docs.amazonaws.cn/zh_cn/AmazonRDS/latest/AuroraUserGuide/aurora-mysql-write-forwarding.html 【2】 https://docs.amazonaws.cn/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Managing.Performance.html#AuroraMySQL.Managing.TempStorage 【3】 https://repost.aws/knowledge-center/rds-aurora-mysql-table-storage-issues

1. 【核心】合并重复 JOIN:用聚合替代多次连接

问题:对 project_network_milestone 表按不同 milestone 值 JOIN 5 次,极易产生笛卡尔积。

优化后

LEFT JOIN (SELECT network_number,MAX(CASE WHEN milestone = '3A'  THEN actual_date END) AS actual_date_3A,MAX(CASE WHEN milestone = '3B'  THEN actual_date END) AS actual_date_3B,MAX(CASE WHEN milestone = '3B2' THEN actual_date END) AS actual_date_3B2,MAX(CASE WHEN milestone = '3P'  THEN actual_date END) AS actual_date_3P,MAX(CASE WHEN milestone = '3X'  THEN success END)     AS success_3XFROM project_network_milestoneWHERE deleted = '0' OR deleted IS NULLGROUP BY network_number
) pnm_agg ON pnm_agg.network_number = pn.network_number

效果:只需扫描一次里程碑表,避免 5 倍中间结果膨胀。


2. 优化窗口函数子查询

原写法:

LEFT JOIN (SELECT ..., ROW_NUMBER() OVER (PARTITION BY network_number, delivery_group ORDER BY id DESC) AS rnFROM network_delivery_info WHERE deleted = 0
) ndi ON ndi.rn = 1

建议

  • 添加复合索引加速分区取最新:

    CREATE INDEX idx_ndi_lookup 
    ON network_delivery_info (network_number, delivery_group, id DESC);
    
  • 若业务允许,加时间范围过滤(如近 6 个月)。


3. 避免字段函数转换,让索引生效

原条件:

STR_TO_DATE(pn.creation_date, '%Y%m%d') > STR_TO_DATE('20250614', '%Y%m%d')

问题:无法使用索引,每行都要计算。

解决方案

  • 长期:将 creation_date 改为 DATE 类型。

  • 短期(MySQL 8.0+):创建函数索引:

    CREATE INDEX idx_pn_creation_expr 
    ON project ((STR_TO_DATE(creation_date, '%Y%m%d')));
    

4. 谨慎使用 DISTINCT

检查是否因 JOIN 不精确导致重复。若可通过主键关联或聚合消除重复,则应移除 DISTINCT,大幅降低排序与临时表开销。


5. 分批次处理大数据查询

即使优化后,若 create_time 范围过大(如查整周),仍可能超限。

推荐做法

  • 定时任务每次只处理 1 小时或 1 天 的数据
  • 应用层循环调用小窗口查询
// 伪代码
for (LocalDateTime windowStart = start; windowStart.isBefore(end); ) {LocalDateTime windowEnd = windowStart.plusHours(1);job.execute(windowStart, windowEnd);windowStart = windowEnd;
}

优化前后对比

指标优化前优化后
执行状态失败(临时表满)成功
执行时间< 10 秒(原预估 > 2 分钟)
临时表大小> 10GB(估算)< 500MB
RDS CPU/IOPS高峰飙升平稳

经验总结

  1. 不要迷信“几百万行不算大” —— 复杂查询会让中间结果指数级增长。
  2. RDS 的 tmp 空间是隐形瓶颈,无法直接扩容,必须从 SQL 入手。
  3. 重复 JOIN 同一张表是性能杀手,优先考虑聚合展开。
  4. 分页 or 分批 是处理大数据定时任务的黄金法则。
  5. EXPLAIN 是你的朋友:重点关注 Using temporary; Using filesort
http://www.dtcms.com/a/600658.html

相关文章:

  • 手机响应式网站怎么做how to use wordpress
  • 网易云音乐回应“不适配鸿蒙”:推动相关部门加快步伐
  • C语言在线编译练习 | 提高编程技能与实战能力
  • 人工智能分支——深度学习、机器学习与神经网络初概览
  • C++ STL 关联式容器:map 与 set 深度解析与应用实践
  • 鄂尔多斯网站制作 建设推广网站建设前台功能
  • 策划书模板免费下载的网站免费获客平台
  • 如何搭建IoT机器视觉
  • 几分钟学会飞书多维表格开发
  • 11.12 脚本APP 手机如何开发简单APP
  • C++17常用新特性
  • oj题 ——— 链式二叉树oj题
  • 数据库项目实战五
  • Python调用Java接口失败(Java日志打印警告:JSON parse error:xxxx)
  • 没有网站如何做SEO推广有用吗怎么不花钱自己开网店
  • ArkTS分布式设计模式浅析
  • 倍福PGV100-F200A-R4-V19使用手册
  • FD2000/4的UEFI编译和烧录文件打包过程记录
  • 微信小程序map自定义气泡customCallout
  • 如何在ubuntu调用exe文件
  • Polar MISC (中)
  • 《理解数据在内存中的存储 --- 解密数据在计算机底层的存储秘密》
  • 兰州网站建设公网站可以换虚拟主机吗
  • 营销型网站建设评价深圳福田住房和建设局网站官网
  • 遍历访问阿里云节点下的所有文件信息并写入excel文件
  • 平台消息推送(go)
  • uniapp集成爱山东获取用户信息
  • Python编程实战 - Python实用工具与库 - 操作Excel:openpyxl / pandas
  • 开展我国电子网站建设wordpress表白
  • Java 在 Excel 中添加或删除批注:Spire.XLS for Java 实践指南