为什么 pg_recvlogic 不能写入 stdout,通过一个不平凡的管道,然后通过管道将其返回到数据库表

问题描述 投票:0回答:1

我无法通过处理命令将 PosgreSQL 的

pg_recvlogical
工具的输出通过管道传输到文件中。当我尝试执行此操作时,目标文件为空并且逻辑解码事件未读取。

我在第一次使用默认输出插件创建插槽后尝试了此命令。

pg_recvlogical -d postgres --slot test --start -f - | awk '{print}' | psql

在另一个终端窗口中使用

psql
插入一些数据,然后终止上面的命令后,我预计
sample.txt
会发生更改事件。相反,我发现它是空的。

奇怪的是,当我用

cat
代替
awk '{print}'
时,它确实有效。

postgresql bash shell pipe
1个回答
0
投票

这里有一个简单的方法,使用 逻辑解码 使用 wal2json 输出插件捕获更改事件,将它们传递给一个不平凡的

jq
过滤器,然后将它们存储回数据库中,在
change_event
中表本身不包含在变更捕获中。它可以适应其他需求。

psql -d postgres -c "create table change_event (payload jsonb)"
pg_recvlogical -d postgres --slot=test --create-slot -P wal2json
pg_recvlogical -d postgres -n --slot=test -o filter-tables=public.change_event --start -f - | jq --unbuffered -rc $'select(.change|length>0)|"insert into change_event (payload) values (\'\(.)\');"' | psql -d postgres &

这就是它的工作原理。

  1. 由于我们使用的是
    change_event
    ,因此
    jsonb
    表是使用
    wal2json
    数据类型创建的。
  2. pg_recvlogical
    使用
    wal2json
    输出插件创建一个插槽。
  3. pg_recvlogical
    无需重新启动即可捕获事件 (
    -n
    )。
  4. filter-tables
    的选项有助于避免涉及
    change_event
    表的循环事件。
  5. 数据发送至
    stdout
    (-f -)
  6. 它们通过
    jq
    ,关键是通过
    --unbuffered
    开关。
    -r
    -c
    开关在这里也很有用。
  7. jq
    过滤器会删除具有空变更集的事件 (
    select(.change|length>0)
    )。
  8. 它们被输入到字符串模板中以生成 SQL
    insert
    语句。
  9. 输出通过管道传输到
    psql
    ,以便写入数据库中的
    change_event
    表。
© www.soinside.com 2019 - 2024. All rights reserved.