今天检查数据库时,发现一个日志库根目录使用率比较高,由于 /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 |
Error Code |
执行报错的 SQL
1 |
INSERT INTO tbl_tmp |
备注:从 INSERT 语句来看,推测是主键 seq 的问题,seq 类型为 integer。
查看表结构
1 |
accessstat=> /d tbl_tmp |
查看序列 next 值
1 |
select nextval('tbl_tmp_seq_seq'); |
数据类型 integer 范围是 ( -2147483648 to +2147483647 )
1 |
accessstat=> select 2148607080-2147483647; |
备注:可见 pk 已经超出了 integer 的范围。
处理方法
最有效的方法是将字段 seq 类型由 integer 扩为 bigint 类型,由于 pg 扩字段需要重写表,那么还得想办法清理历史数据,由于这张表是日志表,和开发人员确认后,可以清理历史数据,只保留当月数据即可。
更改字段类型( integer -> bigint )
1 |
accessstat=> alter table tbl_tmp alter column seq type bigint; |
备注:建议清理历史数据后再执行修改字段操作。
原创文章,作者:6024010,如若转载,请注明出处:https://blog.ytso.com/237824.html