如下例子,手动插入数据后,再使用默认的序列会报错,序列不能自动识别表中已使用的最大值。

#创建测试表
<16:28:43><db:hank><user:postgres><pid:30677>=# CREATE TABLE t_test_seq (
(#     id          serial     PRIMARY KEY,
(#     info     text
(# );
CREATE TABLE
#使用序列自动填充,插入两条数据
<16:32:05><db:hank><user:postgres><pid:30677>=# INSERT INTO t_test_seq (info) VALUES ('foo') RETURNING *;id │ info
────┼──────1 │ foo
(1 row)INSERT 0 1
<16:32:11><db:hank><user:postgres><pid:30677>=# INSERT INTO t_test_seq (info) VALUES ('bar') RETURNING *;id │ info
────┼──────2 │ bar
(1 row)INSERT 0 1
#手动插入第三条成功
<16:32:17><db:hank><user:postgres><pid:30677>=# INSERT INTO t_test_seq VALUES (3, 'bang') RETURNING *;id │ info
────┼──────3 │ bang
(1 row)INSERT 0 1#使用序列自动填充插入报错违反唯一约束,因为这里序列的值是3
<16:32:32><db:hank><user:postgres><pid:30677>=# INSERT INTO t_test_seq (info) VALUES ('boom') RETURNING *;
ERROR:  duplicate key value violates unique constraint "t_test_seq_pkey"
DETAIL:  Key (id)=(3) already exists.

使用CYBERTEC公司提供的插件pg_sequence_fixer解决该问题,git地址如下:
https://github.com/cybertec-postgresql/pg_sequence_fixer

#安装,这里我下载的zip包,解压安装即可
unzip pg_sequence_fixer-main.zip
cd pg_sequence_fixer-main
make install
/usr/bin/mkdir -p '/opt/pgsql/share/extension'
/usr/bin/mkdir -p '/opt/pgsql/share/extension'
/usr/bin/mkdir -p '/opt/pgsql/share/doc/extension'
/usr/bin/install -c -m 644 .//pg_sequence_fixer.control '/opt/pgsql/share/extension/'
/usr/bin/install -c -m 644 .//pg_sequence_fixer--*.sql  '/opt/pgsql/share/extension/'
/usr/bin/install -c -m 644 .//README.md '/opt/pgsql/share/doc/extension/'

安装插件然后解决序列值冲突

<16:28:39><db:hank><user:postgres><pid:30677>=# create extension pg_sequence_fixer ;
CREATE EXTENSION
<16:28:41><db:hank><user:postgres><pid:30677>=# \dxpg_sequence_fixer  │ 1.0     │ public     │ adjusting sequences which got out of sync
#查看相关函数,可见有两个参数,第一个参数表示,我们想要在序列确定的最大值上增加的安全边界。第二个参数控制现是现在锁这些表还是在操作期间锁这些表。通常,锁表不是我们想要的,但为了保证操作一致性,有时候是必要的,以防无法关闭正在修复序列的应用程序。<16:32:37><db:hank><user:postgres><pid:30677>=# \df pg_sequence_fixerList of functionsSchema │       Name        │ Result data type │                 Argument data types                 │ Type
────────┼───────────────────┼──────────────────┼─────────────────────────────────────────────────────┼──────public │ pg_sequence_fixer │ void             │ v_margin integer, v_lock_mode boolean DEFAULT false │ func
(1 row)#原来表中最大值为3,以下例子是在3的基础上增加安全边界10,也就设置当前序列值为13
<16:35:32><db:hank><user:postgres><pid:30677>=# SELECT pg_sequence_fixer(10, false);
NOTICE:  setting sequence for t_test_seq to 13pg_sequence_fixer
───────────────────(1 row)#使用序列自动填充,可见插入值为下一个值14
<16:36:50><db:hank><user:postgres><pid:30677>=# INSERT INTO t_test_seq (info) VALUES ('ttt') RETURNING *;id │ info
────┼──────14 │ ttt
(1 row)INSERT 0 1

核心函数如下:

-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION pg_sequence_fixer" to load this file. \quitCREATE FUNCTION pg_sequence_fixer(IN v_margin int, IN v_lock_mode boolean DEFAULT false)
RETURNS void AS
$$DECLAREv_rec      RECORD; v_sql       text;v_max      int8;BEGINIF    v_margin IS NULL    --判断v_margin的值,如果是空,发出notice并设置为1,如果是负值,则发出warningTHEN RAISE NOTICE 'the safety margin will be set to 1';v_margin := 1;END IF;IF     v_margin < 1THENRAISE WARNING 'a negative safety margin is used';END IF;--v_rec直接取出序列,表,列相关数据FOR v_rec IN SELECT  d.objid::regclass,d.refobjid::regclass,a.attnameFROM   pg_depend AS dJOIN pg_class AS tON d.objid = t.oidJOIN pg_attribute AS aON d.refobjid = a.attrelid AND d.refobjsubid = a.attnumWHERE     d.classid = 'pg_class'::regclassAND d.refclassid = 'pg_class'::regclassAND t.oid >= 16384AND t.relkind = 'S'AND d.deptype IN ('a', 'i')LOOPIF  v_lock_mode = true      --如果参数设置为true,则使用lock table显试加排它锁THENv_sql := 'LOCK TABLE ' || v_rec.refobjid::regclass || ' IN EXCLUSIVE MODE';RAISE NOTICE 'locking: %', v_rec.refobjid::regclass;EXECUTE v_sql;END IF;--设置序列的值,取出列的最大值并加上v_marginv_sql := 'SELECT setval(' || quote_literal(v_rec.objid::regclass) || '::text, max(' || quote_ident(v_rec.attname::text) || ') + ' || v_margin || ') FROM ' || v_rec.refobjid::regclass;EXECUTE v_sql INTO v_max;RAISE NOTICE 'setting sequence for % to %', v_rec.refobjid::text, v_max; END LOOP;RETURN;END;
$$ LANGUAGE 'plpgsql';

参考:
https://www.cybertec-postgresql.com/en/fixing-out-of-sync-sequences-in-postgresql/

Postgresql修正序列插件之pg_sequence_fixer相关推荐

  1. 基于QGIS初探PostgreSQL的PostGIS插件,包括YUM和编译安装PostGIS

    写在前面:本文介绍 QGIS,只是为了展示怎么使用 PostGIS,因作者本人追求的是 PostgreSQL,所以本文的重点还是 PostGIS 这个 PostgreSQL 的插件,QGIS软件只做简 ...

  2. PostgreSQL全局临时表插件pgtt的使用

    墨墨导读:本文主要介绍PostgreSQL全局临时表插件pgtt的使用. https://github.com/darold/pgtt 前言 PostgreSQL目前到最新12版本只支持本地临时表不支 ...

  3. postgresql Mybatis 序列自增

    简单记录一下问题: 以前通过Oracle+Mybatis做新增功能时主键都是通过sequence自增的,了解到postgresql也有序列,遂尝试结合Mybatis做一个简单的insert功能,结果报 ...

  4. postgresql安装postgis插件并导入数据

    今天分享 postgresql安装postgis插件并导入数据,首先我们需要知道什么时候需要安装postgis插件,这是很重要的一个前提:一般来说数据有空间索引坐标相关的数据,需要安装,或者操作数据报 ...

  5. Postgresql在线分区插件之pg_rewrite使用

    在使用数据库的过程中,有一些表开始无法估量大小,后面表变大后,需要做分区表,那么是一件比较烦人的事情,现在好了,有了cybertec公司这款插件,轻松实现.说到这个功能,Oracle从很早就有了,叫在 ...

  6. postgresql 查询序列_时间序列数据库(TSDB)初识与选择

    背景 这两年互联网行业掀着一股新风,总是听着各种高大上的新名词.大数据.人工智能.物联网.机器学习.商业智能.智能预警啊等等. 以前的系统,做数据可视化,信息管理,流程控制.现在业务已经不仅仅满足于这 ...

  7. postgresql 查询序列_RazorSQL for Mac(数据库工具查询) v9.0.9

    RazorSQL Mac激活版是一款专门为mac用户推出的数据库管理软件,允许您从一个数据库工具查询,更新,导航和管理所有主要数据库! 软件特色 RazorSQL 是一个非开源的功能非常强大数据库查询 ...

  8. PostgreSQL SQL OUTLINE插件sr_plan (保存、篡改、固定 执行计划)

    标签 PostgreSQL , sql plan outline , 执行计划篡改 , query rewrite , sr_plan , pg plan hint 背景 功能较为强大的数据库,通常都 ...

  9. postgresql垃圾清理插件pg_repack

    pg_repack插件部署: wget http://api.pgxn.org/dist/pg_repack/1.4.5/pg_repack-1.4.5.zip source /home/postgr ...

最新文章

  1. 用Java实现天天酷跑(附源码),这个真的有点强了!
  2. Codeigniter设计和架构目标
  3. No module named 'StringIO'
  4. 又到半年总结时,IT人只想躺平!
  5. js cookie操作
  6. 酒店管理与计算机技术结合,(定稿)某酒店内部管理系统的开发与应用(完整版)...
  7. 如何才能做到网站高并发访问?
  8. java根据父类找子类_在java中实现多态时,可以通过父类变量引用子类的对象。_学小易找答案...
  9. VS2015 调试代码时写入位置时发生访问冲突
  10. SQL执行效率2-执行计划
  11. 算法笔记 (胡凡 / 曾磊 著)
  12. win10找回自带的windows照片查看器——打开jpg、png、gif、psd其他格式的图片
  13. fullPage.js使用
  14. EMC设计经典15问
  15. Wifi认证及加密详解
  16. vue3 kepp-alive 的使用
  17. Dns是什么?IPHostEntry/IPAddress/IPEndPort是什么?怎么用?
  18. 恋词21版(2022.12.10)
  19. python:操作文档——TXT篇
  20. 幻灯片自动播放的实现

热门文章

  1. leetcode:908. 最小差值 I(数学)
  2. GSS7 - Can you answer these queries VII 题解
  3. 软件工程导论——详解白盒测试和黑盒测试中的各种方法
  4. JavaCV音视频开发宝典:使用JavaCV和springBoot实现http-flv直播服务,无需流媒体服务,浏览器网页flv.js转封装方式播放rtsp,rtmp和桌面投屏实时画面
  5. 不要学习“网红”编程语言
  6. Android音频格式转换,Android音视频系列(八):了解音频格式WAV以及与PCM的转换...
  7. ArcGIS10.2自带的Python2.7下安装pip
  8. C++的XML编程经验
  9. 前端三小时用html和js写一个贪吃蛇游戏,非常简单带讲解,代码可直接用,功能完整
  10. SAP借HANA强大功能为生态系统注入新活力