Among the many things to say about logical replication features added in PostgreSQL 9.4, REPLICA IDENTITY is a new table-level parameter that can be used to control the information written to WAL to identify tuple data that is being deleted or updated (an update being a succession of an insert and a delete in MVCC).

This parameter has 4 modes:

  • DEFAULT
  • USING INDEX index
  • FULL
  • NOTHING

First let's set up an environment using some of the instructions in a previous post dealing with some basics of logical decoding to set up a server using test_decoding in a replication slot.

=# SELECT * FROM pg_create_logical_replication_slot('my_slot', 'test_decoding');
slot_name | xlog_position
-----------+---------------
my_slot | 0/16CB0F8
(1 row)

The replication slot used here will be used in combination with pg_logical_slot_get_changes to consume each change of the slot (to compare with pg_logical_slot_peek_changes that can be used to view the changes but not consume them).

In the case of DEFAULT, old tuple data is only identified with the primary key of the table. This data is written into WAL only when at least one column of the primary key is updated. Columns that are not part of the primary key do not have their old value written.

=# CREATE TABLE aa (a int, b int, c int, PRIMARY KEY (a, b));
CREATE TABLE
=# INSERT INTO aa VALUES (1,1,1);
INSERT 0 1
=# [ ... Clean up of slot information up to now ... ]
=# UPDATE aa SET c = 3 WHERE (a, b) = (1, 1);
UPDATE 1
=# SELECT * FROM pg_logical_slot_get_changes('my_slot', NULL, NULL);
location | xid | data
-----------+------+-----------------------------------------------------------------
0/1728D50 | 1013 | BEGIN 1013
0/1728D50 | 1013 | table public.aa: UPDATE: a[integer]:1 b[integer]:1 c[integer]:3
0/1728E70 | 1013 | COMMIT 1013
(3 rows)
=# UPDATE aa SET a = 2 WHERE (a, b) = (1, 1);
UPDATE 1
=# SELECT * FROM pg_logical_slot_get_changes('my_slot', NULL, NULL);
location | xid | data
-----------+------+---------------------------------------------------------------------------------------------------------------
0/1728EA8 | 1014 | BEGIN 1014
0/1728EA8 | 1014 | table public.aa: UPDATE: old-key: a[integer]:1 b[integer]:1 new-tuple: a[integer]:2 b[integer]:1 c[integer]:3
0/1728FF0 | 1014 | COMMIT 1014
(3 rows)

Ît is important to know that REPLICA IDENTITY can only be changed using ALTER TABLE, and that the parameter value is only viewable with '\d+' only if default behavior is not used. Also, after creating a table, REPLICA IDENTITY is set to DEFAULT (Surprise!).

=# \d+ aa
Table "public.aa"
Column | Type | Modifiers | Storage | Stats target | Description
--------+---------+-----------+---------+--------------+-------------
a | integer | not null | plain | |
b | integer | not null | plain | |
c | integer | | plain | |
Indexes:
"aa_pkey" PRIMARY KEY, btree (a, b)
=# ALTER TABLE aa REPLICA IDENTITY FULL;
ALTER TABLE
=# \d+ aa
Table "public.aa"
Column | Type | Modifiers | Storage | Stats target | Description
--------+---------+-----------+---------+--------------+-------------
a | integer | not null | plain | |
b | integer | not null | plain | |
c | integer | | plain | |
Indexes:
"aa_pkey" PRIMARY KEY, btree (a, b)
Replica Identity: FULL
=# [ ... Replication slot changes are consumed here ... ]

In the case of FULL, all the column values are written to WAL all the time. This is the most verbose, and as well the most resource-consuming mode. Be careful here particularly for heavily-updated tables.

=# UPDATE aa SET c = 4 WHERE (a, b) = (2, 1);
UPDATE 1
=# SELECT * FROM pg_logical_slot_get_changes('my_slot', NULL, NULL);
location | xid | data
-----------+------+----------------------------------------------------------------------------------------------------------------------------
0/172EC70 | 1016 | BEGIN 1016
0/172EC70 | 1016 | table public.aa: UPDATE: old-key: a[integer]:2 b[integer]:1 c[integer]:3 new-tuple: a[integer]:2 b[integer]:1 c[integer]:4
0/172EE00 | 1016 | COMMIT 1016

On the contrary, NOTHING prints... Nothing. (Note: operation done after an appropriate ALTER TABLE and after consuming replication slot information).

=# UPDATE aa SET c = 4 WHERE (a, b) = (2, 1);
UPDATE 1
=# SELECT * FROM pg_logical_slot_get_changes('my_slot', NULL, NULL);
location | xid | data
-----------+------+-----------------------------------------------------------------
0/1730F58 | 1018 | BEGIN 1018
0/1730F58 | 1018 | table public.aa: UPDATE: a[integer]:2 b[integer]:1 c[integer]:4
0/1731100 | 1018 | COMMIT 1018

Finally, there is USING INDEX, which writes to WAL the values of the index defined with this option. The index needs to be unique, cannot contain expressions and must contain NOT NULL columns.

=# ALTER TABLE aa ALTER COLUMN c SET NOT NULL;
ALTER TABLE
=# CREATE unique INDEX aai on aa(c);
CREATE INDEX
=# ALTER TABLE aa REPLICA IDENTITY USING INDEX aai;
ALTER TABLE
=# [ ... Consuming all information from slot ... ]
=# UPDATE aa SET c = 5 WHERE (a, b) = (2, 1);
UPDATE 1
=# SELECT * FROM pg_logical_slot_get_changes('my_slot', NULL, NULL);
location | xid | data
-----------+------+--------------------------------------------------------------------------------------------------
0/1749A68 | 1029 | BEGIN 1029
0/1749A68 | 1029 | table public.aa: UPDATE: old-key: c[integer]:4 new-tuple: a[integer]:2 b[integer]:1 c[integer]:5
0/1749D40 | 1029 | COMMIT 1029
(3 rows)

Note that in this case the primary key information is not decoded, only the NOT NULL column c that the index covers.

REPLICA IDENTITY should be chosen carefully for each table of a given application, knowing that for example FULL generates an extra amount of WAL that may not be necessary, NOTHING may forget about essential information. In most of the cases, DEFAULT provides a good cover though.

REPLICA IDENTITY

This form changes the information which is written to the write-ahead log to identify rows which are updated or deleted. This option has no effect except when logical replication is in use. DEFAULT (the default for non-system tables) records the old values of the columns of the primary key, if any. USING INDEX records the old values of the columns covered by the named index, which must be unique, not partial, not deferrable, and include only columns marked NOT NULLFULL records the old values of all columns in the row. NOTHING records no information about the old row. (This is the default for system tables.) In all cases, no old values are logged unless at least one of the columns that would be logged differs between the old and new versions of the row.

参考:

http://michael.otacoo.com/postgresql-2/postgres-9-4-feature-highlight-replica-identity-logical-replication/

http://www.postgresql.org/docs/devel/static/sql-altertable.html

Postgres 9.4 feature highlight: REPLICA IDENTITY and logical replication的更多相关文章

  1. 【ASP.NET Identity系列教程(一)】ASP.NET Identity入门

    注:本文是[ASP.NET Identity系列教程]的第一篇.本系列教程详细.完整.深入地介绍了微软的ASP.NET Identity技术,描述了如何运用ASP.NET Identity实现应用程序 ...

  2. ASP.NET Identity 一 (转载)

    来源:http://www.cnblogs.com/r01cn/p/5194257.html 注:本文是[ASP.NET Identity系列教程]的第一篇.本系列教程详细.完整.深入地介绍了微软的A ...

  3. Postgres 主从复制搭建步骤

    系统版本: CentOS Linux release 7.5.1804 (Core) 数据库 psql (PostgreSQL) 10.5 2台机器ip : 172.17.0.3 /172.17.0. ...

  4. ASP.NET Identity系列教程-2【Identity入门】

    https://www.cnblogs.com/r01cn/p/5177708.html13 Identity入门 Identity is a new API from Microsoft to ma ...

  5. flink-cdc读取postgres报异常,没有发布表

    异常信息 must be superuser to create FOR ALL TABLES publication 必须是超级用户才能为所有发布表创建 网上搜索了一天,都毫无头绪,后面搜索到了一个 ...

  6. TSQL Identity 用法全解

    Identity是标识值,在SQL Server中,有ID列,ID属性,ID值,ID列的值等术语. Identity属性是指在创建Table时,为列指定的Identity属性,其语法是:column_ ...

  7. mongodb复制集Replica Set使用简介

    MongoDB高可用 对于MongoDB,可以支持使用单机模式提供服务,但是在实际的生产环境中,单机模式将面临很大的风险,一旦这个数据库服务出现问题,就会导致线上的服务出现错误甚至崩溃.因此,在实际生 ...

  8. Replication Controller 和 Replica Set

    使用Replication Controller . Replica Set管理Pod Replication Controller (RC) 简写为RC,可以使用rc作为kubectl工具的快速管理 ...

  9. postgres使用pg_ctl 命令

    想要用pg_ctl等一系列的命令,需要配置环境变量: PATH=$PATH:$HOME/.local/bin:$HOME/bin:/usr/local/pgsql/binexport PGDATA=/ ...

随机推荐

  1. 0505 Scrum 项目1.0

    应用NABCD模型,分析你们初步选定的项目,充分说明你们选题的理由. 录制为演说视频,上传到视频网站,并把链接发到团队博客上. 团队项目选题  一个售书网站(O2O) NABCD 模型 1) N (N ...

  2. Java环境环境配置

    1. 下载并安装JDK,假如安装在D盘 2. 右键计算机->属性->高级系统设置->环境变量 3. 点击新建系统变量:系统变量名:JAVA_HOME   系统变量值:D:\Progr ...

  3. WIN7 java7 环境变量配置

    1 首先要搞清楚,java可能安装了两个部分,一个叫JDK,一个叫jre.其中jre若已经安装了,那么在安装JDK的时候,就不要放在默认的C:\Program File\java\XXX目录.最好另起 ...

  4. Java Java Java

    学下java 的大数该怎么用>< hdu 1023 Train Problem II 求 卡特兰 数 诶...不记得卡特兰数的我眼泪掉下来 第一次用 java 大数 有点激动...> ...

  5. CodeForces #369 C. Coloring Trees DP

    题目链接:C. Coloring Trees 题意:给出n棵树的颜色,有些树被染了,有些没有.现在让你把没被染色的树染色.使得beauty = k.问,最少使用的颜料是多少.   K:连续的颜色为一组 ...

  6. linux 的 磁盘操作

    //显示目录和文件 以kb m g为单位 du -ah //总大小 du -sh /etc //查看分区 fdisk -l //对磁盘进行分区 fdisk /dev/sdb //格式化分区 mkfs ...

  7. cron

    pre.cjk { font-family: "Nimbus Mono L", monospace } p { margin-bottom: 0.1in; line-height: ...

  8. Java中interface和abstract class的区别和联系

    interface: interface类似于class,但是只包含函数(只规定参数.函数名.返回类型,不规定函数体).目的是用来建立类和类之间的一种“协议”.一个类可以实现多种接口,来模拟多重继承. ...

  9. ubuntu 14.04 下找不到命令,路径出错

    在安装一些东西时,可能操作上不小心把路径覆盖或打错,造成一些基本命令如ls mkdir等无法使用,就会出现以下提示错误. 错误: 由于/usr/bin 不在PATH 环境变量中,故无法找到该命令 根本 ...

  10. [TD Cup 2014] TDL的YC牌 & TDL的幼儿园

    TDL的YC牌 传说中的置换群?反正不懂.我的思路竟然是对的,可是为何只有20分? (1)尼玛每行数据输出后回车不打! (2)写gcd函数脑残把a mod b写成a-b,大大减慢速度… (3)看标程才 ...