小编Mor*_*ryx的帖子

关于 Postgres track_commit_timestamp (pg_xact_commit_timestamp) 的问题

我正在设计一个并发安全的增量聚合汇总系统,track_commit_timestamp (pg_xact_commit_timestamp) 听起来很完美。但是我发现很少有关于它的评论,并且无法从源代码中弄清楚它是如何工作的。

希望有人知道我的一个或多个问题的答案:

  • 提交时间戳功能是否有可能产生乱序时间?我所追求的是一种识别自特定时间以来已更改的记录的方法,以便我可以获取任何以后的更改以进行处理。如果有相同的时间戳,我不需要它们以完美的提交顺序。

  • 最终实现中每行添加多少字节?我看到的讨论似乎在 12-24 个字节之间。曾讨论过为“以防万一”添加额外字节。这是 9.5 之前的版本,所以是一个世界之前的版本。

  • 时间戳是否在内部编入索引?用 B 树?我询问容量规划的原因。

  • 我在 StackOverflow 和设计讨论中看到时间戳不是无限期保留的,但无法找到它们存储时间的详细信息。

  • 关于启用 track_commit_timestamp 的性能影响的任何经验法则?我不需要所有表上的数据,但是,在我需要的地方,听起来它可能工作得很好。

  • 有什么问题吗?我尝试在测试表上运行 VACUUM FULL 并且 pg_xact_commit_timestamp 都没有改变。看起来像 VACUUM 这样的物理操作不应该改变任何东西,但很容易有一些我没有想到的东西。而且,老实说,我的快速 VACUUM 测试甚至可能没有任何意义。

非常感谢您的帮助!


我编辑了我的问题以阐明我要完成的任务,我希望根据更新标记跟踪已处理和未处理的数据。

select max(pg_xact_commit_timestamp(xmin)) from scan;--   2019-07-07 20:46:14.694288+10

update scan set quantity = 5 where quantity = 1; --       Change some data.

select max(pg_xact_commit_timestamp(xmin)) from scan; --  2019-07-10 09:38:17.920294+10

-- Find the changed row(s):
select * 
  from scan 
 where pg_xact_commit_timestamp(xmin) > '2019-07-07 20:46:14.694288+10'; 
Run Code Online (Sandbox Code Playgroud)

这个想法是对行进行增量和定期汇总。所以,

-- 跟踪上次汇总的时间戳。-- 等待 5 分钟(或其他时间)。 -- 查找当前的最大提交时间戳。-- …

postgresql transactions rollup

5
推荐指数
2
解决办法
3679
查看次数

包含 tsvector 字段的可能原因?

我对tsvector字段(重新)感到困惑。这是常见的,看文字的例子被连接成的tsvector字段,然后索引。如果您查找 PG 12 生成的列,您会发现快速显示tsvector字段填充的示例。

既然这个字段的唯一目的就是支持索引,那为什么不用表达式构建索引,跳过向量列呢?我之前顺便问过这个问题(找不到),记得听到回复“这个专栏毫无意义”。这对我来说很有意义。最近,我一直在关注这篇文章的一些评论:

使用 PostgreSQL 12 微调全文搜索

这件作品相当不错,顺便说一句。有这样的评论:

实现 tsvector 的一个原因是不在重新检查时评估表达式,这本身可能非常昂贵。

在解释分析中勾选'Recheck Cond',条件可以被真正检查,因此条件(to_tsvector)将被计算。

\d t1
Table “public.t1”
Column | Type    | Collation | Nullable | Default
--–----+---------+----------–+----------+---
id     | integer |           |          |
t      | text    |           |          |
Indexes:
  "t1_to_tsvector_idx" gin (to_tsvector('english'::regconfig, t))

explain analyze select * from t1 where to_tsvector(‘english’, t) @@ to_tsquery(‘english’,’foo’);
Run Code Online (Sandbox Code Playgroud)
\d t1
Table “public.t1”
Column | Type    | Collation | Nullable | Default
--–----+---------+----------–+----------+---
id …
Run Code Online (Sandbox Code Playgroud)

postgresql full-text-search tsvector

5
推荐指数
1
解决办法
639
查看次数

在 Postgres 中将复合数组 UNNEST 为行和列

Postgres 11.7。

我正在尝试解压一个数组,其中每个项目都有多个元素,并且似乎无法获得正确的语法。我希望有人能指出我所缺少的东西。这是一个例子:

select
unnest(array[

                 ('Red Large Special',     1),
                 ('Blue Small',            5),
                 ('Green Medium Special', 87)

              ]) as item_list

Run Code Online (Sandbox Code Playgroud)

这就是我要的:

item_name               item_id  
Red Large Special       1
Blue Small              5
Green Medium Special   87
Run Code Online (Sandbox Code Playgroud)

这就是我得到的:

base_strings
("Red Large Special",1)
("Blue Small",5)
("Green Medium Special",87)
Run Code Online (Sandbox Code Playgroud)

我相信我需要一个列规格列表,如下所示:

select * from
unnest(array[

                 ('Red Large Special',    1),
                 ('Blue Small',        5),
                 ('Green Medium Special', 87)

              ]) AS item_list(item_name citext, item_id int4)
Run Code Online (Sandbox Code Playgroud)

我得到的是:

ERROR:  function return row and query-specified return row do not match
DETAIL:  Returned type …
Run Code Online (Sandbox Code Playgroud)

postgresql unnest

4
推荐指数
1
解决办法
5382
查看次数

在 Postgres 12 或 13 中根据 UUID 进行分区

问题

我被要求将大量数据复制到 Postgres 的新表中。数据包含装配组件列表,在下面的表定义中进行了简化:

CREATE TABLE IF NOT EXISTS assembly_item (
    id               uuid       NOT NULL DEFAULT  NULL,
    assembly_id.     uuid.      NOT NULL DEFAULT  NULL,
    done_dts         timestamp  NOT NULL DEFAULT 'epoch', 

CONSTRAINT assembly_item_pk
    PRIMARY KEY (id) 
);
Run Code Online (Sandbox Code Playgroud)

原来有几十个属性,现在有几亿行。这些记录分布在多个安装中,并且不存储在本地 Postgres 中。据猜测,该表上的插入量会快速增加,一年内将增长到 1B 行。日期很少更新,也从不删除。(它可能会及时发生,但不会经常发生。)相同的情况永远不会id用不同的值重复。因此,在分区级别上唯一是安全的。这里的目标是将这些数据卸载到 Postgres 上,并仅将最近的数据保留在本地服务器的缓存中。assembly_idid

这看起来像是分区的自然候选者,我正在寻找一些有关合理策略的指导。您可以从简化的结构中看到,我们有一个唯一的 row id、一个parentassembly_id和一个时间戳。我查看了原始数据库中的现有查询,主要搜索字段是assembly_id父记录标识符。assembly和之间的基数assembly_item约为 1:200。

为了使分区最有用,似乎需要根据一个值来分割数据,该值使查询规划器能够智能地修剪分区。我已经想到了一些想法,但还没有 200M 行来再次测试。与此同时,我正在考虑的是:

  • RANGE使用或LISTYYYY-MM的进行按月分区done_dts。按日期范围重写所有查询。

  • HASH根据 的前两个字符进行分区assembly_id::text,得到 256 个大小相当相等的分区。我认为这可以让我们搜索assembly_id并删除许多不匹配的分区,但当我设置它时,它看起来很奇怪。 …

sql postgresql uuid database-design partitioning

3
推荐指数
1
解决办法
6454
查看次数