标签: postgresql

如何防止 pg_dump 生成“SET default_table_access_method=heap;”?

我有一个由 PostgreSQL v12 客户端附带生成的大转储文件pg_dump,它是自定义格式而不是纯 sql 文本。服务器的版本也是 PostgreSQL v12。

现在我需要将文件重新加载到 PostgreSQL v11 服务器中,并收到一条错误消息:

unrecognized configuration parameter "default_table_access_method"
Run Code Online (Sandbox Code Playgroud)

我猜测这个参数是PG12引入的,所以PG11无法识别它,即使我使用12版本的pg_restore.

由于该文件很大且采用二进制格式,因此我无法编辑它以手动删除该行。

pg_restore test_file -f plain.sql使用测试转储文件对此进行了测试,看起来可以正常工作,并且我可以从纯 SQL 文件中删除该行。但真实的转储文件约为 30GB,从二进制文件扩展的纯 SQL 文件可能更大(工作数据库占用 300GB 磁盘空间)。

有没有办法,我可以干净地将其重新加载到 PG11 中,而无需“SET default_table_access_method = heap;”行?

其实下面这些都可以忽略,因为都是默认值:

SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security …
Run Code Online (Sandbox Code Playgroud)

postgresql pg-dump downgrade pg-restore postgresql-12

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

为什么 BETWEEN 使用 btree 索引,但“元素包含于”范围运算符 (<@) 却不使用?

我有一个表,utc timestamptz其中的列上有一个“btree”索引utc

CREATE TABLE foo(utc timestamptz)

CREATE INDEX ix_foo_utc ON foo (utc);
Run Code Online (Sandbox Code Playgroud)

该表包含大约5亿行数据。

当我utc使用 进行过滤时BETWEEN,查询规划器按预期使用索引:

> EXPLAIN ANALYZE
SELECT
   utc
FROM foo
WHERE
    utc BETWEEN '2020-12-01' AND '2031-02-15'
;

QUERY PLAN
Bitmap Heap Scan on foo  (cost=3048368.34..11836322.22 rows=143671392 width=8) (actual time=12447.905..165576.664 rows=150225530 loops=1)
Recheck Cond: ((utc >= '2020-12-01 00:00:00+00'::timestamp with time zone) AND (utc <= '2031-02-15 00:00:00+00'::timestamp with time zone))
Rows Removed by Index Recheck: 543231
Heap Blocks: exact=43537 lossy=1818365
->  Bitmap …
Run Code Online (Sandbox Code Playgroud)

postgresql index execution-plan

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

如何同时更新 PostgreSQL 中的唯一键?

CREATE TABLE widget (
  id serial PRIMARY KEY,
  name text NOT NULL,
  ordinal int NOT NULL UNIQUE
);
Run Code Online (Sandbox Code Playgroud)

我有数据

 id | name | ordinal 
----+------+---------
  1 | A    |       1
  2 | B    |       2
  3 | C    |       3
Run Code Online (Sandbox Code Playgroud)

我想将其更新为

 id | name | ordinal 
----+------+---------
  1 | A    |       3
  2 | B    |       2
  3 | C    |       1
Run Code Online (Sandbox Code Playgroud)

尽可能少地接触记录(即不要重写整个记录集,不要启动不必要的触发器),更新为ordinal目标值的通用方法是什么?

普通更新只会给我带来约束违规,即使它发生在单个语句中。

删除并重新创建唯一约束的成本很高,而且并发性很差。

这似乎是一个很常见的问题,应该有一个好的方法来做到这一点,但我只是想不出。

postgresql update unique-constraint

4
推荐指数
2
解决办法
1465
查看次数

我可以对数据库中的所有模式授予 SELECT 权限吗?

我需要创建只能读取(选择)数据的角色用户。我可以针对特定模式执行此操作。但我需要它与所有现有和未来的模式(至少现有)一起工作。我该怎么做?

我试过了

GRANT select ON DATABASE my_db TO my_role;
Run Code Online (Sandbox Code Playgroud)

但它说我不能:

0LP01 无效_授权_操作

ps:我需要向数据库中的所有模式授予选择权限,我只是尝试使用查询中的数据库作为选项来执行此操作,但是如果您知道如何为空数据库的选择授予角色权限,我'我也会很高兴看到这一点

postgresql permissions role select users

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

如何从硬盘驱动器上的 postgres 数据目录恢复数据?

  • 我有一台旧 iMac,不久前就停止工作了
  • 我每周对正在更新的数据库进行备份,其中包含来自多个 rss 提要的提要项目
  • 我仍然缺少上周的数据
  • 我目前拥有旧机器的硬盘,其中包含 postgres 数据目录(它是基于 Intel 的 iMac)
  • 我的新机器是基于 Apple M1 的 mac mini,我想加载所有这些提要项目
  • 我想从包含旧 postgres 文件的硬盘驱动器上的数据目录中的名为 ch_v3 的特定数据库恢复名为 feed_items 的特定表
  • 如何将旧硬盘上以原始格式存储的 100k+ feed 项目恢复到新机器上的新 postgres 安装中?

postgresql recovery restore disaster-recovery

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

Postgresql 13 更改 WAL 段大小

在我的 Ubuntu 20 服务器上,我使用 apt 管理器安装了 PostgreSQL 13。我阅读了一些有关 PostgreSQL 性能调优的文章 [1],并考虑增加 WAL 段大小(默认为 16MB)。我看到以下指令,但是,我不知道在哪里运行它。

initdb -D ./data --wal-segment=1024

我猜文档指的是从 PostgreSQL 源代码安装,我不打算这样做。我该如何更改 WAL 段大小?

[1] https://software.intel.com/content/dam/develop/external/us/en/documents/Open-Source-Database-Tuning-Guide-on-3rd-Generation-Intel-Xeon-Scalable-Processors .pdf


根据丹尼尔的回答,我执行了以下步骤

$ pg_lsclusters
$ sudo pg_dropcluster --stop 13 main
$ sudo pg_createcluster 13 main -- --wal-segsize=256
$ sudo pg_ctlcluster 13 main start
Run Code Online (Sandbox Code Playgroud)

您可以验证 WAL 段的大小为

# du -hcs /var/lib/postgresql/13/main/pg_wal/*
Run Code Online (Sandbox Code Playgroud)

postgresql write-ahead-logging

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

如何“简洁”地检测 PostgreSQL 的 upsert(冲突时)where 子句中的更改值,同时支持 null 更改?

我们维护一个用 PostgreSQL 和 python 实现的大型数据仓库。我们所做的一种非常常见的模式是进行更新插入,并在更新时进行记录。我们有一些独特的键my_key和值,例如my_uuid, my_text, my_int, my_date。如果给定的任何这些值发生变化,my_key我们希望更新该行。没关系,我们有一个运行良好的模式:

insert into my_table (
    my_key,
    my_uuid,
    my_text,
    my_int,
    my_date
)
select
    some_key,
    some_uuid,
    some_text,
    some_int,
    some_date
from some_table
on conflict (my_key) do update set
    some_uuid = excluded.some_uuid,
    some_text = excluded.some_text,
    some_int = excluded.some_int,
    some_date = excluded.some_date,
    update_timestamp = now()
where 
    coalesce(my_table.some_uuid, uuid_nil()) <> coalesce(excluded.some_uuid, uuid_nil())
    or coalesce(my_table.some_text, '') <> coalesce(excluded.some_text, '')
    or coalesce(my_table.some_int, -1) <> coalesce(excluded.some_int, -1)
    or coalesce(my_table.some_date, '3000-01-01'::date) <> coalesce(excluded.some_date, '3000-01-01'::date)
Run Code Online (Sandbox Code Playgroud)

最后一个on conflict …

postgresql null update change-tracking upsert

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

关于 postgres 中几乎无间隙序列的建议

在 PostgreSQL 中,由于本文/sf/ask/698893751/中提到的原因,序列被设计为有间隙。我的问题是:是否可以通过定期(假设每天一次)检查哪些序列号未使用并将其添加回序列中以供使用,从而使序列几乎无间隙?

我假设当前 postgres 实现了一个序列作为计数器,每次访问它时它都会递增。相反,它可以通过自由值列表和计数器来实现。该序列将按如下方式工作:

# python style pseudo code

class Sequence:
    def __init__(self):
        self.free_numbers_set = []
        self.counter = 0

    def get_next_sequence_value(self):
        if not isempty(self.free_numbers_set):
            id = self.free_numbers_set.pop(0)
        else:
            id = self.counter
            id ++

        return id

    def add_free_numbers(self, column):
        for i in range(0:self.counter):
            if not i in column:
                free_numbers_set.append(i)
        free_numbers_set.sort()
Run Code Online (Sandbox Code Playgroud)

每当我们需要一个新的 id 时,get_next_sequence_value()我们就会定期运行add_free_numbers(column)

更新解决一些问题

  1. 对于标识列,获取当前使用的值将是微不足道的。在其他情况下,由用户提供已在使用的值的列表。
  2. 需要考虑与 MVCC 的交互。人们可以潜在地实现它,以便在缺失值更新期间,序列将默认为仅递增计数器 - 这将避免冲突。

我相信这个解决方案可以提供更少的稀疏序列,这将允许用户使用更小的 id 类型(int 与 bigint),同时向后兼容当前的实现。

postgresql sequence database-internals

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

查找创建或重新索引索引时的时间戳

有什么方法可以找到 PostgreSQL 12-13 中索引上次创建或重新索引的时间吗?

文档显示了一些标准视图,例如pg_stat_user_indexes跟踪索引的使用统计信息,但我找不到任何跟踪创建/更新统计信息的内容。

postgresql index metadata change-tracking

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

如何获得 OR'ed 时间范围谓词的索引扫描?

我有events包含字段的表:

id
user_id
time_start
time_end
...
Run Code Online (Sandbox Code Playgroud)

并在 上有 B 树索引(time_start, time_end)

SELECT user_id
FROM events
WHERE ((time_start <= '2021-08-24T15:30:00+00:00' AND time_end >= '2021-08-24T15:30:00+00:00') OR
       (time_start <= '2021-08-24T15:59:00+00:00' AND time_end >= '2021-08-24T15:59:00+00:00'))
GROUP BY user_id);
Run Code Online (Sandbox Code Playgroud)
Group  (cost=243735.42..243998.32 rows=1103 width=4) (actual time=186.533..188.244 rows=166 loops=1)
  Group Key: user_id
  Buffers: shared hit=224848
  ->  Gather Merge  (cost=243735.42..243992.80 rows=2206 width=4) (actual time=186.532..188.199 rows=176 loops=1)
        Workers Planned: 2
        Workers Launched: 2
        Buffers: shared hit=224848
        ->  Sort  (cost=242735.39..242738.15 rows=1103 width=4) (actual time=184.121..184.126 rows=59 loops=3) …
Run Code Online (Sandbox Code Playgroud)

postgresql index range-types query-performance postgresql-performance

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