最近,我将 PostgreSQL 8.2.11 服务器升级到 8.4,以便利用 autovacuum 功能并与 30 左右的其他 PGSQL 服务器保持一致。这是由管理硬件的单独 IT 小组完成的,因此我们在任何其他升级上没有太多选择(暂时不会看到 9+)。服务器存在于一个非常封闭的环境中(隔离网络,有限的root权限),运行在RHEL5.5(i686)上。升级后,数据库以每天 5-6 GB 的速度不断增长。通常情况下,整个数据库大约为 20GB;目前,它是~89GB。我们还有其他几台服务器,它们运行等效的数据库,并通过第 3 方应用程序(我无法访问内部工作原理的应用程序)将记录相互同步。其他数据库应该是~20GB。
运行以下 SQL,很明显特定表存在问题,更具体地说,它的 TOAST 表存在问题。
SELECT nspname || '.' || relname AS "relation",
pg_size_pretty(pg_relation_size(C.oid)) AS "size"
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE nspname NOT IN ('pg_catalog', 'information_schema')
ORDER BY pg_relation_size(C.oid) DESC
LIMIT 20;
Run Code Online (Sandbox Code Playgroud)
其中产生:
关系 | 尺寸 -------------------------------------+--------- pg_toast.pg_toast_16874 | 89GB somes00.warmstates | 1095 MB ... (20 行)
此 TOAST 表用于名为“timeseries”的表,该表保存大量斑点数据记录。SUM(LENGTH(blob)/1024./1024.)时间序列中所有记录的A为该列产生约 16GB。应该有什么理由 …
所以我目前正在创建一些 SQL 来读取 postgres (9.1) 目录以构建表定义。但是,我遇到了 SERIAL/BIGSERIAL 数据类型的问题。
例子:
CREATE TABLE cruft.temp ( id BIGSERIAL PRIMARY KEY );
SELECT * FROM information_schema.columns WHERE table_schema='cruft' AND table_name='temp';
"db","cruft","temp","id",1,"nextval('cruft.temp_id_seq'::regclass)","NO","bigint",,,64,2,0,,,,,,,,,,,,,"db","pg_catalog","int8",,,,,"1","NO","NO",,,,,,,"NEVER",,"YES"
Run Code Online (Sandbox Code Playgroud)
它给了我数据库名 (db)、模式名 (cruft)、表名 (temp)、列名 (id)、默认值 (nextval( ... )) 和数据类型(bigint 和 int8 .. NOT bigserial) ...我意识到我可以检查默认值是否是一个序列 - 但我不相信这会是 100% 准确的,因为我可以手动创建一个序列并创建一个非序列列,其中默认值是那个顺序。
有没有人对我如何实现这一点有建议?除了检查 nextval(*_seq) 的默认值之外还有什么别的方法吗?
针对 TL;DR 或不熟悉 pg_catalog 的新用户在此处添加的 SQL 解决方案进行了编辑:
with sequences as (
select oid, relname as sequencename from pg_class where relkind = 'S'
) select
sch.nspname as schemaname, tab.relname as tablename, col.attname …Run Code Online (Sandbox Code Playgroud) 有没有办法将 Postgres 转储文件转换为文本文件?
我在将转储到正确的文件位置时遇到问题,我只想从转储文件中恢复,然后导出到文本。
真的,我只需要将它导入到 SQLite 数据库中。
我认为这是一个二进制转储。这是最新的转储内容:

我想在触发器的表中插入一个 RECORD 数据类型变量(新变量)。SQL 会是什么样子?
以下尝试均未成功:
EXECUTE 'INSERT INTO my_table VALUES ' || NEW;
EXECUTE 'INSERT INTO my_table VALUES ' || NEW.*;
EXECUTE 'INSERT INTO my_table SELECT * FROM ' || NEW;
Run Code Online (Sandbox Code Playgroud) 我知道INPostgres 中的语句不能保证返回行的顺序。例如,如果我这样做:
SELECT users.id FROM users WHERE users.id IN (13589, 16674, 13588)
Run Code Online (Sandbox Code Playgroud)
我可能会得到这样的结果:
16674
13588
13589
Run Code Online (Sandbox Code Playgroud)
但是,我希望返回的行尊重IN列表中的顺序,所以我在网上找到的解决方案很少,例如:
SELECT users.id FROM users WHERE users.id IN (13589, 16674, 13588)
ORDER BY POSITION(id::text in '(13589, 16674, 13588)')
Run Code Online (Sandbox Code Playgroud)
或者
SELECT users.id FROM users WHERE users.id IN (13589, 16674, 13588)
ORDER BY id = 13589 desc,
id = 16674 desc,
id = 13588 desc;
Run Code Online (Sandbox Code Playgroud)
我想知道是否有更好的方法来做到这一点,或者更好但更有效?
给定band表格,其中一json列包含一个数组:
id | people
---+-------------
1 | ['John', 'Thomas']
2 | ['John', 'James']
3 | ['James', 'George']
Run Code Online (Sandbox Code Playgroud)
如何列出每个名称所属的乐队数量?
期望的输出:
name | count
-------+------------
John | 2
James | 2
Thomas | 1
George | 1
Run Code Online (Sandbox Code Playgroud) 我想验证一json[]列the_array不为空。对于普通数组,我可以检查:
the_array != '{}'
Run Code Online (Sandbox Code Playgroud)
但是,这不适用于 a json[],如下所示:
select '{}'::json[] != '{}'
ERROR: could not identify an equality operator for type json
Run Code Online (Sandbox Code Playgroud)
我可以改用以下检查:
array_length(the_array, 1) != null // yes, array_length on an
empty array returns null
Run Code Online (Sandbox Code Playgroud)
我担心这array_length()会遍历整个数组以计算项目数,然后返回该计数。就我而言,我不需要数组的实际大小,我只需要知道它是否为空。
那么,是否array_length()遍历整个数组?如果是这样,是否有更好的方法来检查 json 数组是否为空?
清理 WAL postgres 的正确方法是什么?我有一个超过 100 GB 的数据库,它在 pg_wal 中有大约 600 GB。我还设置了 2 个逻辑复制。
主从 - Postgres 10。
Master 和 Slaves 有评论wal_keep_segments和max_wal_size。
pg_archivecleanup没有使用%r选项,然后我通过在pg_controldata最新检查点的 REDO WAL 文件中搜索并删除了日志来获取存档名称,但随后一个副本因错误而停止
无法从 WAL 流接收数据:致命:请求的 WAL 段 xxx 已被删除
为了解决这个问题,我删除并重新创建了副本。
我们有一个整数列,目前仅包含 0 或 1 个值。此列现在已被开发人员用于在某些情况下存储唯一的 32 位标识符,我们需要能够有效地提取包含这些标识符中的任何一个的行。
鉴于该值在 99% 的情况下是 0 或 1(我还没有数字),如何最好地索引以查询少数情况?我认为共同价值的数量将成为一个问题是否正确?
Column | Type | Modifiers
----------------------------+---------+--------------------
event_value | integer | not null
Run Code Online (Sandbox Code Playgroud)
此列当前没有索引。而且我不认为需要定期只选择 0 或 1 值。
该表大小合理,目前有 3000 万行并且增长很快。
我很欣赏这不是该专栏的最佳用途,但在短期内不会改变。
我有一个运行以下内容的脚本:
pg_restore tmp/latest.backup --verbose --clean --no-acl --no-owner --dbname hub_development --jobs=12
Run Code Online (Sandbox Code Playgroud)
这经常失败并出现以下错误:
error: could not find block ID 4584 in archive -- possibly due to out-of-order restore request, which cannot be handled due to lack of data offsets in archive
pg_restore: error: a worker process died unexpectedly
Run Code Online (Sandbox Code Playgroud)
反过来,这个错误意味着应该有索引、主键等的表最终没有它们。例如,在没有多核的情况下运行时,我们的users表如下所示,正如预期的那样:
Table "public.users"
Column | Type | Collation | Nullable | Default
--------------------+-----------------------------+-----------+----------+-----------------------------------
id | integer | | not null | nextval('users_id_seq'::regclass)
created_at | timestamp without time zone | | not null …Run Code Online (Sandbox Code Playgroud)