我需要每天(也可以连续)将 Postgres 数据库复制到另一台服务器,但不更改 Postgres 设置。
我无法更改数据库设置,因为它来自我的客户端。我只有用户、密码和主机等凭据。
如果需要的话,我可以安装任何软件到服务器上,但我无法更改设置。而且我不想每天发送完整备份,因为数据库太重了。
我需要客户端的数据库,因为我们在服务器中处理大量数据。
我搜索过的所有地方,总是说在中启用和配置 WAL postgresql.conf
。但我无法更改此文件。
我需要每天(也可以连续)将 Postgres 数据库复制到另一台服务器,但不更改 Postgres 设置。
我无法更改数据库设置,因为它来自我的客户端。我只有用户、密码和主机等凭据。
如果需要的话,我可以安装任何软件到服务器上,但我无法更改设置。而且我不想每天发送完整备份,因为数据库太重了。
我需要客户端的数据库,因为我们在服务器中处理大量数据。
我搜索过的所有地方,总是说在中启用和配置 WAL postgresql.conf
。但我无法更改此文件。
amcheck报告以下错误:
select bt_index_parent_check(34465);
ERROR: item order invariant violated for index "admin_access_rights_pkey"
DETAIL: Lower index tid=(282,71) (points to heap tid=(201,46)) higher index tid=(282,72) (points to heap tid=(197,38)) page lsn=396C/DDF2FD00
我该如何修复这个问题?
文档表明这REINDEX
可能没有帮助。
REINDEX 可能无法有效修复损坏。
編輯:
我需要从某些 PostgreSQL 表中删除外键约束。但是,这些表使用频繁,包含大量数据。有些表已分区,而有些则未分区。
当我尝试修改表以删除外键时,它会导致锁定,除非我们安排停机时间,否则锁定会中断正在进行的操作或由于某些写操作而被锁定。
有没有办法从 PostgreSQL 中的表中删除外键约束而不会导致锁或影响正在进行的操作?
任何建议或最佳实践都将受到赞赏。
PS:我确实认为如果没有锁,可能会导致数据一致性、完整性和并发控制问题。
我看到 PostgreSQL 17 引入了增量备份,这听起来真的很棒!我想知道它是否可以用于恢复增量备份。
我们的用例是,我们有一个数据库服务器。目前,当我们需要停机时,我们会停止应用程序,pg_dump 主数据库,在辅助服务器上恢复它,然后重新启动指向辅助数据库的应用程序。当主数据库服务器上的停机完成后,我们会执行相反的操作。目前,从转储到恢复通常需要大约 20 分钟,我希望进一步缩短这一时间。
我希望能够让数据库保持运行,转储现有数据库并将其恢复到辅助数据库。然后停止数据库,执行增量备份并恢复,然后启动辅助数据库。
我想这会为我们节省大量停机时间,并使我们的设置保持简单。我们可以考虑使用复制的更复杂的解决方案,但这似乎比我们真正需要的更复杂。
我有一张包含 3.5 亿条记录的 Postgres 表。我在该表上有 3 个索引:
historical_offers(recovery_date, uprn)
historical_offers(recovery_date, account_id)
historical_offers(recovery_date, individual_id)
如果我针对 24 小时之前的日期运行查询,它很快。但如果我针对今天(有时是昨天)运行查询,它就太慢了(0.05 毫秒 vs 300 毫秒)。
我的查询针对所有 3x 字段,并使用 3x 索引,然后针对日期 > 24 小时~ 快速完美地混合结果。因此,我认为这与 3x 字段上的 OR 条件需要使用 3x 索引无关。此外:如果我将查询修改为仅在 1 个字段上运行,我会遇到同样的问题。
目前的理论:
响应缓慢(今天):
EXPLAIN ANALYZE SELECT * FROM historical_offers.historical_offers WHERE (historical_offers.uprn = '1001005' OR historical_offers.account_id = 'SW1006' OR historical_offers.individual_id = '6752da6') AND (historical_offers.recovery_date = '2025-01-02');
+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| QUERY PLAN |
|------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Index Scan using historical_offers_date_individual_id_idx on historical_offers (cost=0.57..8.56 rows=1 width=174) (actual time=346.467..346.467 rows=0 loops=1) |
| Index Cond: (recovery_date = '2025-01-02'::date) |
| Filter: (((uprn)::text = '1001005'::text) OR ((account_id)::text = 'SW1006'::text) OR ((individual_id)::text = '6752da6'::text)) |
| Rows Removed by Filter: 1470748 |
| Planning Time: 0.099 ms |
| Execution Time: 346.488 ms |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
EXPLAIN 6
Time: 0.383s
快速查询(2天前):
EXPLAIN ANALYZE SELECT * FROM historical_offers.historical_offers WHERE (historical_offers.uprn = '1001005' OR historical_offers.account_id = 'SW1006' OR historical_offers.individual_id = '6752da6') AND (historical_offers.recovery_date = '2025-01-01');
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| QUERY PLAN |
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Bitmap Heap Scan on historical_offers (cost=13.88..78.14 rows=16 width=174) (actual time=0.031..0.032 rows=0 loops=1) |
| Recheck Cond: (((recovery_date = '2025-01-01'::date) AND ((uprn)::text = '1001005'::text)) OR ((recovery_date = '2025-01-01'::date) AND ((account_id)::text = 'SW1006'::text)) OR ((recovery_date = '2025-01-01'::date) AND ((individual_id)::text = '6752da6'::text))) |
| -> BitmapOr (cost=13.88..13.88 rows=16 width=0) (actual time=0.030..0.030 rows=0 loops=1) |
| -> Bitmap Index Scan on historical_offers_date_uprn_idx (cost=0.00..4.62 rows=5 width=0) (actual time=0.013..0.013 rows=0 loops=1) |
| Index Cond: ((recovery_date = '2025-01-01'::date) AND ((uprn)::text = '1001005'::text)) |
| -> Bitmap Index Scan on historical_offers_date_account_id_idx (cost=0.00..4.62 rows=5 width=0) (actual time=0.008..0.008 rows=0 loops=1) |
| Index Cond: ((recovery_date = '2025-01-01'::date) AND ((account_id)::text = 'SW1006'::text)) |
| -> Bitmap Index Scan on historical_offers_date_individual_id_idx (cost=0.00..4.62 rows=5 width=0) (actual time=0.008..0.008 rows=0 loops=1) |
| Index Cond: ((recovery_date = '2025-01-01'::date) AND ((individual_id)::text = '6752da6'::text)) |
| Planning Time: 0.113 ms |
| Execution Time: 0.054 ms |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
EXPLAIN 11
Time: 0.026s
我正在处理一个包含大约 7000 万条记录的表。我需要在这个表上创建一个主键和几个索引。我使用的 SQL 查询如下:
BEGIN;
ALTER TABLE table_name ADD CONSTRAINT table_name_pkey PRIMARY KEY (uniqueid);
CREATE INDEX IF NOT EXISTS table_name_column1_idx ON table_name (column1);
CREATE INDEX IF NOT EXISTS table_name_column2_idx ON table_name (column2);
CREATE INDEX IF NOT EXISTS table_name_column3_idx ON table_name (column3);
CREATE INDEX IF NOT EXISTS table_name_column4_idx ON table_name (column4);
CREATE INDEX IF NOT EXISTS table_name_column5_idx ON table_name (column5);
COMMIT;
但是,执行这些查询需要花费相当长的时间。我没有任何资源限制,因此我正在寻找优化此过程的方法。具体来说,我正在考虑从 Python Django 应用程序并行或同时运行这些 SQL 查询。
我的问题是:
1.我可以使用哪些策略来最小化锁并加快索引过程?
2.是否有任何最佳实践或工具可以帮助有效地管理大型表上的多个索引的创建?
3.在索引创建期间使用 BEGIN; COMMIT; 是否有任何性能优势?
如有任何建议或推荐我将不胜感激。
我正在使用 AGI 生成 Postgres SQL(AWS RDS Postgres),但我想阻止用户询问有关底层表的问题,例如“显示所有数据库”、“显示所有用户”,这些问题会导致诸如SELECT * FROM pg_database
和之类的查询SELECT * FROM pg_roles
。
我为此制定的工作脚本是:
连接到postgres
(postgres
超级用户):
CREATE ROLE client_creator WITH LOGIN PASSWORD '<generate>' CREATEDB CREATEROLE;
連接postgres
至client_creator
:
CREATE DATABASE "client_db";
CREATE ROLE "client_reader" WITH LOGIN PASSWORD '<generate>';
連接client_db
至client_creator
GRANT CONNECT, TEMPORARY ON DATABASE "client_db" TO "client_reader";
GRANT SELECT ON ALL TABLES IN SCHEMA public TO "client_reader";
GRANT USAGE ON SCHEMA public TO "client_reader";
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO "client_reader";
REVOKE ALL PRIVILEGES ON SCHEMA pg_catalog FROM client_reader;
REVOKE ALL PRIVILEGES ON SCHEMA pg_catalog FROM public;
问题是最后两个REVOKE
命令似乎没有效果,因为我仍然可以运行SELECT * FROM pg_roles
并接收所有行。
我也尝试过撤销SELECT
表格pg_catalog
。
问题是:
我想在 Postgresql 上使用外部合并排序算法对随机记录进行排序的基准测试。因此,我尝试了以下两种方法(一个接一个,保持所有参数/配置相同):
尝试 1:
CREATE TABLE test(id BIGINT, name varchar(200));
INSERT INTO test (id,name) SELECT (random() * 1000000), concat(CONCAT(md5(random()::text), md5(random()::text))) FROM generate_series(1, 1000000) as t;
explain analyze select * from test order by id, name;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------
Gather Merge (cost=41486.43..63526.06 rows=188898 width=426) (actual time=76.477..207.253 rows=1000000 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Sort (cost=40486.40..40722.52 rows=94449 width=426) (actual time=73.418..101.593 rows=333333 loops=3)
Sort Key: id, name
Sort Method: external merge Disk: 29744kB
Worker 0: Sort Method: external merge Disk: 26008kB
Worker 1: Sort Method: external merge Disk: 25512kB
-> Parallel Seq Scan on test (cost=0.00..14278.49 rows=94449 width=426) (actual time=0.011..20.945 rows=333333 loops=3)
Planning Time: 2.820 ms
Execution Time: 227.090 ms
(11 rows)
尝试2:
explain analyze SELECT (random() * 1000000) as id, concat(CONCAT(md5(random()::text), md5(random()::text))) as name
FROM generate_series(1, 1000000) as t order by id, name;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------
Sort (cost=194348.85..196848.85 rows=1000000 width=40) (actual time=1707.086..1768.986 rows=1000000 loops=1)
Sort Key: ((random() * '1000000'::double precision)), (concat(concat(md5((random())::text), md5((random())::text))))
Sort Method: external merge Disk: 81256kB
-> Function Scan on generate_series t (cost=0.00..40000.00 rows=1000000 width=40) (actual time=55.734..1388.681 rows=1000000 loops=1)
Planning Time: 0.191 ms
JIT:
Functions: 3
Options: Inlining false, Optimization false, Expressions true, Deforming true
Timing: Generation 0.338 ms (Deform 0.000 ms), Inlining 0.000 ms, Optimization 0.497 ms, Emission 11.837 ms, Total 12.672 ms
Execution Time: 1841.843 ms
(10 rows)
有人能向我解释一下,为什么对随机生成的数据进行排序比对磁盘中的类似随机数据进行排序慢吗?
我重新运行了这两个查询max_parallel_workers_per_gather = 0
;第一个查询的延迟下降到 360 毫秒,而正如预期的那样,第二个查询没有变化。
我最近发现我们的一个系统使用默认的 postgres 数据库作为......嗯,数据库。
我想将所有数据移动到同一集群中的另一个数据库。但是数据库相对较大,并且系统有点 24/7 全天候运行。
也许我可以简单地重命名 postgres db?然后创建另一个名为 postgres 的数据库并将其用作维护数据库。
这听起来不安全,我的直觉告诉我应该坚持传统的转储/恢复方法。
也许我反应过度了?