我想保留两个具有相同模式的 PostgreSQL 数据库,但有一个从只保留一小部分实时数据的主数据库复制。
基本上,master 接收实时数据并删除时间窗口之外的旧数据,而复制的 slave 应该保留所有历史数据(至少达到磁盘的限制)。所以本质上,除了删除操作之外,从站应该复制主站。
任何“现成的”PostgreSQL 复制方法都可以做到这一点吗?
我在某些服务器上运行了2 个PostgreSQL实例。一个默认端口(5432)和端口5433.有些用户(和工艺)只需要进入二审(5433)其他实例上,我想设置它,这样,当这些用户使用的命令状psql或createdb在他们的 shell 中,它会自动将他们引导到正确的 Postgres 实例,而不是他们必须-p 5433随着每个命令一起输入。
我试图在 www.postgresql.org 上查找它,但找不到它……可能是我的错。有谁知道怎么做?
从 PostgreSQL 9.0 开始,每个大对象都有自己的访问权限,这些权限被授予:
GRANT { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] }
ON LARGE OBJECT loid [, ...]
TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ]
Run Code Online (Sandbox Code Playgroud)
SELECT 权限允许以只读模式打开对象,对于 UPDATE,文档说:
For large objects, this privilege allows writing or truncating the object.
Run Code Online (Sandbox Code Playgroud)
但是如果一个大对象属于user1,我找不到如何授予user2删除(lo_unlink)这个对象的权限。如果 user1 说GRANT UPDATE on LARGE OBJECT xyz TO user2;并且 user2 运行SELECT lo_unlink(xyz);,则会被拒绝: …
我正在使用一个带有大型 TEXT 字段的 PostgreSQL 表,理论上该表会定期更新。我曾考虑过将数据直接存储在文件系统中,但使用 TOAST 时,数据已经存储在页外并压缩在数据库中,所以我想我会让事情变得简单,只使用数据库存储。
为了提供一些背景信息,我正在为 RSS 提要建立索引。我将每 24 小时运行一个脚本来提取 RSS 源并可能更新表格。这可能会导致大量死元组,从而占用大量磁盘空间。当然,autovacuum 最终会处理这个问题,但它可能会产生大量数据(很多 GB),我想确保我知道当我在这个非常大的表上进行大量更新时会发生什么。
我的一个解决方案是仅在提要发生某些重大更改(例如网站上出现新帖子)时才更新 TEXT 字段(存储 RSS 数据)。这意味着我可以避免进行更新,除非确实必须这样做。但是,我仍然想更新该表(以跟踪我最近执行 HTTP 请求的时间)。这将使用旧版本的行数据创建一个死元组。
如果 TEXT 数据实际上没有改变,会发生什么情况?当 UPDATE 创建死元组时,它还会复制 TEXT 数据吗?或者 TEXT 数据会保持不变,因为它没有更改并且存储在页外?
我在我们的代码库中找到了这个查询:
DELETE FROM "Foo"
WHERE ("Foo"."Id", "Foo"."CreatedAt")
IN (SELECT "f"."Id", "f"."CreatedAt"
FROM "Foo" AS "f"
WHERE "f"."CreatedAt" <= CURRENT_TIMESTAMP);
Run Code Online (Sandbox Code Playgroud)
它删除当前时间之前创建的记录。
这给出了相同的结果:
DELETE FROM "Foo"
WHERE "Foo"."CreatedAt"
IN (SELECT "f"."CreatedAt"
FROM "Foo" AS "f"
WHERE "f"."CreatedAt" <= CURRENT_TIMESTAMP);
Run Code Online (Sandbox Code Playgroud)
我不知道为什么Foo.Id将 包含在WHERE子句中 - 也许是各种重构留下的垃圾(例如,它可能已用于批量删除ORDER BY "f"."Id" LIMIT 1000)。但因为这是一场PK,我不愿意删除它,因为也许它的存在是有原因的。
是否有理论/性能原因将其放在那里,或者这两个查询是否等效?
(这同时针对 postgres 和 sqlite。)
我正在尝试使用 CASE 表达式来选择每行应与哪个表连接。
假设我的游戏中有一个 item_instances 表,其中包含游戏世界中的所有项目,其中一些项目是 item_templates 表中通用项目的千篇一律的副本,而其他项目则以模板开始,然后当玩家使用它们时获得独特的属性。它们现在存储在 unique_items 表中。
因此,当我在 item_instances 表中找到某个项目的记录时,我想查找有关它的更多信息,并且需要从正确的表中提取该信息。
这是我一直在尝试但没有成功的事情:
SELECT item_table, item_id, *
FROM item_instances AS ii
JOIN
CASE ii.item_table
WHEN 0 THEN 'item_templates'
WHEN 1 THEN 'unique_items'
ELSE 'unique_items'
END
ON CASE = ii.item_id;
Run Code Online (Sandbox Code Playgroud)
如果有语法的快速修复,我很想听听。或者,如果这是您在概念上无法做到的事情 - 让每一行选择自己的连接 - 我很乐意获得更深入解释的链接。
过去,我通过执行两个 SELECT 来完成类似的操作,其中一个针对 item_templates 表,另一个针对 unique_items 表,并采用它们的 UNION。这感觉是一种更正确且更少浪费的方法。如果不是出于某种原因与 SQL 更深层次的架构有关,我想了解为什么。
我们有一个由 Postgresql v11.4提供支持的 Rails 应用程序,我想在其中添加一个具有默认值和非空约束的新列,如下所示:
ALTER TABLE "blogs" ADD "published" boolean DEFAULT FALSE NOT NULL
Run Code Online (Sandbox Code Playgroud)
我知道添加具有默认值的新列是安全的。但是,与 组合使用仍然安全吗NOT NULL?或者它会锁定数据库吗?谢谢!
Postgres 文档声明了以下有关仅索引扫描和覆盖索引的内容:
如果您经常运行类似的查询
SELECT y FROM tab WHERE x = 'key';加速此类查询的传统方法是仅在 x 上创建索引。然而,索引定义为
CREATE INDEX tab_x_y ON tab(x) INCLUDE (y);可以将这些查询作为仅索引扫描来处理,因为可以从索引中获取 y 而无需访问堆。
因为列 y 不是索引搜索键的一部分,所以它不必是索引可以处理的数据类型;它仅存储在索引中,并且不被索引机制解释。另外,如果索引是唯一索引,即
CREATE UNIQUE INDEX tab_x_y ON tab(x) INCLUDE (y);唯一性条件仅适用于 x 列,不适用于 x 和 y 的组合。(INCLUDE 子句也可以用 UNIQUE 和 PRIMARY KEY 约束编写,为设置这样的索引提供替代语法。)
问题1:如果 的数据类型y可以添加到索引中,并且没有唯一性要求,那么使用CREATE INDEX tab_x_y ON tab(x) INCLUDE (y)overCREATE INDEX tab_x_y ON tab(x, y)进行查询有什么优势SELECT y FROM tab WHERE x = 'key';?
在向索引添加非键有效负载列(尤其是宽列)时保持保守是明智的做法。如果索引元组超过索引类型允许的最大大小,数据插入将失败。在任何情况下,非键列都会复制索引表中的数据并使索引的大小膨胀,从而可能会减慢搜索速度。 …
我刚刚写了一个很长的问题,关于我如何优化一个相当简单的查询,该查询花费的时间比我希望的要长得多。我一直向pgAdmin查询。然后我使查询变得越来越简单,直到我最终查询一个新创建的表的主键,其中只有 1 行。
create table perf_test (id bigint primary key);
Run Code Online (Sandbox Code Playgroud)
然后查询:
select
count(t.id)
from
perf_test t
where
t.id = 1
;
Run Code Online (Sandbox Code Playgroud)
消息输出为:
Successfully run. Total query runtime: 66 msec.
1 rows affected.
Run Code Online (Sandbox Code Playgroud)
我需要优化一个查询,该查询从我的应用程序发出时通常需要大约 30-40 毫秒。如果 pgAdmin 中最简单的查询的执行时间已经长得多,我该如何实验和测量性能?
我正在尝试 postgres-addon citus。到目前为止,我已经设置了一个包含一个协调器和三个工作节点的集群。
现在我想为其中一个工作节点设置辅助节点。到目前为止,我已经设置了从该工作节点到第四个(备用)节点的流复制。
我现在是否必须使用add_node和 noderole“辅助”将备用节点添加为辅助节点?
citus_add_secondary_node更好,因为您必须使用该命令定义合适的主节点?
或者,设置一个带有 citus 扩展的新数据库就足够了,并且add_node/ secondary会将该节点转变为包含来自工作线程的所有数据的辅助节点?
我使用以下命令获得了辅助节点的正确组 ID:
select * from pg_dist_node;
Run Code Online (Sandbox Code Playgroud) postgresql ×10
alter-table ×1
autovacuum ×1
case ×1
citus ×1
command-line ×1
disk-space ×1
index ×1
join ×1
null ×1
pgadmin ×1
psql ×1
query ×1
sqlite ×1
standby ×1
subquery ×1
update ×1
vacuum ×1