PostgreSQL 整型字段 “Integer out of range” 一例

今天检查数据库时,发现一个日志库根目录使用率比较高,由于 /var/applog/pg_log 用来存放 postgresql 日志,猜测 postgresql 有大量日志,经查,果然目录 /var/applog/pg_log 下有大量日志,每天的日志有 2G 左右,且日志里有大量以下内容。

数据库 CSV 日志

1
2012-02-14 14:35:30.640 CST,"accessstat","accessstat",18107,"192.168.169.71:43743",4ed49343.46bb,5331,"INSERT",2011-11-29 16:09:39 CST,168/45813,0,ERROR,22003,"integer out of range",,,,,,"INSERT INTO tbl_tmp(imsi, termipaddr, accessipaddr, networkID, conntype, smsCenter, cellId, dialTime, connectTime, dialRatio, connectRatio, exitReason, reconnresult) VALUES ('460028469626829', '117.136.7.71', '192.168.169.71', 0, 0, '', 0, 2306, 221, -1, -1, 1, 1);

备注:猜测可能有整型字段长度不够,于是查询手册确认下。

手册上 ERROR 代码表

1
2
3
4
5
6
 Error Code
Meaning
Condition Name
22003
NUMERIC VALUE OUT OF RANGE
numeric_value_out_of_range

执行报错的 SQL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
INSERT INTO tbl_tmp  
(xxxxxxxxxx,
xxxxxxxxxx,
xxxxxxxxxx,
xxxxxxxxxx,
xxxxxxxxxx,
xxxxxxxxxx,
xxxxxxxxxx,
xxxxxxxxxx,
xxxxxxxxxx,
xxxxxxxxxx,
xxxxxxxxxx,
xxxxxxxxxx,
xxxxxxxxxx)
VALUES
('460021452274418',
'117.136.7.72',
'192.168.169.70',
0,
0,
'8613800452500',
0,
56,
1098,
-1,
-1,
0,
0);

备注:从 INSERT 语句来看,推测是主键 seq 的问题,seq 类型为 integer。

查看表结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
accessstat=> /d tbl_tmp  
Table "skytf.tbl_tmp"
Column | Type | Modifiers
--------------+-----------------------+---------------------------------------------------------------------
seq | integer | not null default nextval('tbl_tmp_seq_seq'::regclass)
xxxx | character varying(16) | not null
xxxxxxxxxx | character varying(16) | not null
xxxxxxxxxxxx | character varying(16) | not null
xxxxxxxxx | smallint | not null
xxxxxxxx | smallint | not null
xxxxxxxxx | character varying(16) | not null
xxxxxx | integer | not null
xxxxxxxx | integer | not null
xxxxxxxxxxx | integer | not null
xxxxxxxxx | smallint | not null
xxxxxxxxxxxx | smallint | not null
xxxxxxxxxx | smallint | not null
xxxxxxxxxxxx | smallint | not null
xxxxxxxx | date | not null default now()
Indexes:
"tbl_tmp_pkey" PRIMARY KEY, btree (seq)
Inherits: tbl_tmp
Tablespace: "tbs_accessstat_idx"

查看序列 next 值

1
2
3
4
5
accessstat=> select nextval('tbl_tmp_seq_seq');  
nextval
------------
2148607080
(1 row)

数据类型 integer 范围是 ( -2147483648 to +2147483647 )

1
2
3
4
5
accessstat=> select 2148607080-2147483647;  
?column?
----------
1123433
(1 row)

备注:可见 pk 已经超出了 integer 的范围。

处理方法

最有效的方法是将字段 seq 类型由 integer 扩为 bigint 类型,由于 pg 扩字段需要重写表,那么还得想办法清理历史数据,由于这张表是日志表,和开发人员确认后,可以清理历史数据,只保留当月数据即可。

更改字段类型( integer -> bigint )

1
2
3
accessstat=> alter table tbl_tmp alter column seq type bigint;  
ALTER TABLE
Time: 83110.885 ms

备注:建议清理历史数据后再执行修改字段操作。

原创文章,作者:6024010,如若转载,请注明出处:https://blog.ytso.com/237824.html

(0)
上一篇 2022年1月29日
下一篇 2022年1月29日

相关推荐

发表回复

登录后才能评论