解决postgresql序列重复的问题

问题来源

在系统使用过程中出现了一个报错信息
在这里插入图片描述
错误:more than one owned sequence found (找到多个拥有的序列)

排查得知是数据库在迁移时生成了多个序列导致,如下图
在这里插入图片描述
现在数据库中基本每个序列都有三个

解决办法

背景介绍完毕,接下来开始删掉多余的序列

执行代码得到序列的删除语句

 SELECT 'DROP SEQUENCE "'||c.relname||'";' FROM pg_class c WHERE c.relkind ='S';

在这里插入图片描述
新建.sql文件,将语句复制到文件中
然后执行sql文件,选中“遇到错误时继续”
在这里插入图片描述
这里删掉的92个就是重复的序列,留下了54个序列
在这里插入图片描述
但是剩下的序列名都是以1或2结尾,我们把序列名进行一个修改
在这里插入图片描述

 UPDATE pg_class SET relname = substr(relname,0,char_length(relname)) WHERE relname like '%seq_'

至此,序列重复的问题就解决了
但是,因为序列混乱,而且在发现问题之前有些错误序列已经生成过数据。
导致现在有部分表的序列值比实际值小,插入数据时发生了主键冲突。
需要将序列的值更新为对应表的最大值
在这里插入图片描述
复制下面sql执行结果的第一列,然后执行sql

select 
 ( E'SELECT setval(\''||b.sequence_name||E'\', (select COALESCE(max('|| pg_attribute.attname || '),1) from '||pg_class.relname||'), true);'),
 pg_class.relname, pg_constraint.conname as pk_name,pg_attribute.attname as colname,pg_type.typname as typename  
 from 
pg_constraint  inner join pg_class 
on pg_constraint.conrelid = pg_class.oid 
inner join pg_attribute on pg_attribute.attrelid = pg_class.oid 
and  pg_attribute.attnum = pg_constraint.conkey[1]
inner join pg_type on pg_type.oid = pg_attribute.atttypid 
RIGHT JOIN (select seq_ns.nspname as sequence_schema, 
       seq.relname as sequence_name,
       tab_ns.nspname as table_schema,
       tab.relname as related_table
from pg_class seq
  join pg_namespace seq_ns on seq.relnamespace = seq_ns.oid
  JOIN pg_depend d ON d.objid = seq.oid 
  JOIN pg_class tab ON d.objid = seq.oid AND d.refobjid = tab.oid
  JOIN pg_namespace tab_ns on tab.relnamespace = tab_ns.oid
where seq.relkind = 'S' 
  and seq_ns.nspname = 'public') b on related_table=pg_class.relname
where 
-- pg_class.relname is null 
pg_constraint.contype = 'p'

在这里插入图片描述
执行SQL,问题解决

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

witleo灬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值