BenchmarkSQL 测试 PostgreSQL 时遇到 numeric field overflow 报错的原因与解决方案
现象描述
在使用 BenchmarkSQL 对 PostgreSQL 进行长时间 TPC-C 性能测试时,部分用户会遇到如下报错:
ERROR: numeric field overflow
该错误通常出现在测试运行一段时间后,导致部分事务失败,影响测试的连续性和准确性。
原因分析
-
表字段类型与TPC-C规范不符
- BenchmarkSQL 的 TPC-C 测试涉及大量订单、支付等表的金额字段(如
OL_AMOUNT
、C_BALANCE
、W_YTD
等),这些字段在 schema.sql 中通常被定义为NUMERIC(6,2)
、NUMERIC(12,2)
等。 - 长时间高并发测试下,金额字段(如累计销售额、客户余额等)会不断累加,最终超出字段定义的最大值(如
NUMERIC(6,2)
最大值为 9999.99),导致溢出报错。
- BenchmarkSQL 的 TPC-C 测试涉及大量订单、支付等表的金额字段(如
-
BenchmarkSQL 版本或自定义 schema 问题
- 部分 BenchmarkSQL 版本或用户自定义的 schema.sql 文件,金额相关字段精度设置过小,未考虑长时间测试下的累加效应。
-
PostgreSQL 对 NUMERIC 类型的严格校验
- PostgreSQL 对 NUMERIC 类型的溢出校验非常严格,任何超出定义范围的写入都会直接报错并回滚事务。
解决方案
1. 修改 schema.sql,增大金额字段精度
-
推荐将所有涉及金额累计的字段(如
W_YTD
、D_YTD
、C_BALANCE
、OL_AMOUNT
等)精度统一调整为NUMERIC(15,2)
或更大。 -
具体操作:
-- 以 warehouse 表为例 CREATE TABLE warehouse (...w_ytd NUMERIC(15,2) NOT NULL,... ); -- 其他表类似,找到所有金额相关字段,统一放大精度
-
修改后,建议重新初始化数据库(重新建表、装载数据)。
2. 已有数据在线修改精度
对于不想重新灌数的场景,可以尝试在线修改,示例
alter table bmsql_warehouse alter clumn w_ytd type numeric(15,2);
3. 关注测试期间的字段增长
- 长时间高并发测试下,部分字段增长极快。可定期监控相关字段的最大值,提前预警。
- 也可通过 SQL 查询当前最大金额:
SELECT MAX(w_ytd) FROM warehouse; SELECT MAX(c_balance) FROM customer;