在postgresql

时间:2016-03-29 17:56:18

标签: postgresql

我想知道是否可以使用标准查询选择查询交易。

例如:

SELECT * FROM information_schema.transaction_logs 
WHERE table_name = 'product' AND time_stamp > '2016-01-01';

结果将类似于

===> table_name | operation | old_val_json   | new_val_json...
      product   |    update | {....desc:...} | {...desc...}| 

查询不起作用,因为没有像transaction_logs这样的表,但是存在类似的东西吗?

1 个答案:

答案 0 :(得分:7)

您可以通过逻辑复制槽查询预写日志流。

首先,您需要更改几个参数,然后重新启动服务器以进行更改:

postgres=# alter system set wal_level = logical;
postgres=# alter system set max_replication_slots = 1;

然后(重启后)你需要创建一个插槽:

postgres=# SELECT * FROM pg_create_logical_replication_slot('slot', 'test_decoding');
 slot_name | xlog_position 
-----------+---------------
 slot      | 2E/839F3300
(1 row)

此处,test_decoding是一个输出插件名称,用于将日志记录(二进制)转换为某些文本表示。

然后让我们创建一个表......

postgres=# create table product(id serial, val json);
CREATE TABLE

现在您可以查询WAL流:

postgres=# SELECT * FROM pg_logical_slot_get_changes('slot', NULL, NULL);
  location   |  xid  |     data     
-------------+-------+--------------
 2E/83A0BA48 | 80243 | BEGIN 80243
 2E/83A1D2B8 | 80243 | COMMIT 80243
(2 rows)

不幸的是,现在你无法解码DDL,所以你得到的只是BEGIN和END。 Xid字段代表交易号。

但是让我们插入一些东西......

postgres=# insert into product(val) values ('{"desc":"aaa"}');
INSERT 0 1

现在再次查询流:

postgres=# SELECT * FROM pg_logical_slot_get_changes('slot', NULL, NULL);
  location   |  xid  |                                  data                                  
-------------+-------+------------------------------------------------------------------------
 2E/83A1D3C0 | 80244 | BEGIN 80244
 2E/83A1D3C0 | 80244 | table public.product: INSERT: id[integer]:1 val[json]:'{"desc":"aaa"}'
 2E/83A1D440 | 80244 | COMMIT 80244
(3 rows)

您可以在此处查看表名和插入值。

更新声明相同:

postgres=# update product set val = '{"desc":"bbb"}';
UPDATE 1
postgres=# SELECT * FROM pg_logical_slot_get_changes('slot', NULL, NULL);
  location   |  xid  |                                  data                                  
-------------+-------+------------------------------------------------------------------------
 2E/83A1D560 | 80245 | BEGIN 80245
 2E/83A1D560 | 80245 | table public.product: UPDATE: id[integer]:1 val[json]:'{"desc":"bbb"}'
 2E/83A1D5E8 | 80245 | COMMIT 80245
(3 rows)

请注意,使用pg_logical_slot_get_changes函数从流中“消耗”某些更改后,您无法再次查询相同的更改。

如果您不再需要,请删除插槽:

postgres=# SELECT pg_drop_replication_slot('slot');
 pg_drop_replication_slot 
--------------------------

(1 row)

您可以阅读有关逻辑解码in the documentation的更多信息。