标签: postgresql

Postgresql 10:使用精确堆块进行位图堆扫描

我有以下查询:

select ro.*
from courier c1
    join courier c2 on c2.real_physical_courier_1c_id = c1.real_physical_courier_1c_id
    join restaurant_order ro on ro.courier_id = c2.id
    left join jsonb_array_elements(items) jae on true
    left join jsonb_array_elements(jae->'options') ji on true
    inner join catalogue c on c.id in ((jae->'id')::int, (ji->'id')::int)
    join restaurant r on r.id = ro.restaurant_id
where c1.id = '7b35cdab-b423-472a-bde1-d6699f6cefd3' and ro.status in (70, 73)
group by ro.order_id, r.id ;
Run Code Online (Sandbox Code Playgroud)

以下是占用约 95% 时间的查询计划的一部分:

->  Parallel Bitmap Heap Scan on restaurant_order ro  (cost=23.87..2357.58 rows=1244 width=1257) (actual time=11.931..38.163 rows=98 loops=2)" …
Run Code Online (Sandbox Code Playgroud)

postgresql execution-plan postgresql-performance

2
推荐指数
1
解决办法
973
查看次数

编写一个查询,如果目标行上有锁,该查询将退出

是否可以编写一个UPDATE查询,如果它尝试更改的记录被另一个进程锁定(而不是等待锁被释放),则该查询将简单地退出?

我有一个进程应该更新表中的记录,有时这些记录会被锁定。更新这些记录是可取的,但不是必需的。如果记录正在使用中,我宁愿我的流程忘记更新并继续处理更重要的事情。

我当前的方法是将命令超时设置为 1 秒,但即使这也比我想要等待的时间长 - 正常更新需要不到一毫秒,因此等待一秒是一个主要开销。

postgresql locking update query-performance

2
推荐指数
1
解决办法
5294
查看次数

创建新数据库时不会设置排序规则

我正在尝试在 PostgreSQL 13 中设置新数据库的排序规则,但它似乎没有生效:

postgres=# CREATE DATABASE assets ENCODING 'UTF8' LC_COLLATE 'C' LC_CTYPE 'en_US.UTF-8';
CREATE DATABASE
postgres=# \l
                                      List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
-----------+----------+----------+-------------+-------------+-----------------------
 assets    | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.UTF-8 | …
Run Code Online (Sandbox Code Playgroud)

postgresql collation postgresql-13

2
推荐指数
1
解决办法
6666
查看次数

PostgreSQL 由于设备空间不足而崩溃

PostgreSQL 11我们在服务器下运行CentOS 7。最近,我们在日志中发现了几个导致 PostgreSQL 服务器崩溃的警告:

2022-05-09 23:26:29 EDT pg_restore      db123      132.132.132.32  postgres        ERROR:  could not extend file "base/71592268/71621568": No space left on device
2022-05-09 23:26:29 EDT pg_restore      db123      132.132.132.32  postgres        HINT:  Check free disk space.
(...)
2022-05-09 23:26:33 EDT                                 DETAIL:  Could not open file "pg_notify/0000": No space left on device.
2022-05-09 23:26:34 EDT                                 LOG:  database system is shut down
Run Code Online (Sandbox Code Playgroud)

目录下有几个数据库/var/lib/pgsql/11/data/base/

# du -h /var/lib/pgsql/11/data/base/
7.7M    /var/lib/pgsql/11/data/base/1
7.7M    /var/lib/pgsql/11/data/base/13877
8.1M    /var/lib/pgsql/11/data/base/13878
0       /var/lib/pgsql/11/data/base/pgsql_tmp
61M     /var/lib/pgsql/11/data/base/852671
166M …
Run Code Online (Sandbox Code Playgroud)

postgresql disk-space crash

2
推荐指数
1
解决办法
1911
查看次数

ALTER TABLE … ADD COLUMN 在一个小表上花费很长时间,pg_stat_activity 不显示该表上的任何查询

所以这是永远挂起的查询:

ALTER TABLE tasks
ADD COLUMN in_progress BOOLEAN NOT NULL DEFAULT FALSE;
Run Code Online (Sandbox Code Playgroud)

该表tasks少于 20,000 行,每 5 分钟左右查询一次。

我检查了pg_stat_activity大约 10 次,但从未显示任何锁定表的查询:

SELECT *
FROM pg_stat_activity
WHERE query LIKE '%tasks%';

--- No results
Run Code Online (Sandbox Code Playgroud)

我尝试了真空吸尘器,但没有帮助:

VACUUM (VERBOSE, ANALYZE) tasks;
Run Code Online (Sandbox Code Playgroud)

我还尝试添加没有约束和默认值的列,我希望在这样的表上几乎是即时的,但是当我停止查询时,查询已经运行了 1 分钟:

ALTER TABLE tasks
ADD COLUMN in_progress BOOLEAN;
Run Code Online (Sandbox Code Playgroud)

我在同一时间段内对另一个表(约 1000 行)运行了查询,结果是即时的。

任何想法?

PostgreSQL 11.13

通过 DBeaver 执行的查询(为了以防万一,我多次无效/重新连接)。

postgresql alter-table locking

2
推荐指数
1
解决办法
4968
查看次数

如果PostgreSQL数据库或服务器异常关闭,脏数据会怎样?

假设我的 PostgreSQL 实例突然异常停止,并且数据是脏的并且没有保存在 RAM 或 WAL 中。那样的话会发生什么?

我可以从哪里恢复这些数据?如果服务器也关闭,在这种情况下脏数据会发生什么?

是否有任何单独的文件来存储脏数据以进行恢复?

postgresql database-design postgresql-performance postgresql-13 postgresql-14

2
推荐指数
1
解决办法
274
查看次数

从 GROUP BY 创建表会使用大量临时磁盘空间 - 可以避免吗?

我有一个包含约 20 亿行数据的表,我想创建另一个包含一些聚合的表。看起来 PostgreSQL 使用临时磁盘空间来执行这些查询。我可以创建表...

CREATE TABLE my_new_table ...
Run Code Online (Sandbox Code Playgroud)

但是当我插入数据时:

INSERT INTO my_new_table SELECT
   col_1,
   col_2,
   col_3,
   col_4,
   col_5,
   col_6,
   col_7,
   col_8,
   col_9,
   sum(col_10),
   sum(col_11)
FROM
   my_table
GROUP BY
   1,2,3,4,5,6,7,8,9
Run Code Online (Sandbox Code Playgroud)

PostgreSQL 似乎使用临时文件来存储结果,并且空间不足,例如出现如下错误:

无法写入文件“base/pgsql_tmp/pgsql_tmp31757.25”:设备上没有剩余空间

从 EXPLAIN 的结果来看,我怀疑这是来自某种排序。有办法避免这种情况吗?不会有那么多的输出行,所以不知何故,我觉得好像应该有一种方法可以在输出处做得更到位......但这是一个非常模糊的直觉。

postgresql disk-space group-by postgresql-10 aws-aurora

2
推荐指数
1
解决办法
329
查看次数

如何判断哪些外键是循环的?正如 pg_dump 的警告所强调的那样

pg_dump当在本地容器中运行的(时间尺度)数据库上执行时,我有以下内容:

pg_dump: warning: there are circular foreign-key constraints on this table:
pg_dump:   hypertable
Run Code Online (Sandbox Code Playgroud)

我为上述运行的命令:

pg_dump --schema-only -h localhost --port 5432 --dbname db --username user > schema.sql
Run Code Online (Sandbox Code Playgroud)

我不知道如何使用 postgres 检查哪些键是循环的。

我可以浏览所有表格并手动跟踪哪些键指向我猜测的 - 但我希望有一种更直接的方法来确定哪些键是循环的以及在哪里,以便我可以修复它们。

postgresql foreign-key timescaledb

2
推荐指数
1
解决办法
1660
查看次数

Postgres 列限制

我有一个 PostgreSQL 表,目前非常大:340 列。该表旨在保存复杂 PDF 的样式。

随着时间的推移,我做出了一些改变:删除了一些列,添加了一些新的列等等......并且它可能仍会进一步发展。实际上我当前的需要是将列数加倍。

根据https://www.postgresql.org/docs/current/limits.html,表的上限是:

  • 1600列
  • 8192 字节的堆页

我在 Rails 应用程序中模拟了所有可能的情况来计算最大堆页,目前看起来不错,大小为 2.5KB。我的大多数列都是布尔类型(1 字节)、整数(4 字节)和双精度(8 字节)类型。还有一些特征有所不同,但数量很少。

Postgres 文档还指定:“从表中删除的列也会影响最大列限制。此外,尽管新创建的元组的删除列值在元组的空位图中内部标记为空,但空位图也占用空间”。

由于我不想使用 JSON 列,因此我不会将列数加倍,而是创建另一个表。然而,上述 340 列可能会比 340 列进一步推进。

所以这是我的问题:

  • 如何从 psql 客户端了解列的总数,包括已销毁的列
  • 被破坏的列中的元组的大小是多少?
  • 是否可以从特定记录(仍然是 psql )获取堆页面大小?
  • 如果达到两个限制之一,数据库将如何失败:数据库是否损坏、表损坏还是只是记录损坏(如果达到的限制是堆页大小)

postgresql

2
推荐指数
1
解决办法
1459
查看次数

PostgreSQL 中 FETCH FIRST 和 FETCH NEXT 有什么区别?

FETCH FIRSTPostgreSQL和PostgreSQL之间有什么区别FETCH NEXT?文档只是

NEXT 获取下一行

FIRST 获取查询的第一行

这没什么解释。我创建了一个包含示例行的示例表,并执行

SELECT * from users
FETCH FIRST 2 ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)
SELECT * from users
FETCH NEXT 2 ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)

并得到完全相同的输出。它几乎就像 ifFETCH FIRSTFETCH NEXT只是同义词LIMIT(我读到,它不是 SQL 标准的一部分,与 不同FETCH [FIRST|NEXT]

如果两者相同,为什么文档不这么说?还是毕竟存在一些差异?

这个 Stack Overflow 答案意味着它们至少在某些 RDBMS 中可能以相同的方式运行,特别是在 MS Server 中

postgresql offset-fetch

2
推荐指数
1
解决办法
776
查看次数