- PostgresSQL导入大量数据
- PostgresSQL修改序列的id
1.导入大量数据的方法
PostgreSQL导入数据可以把数据按一条记录一行写入到一个文本文件,然后使用如下命令导入
\copy oplog from oplogfile.txt delimiter ',' ;
说明:delimiter ',' 代表每列以逗号分隔
【例】测试操作日志占用存储超过阈值触发清除的机制,需要插入大量数据
说明:这里的操作日志是记录软件图形化页面的操作,例如登录会记录一条日志;操作日志会存库
因为只是测试清除的功能,可以插入大量重复数据
(1)编辑 psqlinsert.sh,使用该脚本生成文本文件
#!/bin/bash
INSERT_NUM=1999594
START_ID=211
OUTPUT_FILE='/root/Downloads/oplogfile.txt'
rm -rf $OUTPUT_FILE
id=$START_ID
num=$INSERT_NUM
for((i=0;i> $OUTPUT_FILE
done
说明:
- INSERT_NUM插入记录的行数,START_ID代表插入的第一条记录的id
- 第11按照表结构提供数据
(2)执行psqlinsert.sh后生成了文件oplogfile.txt
(3)将软件的其它服务停止,连接到PostgreSQL执行 \copy oplog from oplogfile.txt delimiter ',' ;
如果导入的数据量大需要等待一段时间
2.导入数据后出现的问题及解决
问题:
导入好数据确认已导入这些记录,将其它服务起来并登录页面,这时页面报SQL的错,类似如下,每次登录这个id会增加,但是后台查数据库并没有重复的记录
把新导入的数据删除就可以登录,使用INSERT命令插入一条数据也会报错……
排查:
执行如下命令可以看到当前的最大id -> 1999805
select id from
select max(id) from
test=> select id from oplog order by id desc limit 1;
id
---------
1999805
(1 row)
test=> select max(id) from oplog;
max
---------
1999805
(1 row)
test=>
查看对应递增序列的下一个值 -> 216
select nextval('
test=> select nextval('oplog_id_seq');
nextval
---------
216
(1 row)
test=>
参考资料:
POSTGRESQL 插入数据时主键冲突异常 https://blog.csdn.net/ant98002/article/details/102248262/
PostgreSQL中序列相关函数 nextval、currval、lastval、setval、setval https://blog.csdn.net/carcarrot/article/details/106873197
test=> SELECT nextval('oplog_id_seq');
nextval
---------
393
(1 row)
test=>
test=> SELECT currval('oplog_id_seq');
currval
---------
393
(1 row)
test=> SELECT nextval('oplog_id_seq');
nextval
---------
394
(1 row)
test=>
原因:
操作日志对应的表插入大量数据后最大的id到了1999805,但其对应的序列自增的id还停留在216,登录图形化界面的时候会记录一条日志,例如id为213,会与插入的数据冲突,所以页面报错
解决:
方法一,插入的数据从较大的id开始,避免与自增的冲突
方法二,修改序列对象计数器的值,至插入数据后的位置
select setval('
test=> SELECT setval('oplog_id_seq',1999805);
setval
---------
1999805
(1 row)
test=>
3.导入大量数据测试清理表数据的整体步骤
生成包含大量记录的文本文件 -> 连接数据库导入文本文件中的数据 -> 更新对应序列计数器的值