skills/skills.netease.im/sparksql-error-analyzer

sparksql-error-analyzer

SKILL.md

Spark SQL Error Analyzer

分析 Spark SQL 报错日志,识别错误原因并提供解决方案代码。

使用场景

  • 分析 Spark SQL 执行异常
  • 解析报错日志并提供修复方案
  • 优化 SQL 语句解决性能问题
  • 处理语法错误和逻辑错误

输入格式

用户提供以下信息:

  1. 错误日志 (error_log): Spark SQL 的报错日志或异常堆栈
  2. SQL 语句 (sql_statement): 出错的 SQL 语句

分析流程

步骤 1: 解析错误日志(使用脚本)

使用 scripts/parse_sparksql_error.py 脚本自动解析错误日志:

# 方式 1: 从文件读取
python scripts/parse_sparksql_error.py error.log sql_query.sql

# 方式 2: 从标准输入读取
echo '<错误日志内容>' | python scripts/parse_sparksql_error.py -

脚本输出 JSON 格式的解析结果,包含:

  • error_type: 错误类型
  • error_code: 错误代码
  • error_message: 错误描述
  • root_cause: 根本原因
  • affected_objects: 涉及的表、列等
  • suggestions: 修复建议列表
  • sql_analysis: SQL 结构分析(如果提供了 SQL 文件)

手动解析要点

  1. 识别错误类型和关键信息:

    • 异常类型(如 AnalysisException, ParseException, SparkException
    • 错误代码(如 TABLE_OR_VIEW_NOT_FOUND, COLUMN_NOT_FOUND
    • 错误位置(行号、列名、表名等)
    • 根本原因(Root Cause)
  2. 常见错误类型分类:

    错误类型 典型特征 常见原因
    语法错误 ParseException SQL 语法不正确、关键字拼写错误
    分析错误 AnalysisException 表/列不存在、类型不匹配
    运行时错误 SparkException 数据问题、内存不足、执行超时
    资源错误 OutOfMemoryError 数据倾斜、分区不当

步骤 2: 分析 SQL 语句

使用脚本分析

# 在 Python 中调用分析函数
from scripts.parse_sparksql_error import analyze_sql_structure

sql_info = analyze_sql_structure("SELECT * FROM users WHERE age > 18")
print(sql_info)
# 输出: {
#   'sql_type': 'SELECT',
#   'tables': ['users'],
#   'joins': [],
#   'aggregations': [],
#   'potential_issues': ['建议添加 LIMIT 限制返回行数']
# }

手动分析要点

  1. 检查 SQL 结构:

    • SELECT / JOIN / WHERE / GROUP BY / ORDER BY 等子句
    • 子查询和嵌套查询
    • 窗口函数和聚合函数
    • UDF 使用
  2. 识别潜在问题:

    • 隐式类型转换
    • 笛卡尔积风险
    • 数据倾斜迹象
    • 性能瓶颈

步骤 3: 生成分析报告

输出结构化的分析结果:

## 错误分析

### 错误类型
[具体错误类型]

### 错误原因
[详细解释错误产生的根本原因]

### 涉及对象
- 表: [表名列表]
- 列: [列名列表]
- 函数: [函数名列表]

## 解决方案

### 方案 1: [方案标题]
**适用场景**: [说明适用情况]

**修复代码**:
```sql
[修复后的 SQL 代码]

说明: [详细解释修复原理]

方案 2: [备选方案,如有]

...

预防措施

  • [建议 1]
  • [建议 2]
  • [建议 3]

## 常见错误模式与解决方案

### 1. 表或视图不存在 (TABLE_OR_VIEW_NOT_FOUND)

**错误特征**:

AnalysisException: [TABLE_OR_VIEW_NOT_FOUND] The table or view xxx cannot be found


**解决方案**:
- 检查表名拼写
- 确认数据库/Schema 正确
- 使用 `SHOW TABLES` 验证表存在
- 添加数据库前缀: `database.table`

### 2. 列不存在 (COLUMN_NOT_FOUND)

**错误特征**:

AnalysisException: [COLUMN_NOT_FOUND] Column 'xxx' does not exist


**解决方案**:
- 检查列名拼写
- 使用 `DESCRIBE table_name` 查看可用列
- 检查是否使用了别名后引用原列名

### 3. 类型不匹配 (DATATYPE_MISMATCH)

**错误特征**:

AnalysisException: [DATATYPE_MISMATCH] Cannot resolve column due to data type mismatch


**解决方案**:
- 使用 `CAST(column AS type)` 进行显式转换
- 检查 JOIN 条件的类型一致性
- 处理 NULL 值

### 4. 内存不足 (OutOfMemoryError)

**错误特征**:

java.lang.OutOfMemoryError: Java heap space


**解决方案**:
- 增加 executor 内存
- 优化数据分区
- 使用 `spark.sql.adaptive.enabled=true`
- 减少数据倾斜

### 5. 数据倾斜

**错误特征**:

Task xxx failed due to data skew

或执行极慢,某些 task 耗时过长

**解决方案**:
- 添加盐值 (salt) 打散热点 key
- 使用两阶段聚合
- 调整分区数

## 最佳实践

### SQL 编写建议
1. 使用显式 JOIN 语法,避免隐式 JOIN
2. 尽早过滤数据(谓词下推)
3. 避免 SELECT *,只选择需要的列
4. 合理使用分区裁剪

### 性能优化建议
1. 大表 JOIN 时确保分区/桶策略合理
2. 使用广播 JOIN 处理小表
3. 避免在 WHERE 中对列进行函数操作
4. 合理使用缓存 `CACHE TABLE`

### 调试技巧
1. 使用 `EXPLAIN` 查看执行计划
2. 使用 `EXPLAIN EXTENDED` 查看详细计划
3. 开启 `spark.sql.adaptive.enabled` 自动优化
4. 查看 Spark UI 分析 task 分布

## 示例

### 示例 1: 列不存在错误

**输入**:
- 错误日志: `AnalysisException: [COLUMN_NOT_FOUND] Column 'user_id' does not exist`
- SQL: `SELECT user_id, name FROM users`

**分析输出**:
```markdown
## 错误分析

### 错误类型
AnalysisException - COLUMN_NOT_FOUND

### 错误原因
SQL 中引用的列 `user_id` 在表 `users` 中不存在

### 涉及对象
- 表: users
- 列: user_id (不存在的列)

## 解决方案

### 方案 1: 修正列名
**适用场景**: 列名拼写错误

**修复代码**:
```sql
-- 先查看表结构
DESCRIBE users;

-- 假设正确的列名是 id
SELECT id, name FROM users;

说明: 使用 DESCRIBE 命令确认表的实际列名,然后修正 SQL 中的列引用。

预防措施

  • 编写 SQL 前先查看表结构
  • 使用 IDE 的自动补全功能
  • 建立数据字典文档

### 示例 2: 类型不匹配错误

**输入**:
- 错误日志: `AnalysisException: [DATATYPE_MISMATCH] Cannot resolve 'date_col' due to data type mismatch`
- SQL: `SELECT * FROM logs WHERE date_col > '2024-01-01'`

**分析输出**:
```markdown
## 错误分析

### 错误类型
AnalysisException - DATATYPE_MISMATCH

### 错误原因
`date_col` 列的类型与字符串 '2024-01-01' 不匹配,可能是数值类型或日期类型不匹配

### 涉及对象
- 表: logs
- 列: date_col

## 解决方案

### 方案 1: 显式类型转换
**适用场景**: date_col 是 DATE/TIMESTAMP 类型

**修复代码**:
```sql
SELECT * FROM logs WHERE date_col > DATE '2024-01-01';
-- 或
SELECT * FROM logs WHERE date_col > CAST('2024-01-01' AS DATE);

方案 2: 转换为字符串比较

适用场景: date_col 是字符串类型,存储格式为 'yyyy-MM-dd'

修复代码:

SELECT * FROM logs WHERE date_col > '2024-01-01';
-- 确保格式一致

预防措施

  • 定义表时使用合适的类型
  • 比较时确保类型一致
  • 避免隐式类型转换

## 脚本使用指南

### parse_sparksql_error.py 完整用法

```bash
# 基本用法 - 只分析错误日志
python scripts/parse_sparksql_error.py error.log

# 完整用法 - 同时分析错误日志和 SQL
python scripts/parse_sparksql_error.py error.log query.sql

# 从管道输入错误日志
cat error.log | python scripts/parse_sparksql_error.py -

# 直接在命令行传入错误日志
echo "AnalysisException: [COLUMN_NOT_FOUND] Column 'xxx' does not exist" | python scripts/parse_sparksql_error.py -

脚本功能

  1. 错误解析 (SparkSQLErrorParser 类):

    • 自动识别 10+ 种常见 Spark SQL 错误
    • 提取错误代码、类型、涉及对象
    • 生成针对性的修复建议
  2. SQL 分析 (analyze_sql_structure 函数):

    • 识别 SQL 类型 (SELECT/INSERT/UPDATE/DELETE 等)
    • 提取涉及的表名、JOIN 类型、聚合函数
    • 检测潜在问题 (SELECT *、隐式 JOIN 等)
  3. 输出格式:

    {
      "error_analysis": {
        "error_type": "AnalysisException",
        "error_code": "COLUMN_NOT_FOUND",
        "error_message": "列不存在",
        "root_cause": "...",
        "affected_objects": {
          "tables": [],
          "columns": ["xxx"]
        },
        "suggestions": [...]
      },
      "sql_analysis": {
        "sql_type": "SELECT",
        "tables": ["users"],
        "potential_issues": [...]
      }
    }
    

注意事项

  1. 隐私保护: 分析时注意隐藏敏感数据(如用户 ID、手机号等)
  2. 上下文理解: 结合业务逻辑理解 SQL 意图
  3. 多方案提供: 复杂问题提供多个解决方案供选择
  4. 验证建议: 建议用户在小数据集上验证修复方案
  5. 脚本依赖: 脚本使用 Python 3 标准库,无需额外安装依赖
Installs
1
First Seen
Apr 14, 2026