PostgreSQL主从序列的last_value不一致

本文通过实例演示了在PostgreSQL的主从复制环境中,序列的last_value在主备机之间存在的差异现象及其原因。该差异会导致从备机同步数据到测试环境时出现主键冲突的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
一直以为PostgreSQL的主从所有数据都是一致的,但直到最近测试过程中发现的一个奇怪的序列问题让我有所改观,一开始以为是某个版本的问题,发现9.x的版本都存在这个问题,让我一度认为是postgresql的一个BUG。

我们的一个应用会定期同步PostgreSQL流复制的从机数据到一台测试机上,此时测试机上的数据和生产的现存数据是一致的,但是序列的last_value值是不一样的,导致测试机上新增数据时,最新的序列值和生产上是不一样的。

简单的测试过程如下

环境:
OS :CentOS 6.5
DB:PostgreSQL 9.4beta3
Primary:10.1.11.71
StandBy:10.1.11.72
主从环境部署略


Primary端新建一张表:
[postgres @localhost ~]$ psql
psql (9.4beta3)
Type "help" for help.
 
postgres=# create table test(id serial,remark varchar(100));
CREATE TABLE
postgres=# select sequence_name,last_value,log_cnt from test_id_seq;
sequence_name | last_value | log_cnt
---------------+------------+---------
test_id_seq   |          1 |       0
(1 row)

此时在Standby端查看
[postgres @localhost ~]$ psql
psql (9.4beta3)
Type "help" for help.

postgres=# select sequence_name,last_value,log_cnt from test_id_seq;
sequence_name | last_value | log_cnt
---------------+------------+---------
test_id_seq   |          1 |       0
(1 row)

更新Primary端的测试数据
postgres=# insert into test(remark) select generate_series(1,100)||'hello,world';
INSERT 0 100
postgres=# select sequence_name,last_value,log_cnt from test_id_seq;
sequence_name | last_value | log_cnt
---------------+------------+---------
test_id_seq   |        100 |      32
(1 row)

再次去查看standby端的序列值
postgres=# select sequence_name,last_value,log_cnt from test_id_seq;
sequence_name | last_value | log_cnt
---------------+------------+---------
test_id_seq   |        132 |       0
(1 row)

其实多更新几次,你会发现备机上的last_value比主机上的略大,而且是主机上的last_value与 log_cnt之和。log_cnt在官方文档上没有详细说明,只是标注一个内部参数,并在replication中才有用处,通常认为是备机应用其他WAL时预留的nextval值,默认是32,所以这并不是一个BUG,而是故意设置的。
如果从备机上同步数据到模测环境上需要注意这一点。

转载于:https://my.oschina.net/Kenyon/blog/340846

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值