标签: postgresql

PostgreSQL 初始数据库大小

我的问题有两个部分。

  1. 有没有办法在 PostgreSQL 中指定数据库的初始大小?
  2. 如果没有,当数据库随着时间的推移而增长时,您如何处理碎片?

我最近从 MSSQL 迁移到 Postgres,我们在 MSSQL 世界中创建数据库时所做的一件事是指定数据库和事务日志的初始大小。这减少了碎片并提高了性能,特别是如果事先知道数据库的“正常”大小。

我的数据库的性能随着大小的增长而下降。例如,我处理的工作负载通常需要 10 分钟。随着数据库的增长,这个时间会增加。执行 VACUUM、VACUUM FULL 和 VACUUM FULL ANALYZE 似乎不能解决问题。解决性能问题的是停止数据库,对驱动器进行碎片整理,然后进行 VACUUM FULL ANALYZE 使我的测试性能恢复到原来的 10 分钟。这让我怀疑是碎片化是导致我痛苦的原因。

我在 Postgres 中找不到任何关于保留表空间/数据库空间的参考。要么我使用了错误的术语,因此一无所获,要么在 Postgres 中有一种不同的方法来减轻文件系统碎片。

任何指针?

解决方案

提供的答案有助于确认我开始怀疑的内容。PostgreSQL 将数据库存储在多个文件中,这使得数据库可以增长而不必担心碎片化。默认行为是将这些文件与表数据一起打包,这对很少更改的表有好处,但对经常更新的表不利。

PostgreSQL 利用MVCC提供对表数据的并发访问。在此方案下,每次更新都会创建已更新行的新版本(这可能是通过时间戳或版本号,谁知道?)。旧数据不会立即删除,而是标记为删除。执行 VACUUM 操作时会发生实际删除。

这与填充因子有什么关系?表默认填充因子 100 完全填充表页,这反过来意味着表页内没有空间来保存更新的行,即更新的行将放置在与原始行不同的表页中。正如我的经验所示,这对性能不利。由于我的汇总表更新非常频繁(高达 1500 行/秒),我选择将填充因子设置为 20,即表的 20% 用于插入行数据,80% 用于更新数据。虽然这可能看起来过多,但为更新行保留的大量空间意味着更新行与原始行保持在同一页内,并且在 autovacuum 守护程序运行以删除过时行时表页未满。

为了“修复”我的数据库,我执行了以下操作。

  1. 将我的汇总表的填充因子设置为 20。您可以在创建时通过将参数传递给CREATE TABLE或事后通过 ALTER TABLE 来执行此操作。我发出了以下 plpgsql 命令:ALTER TABLE "my_summary_table" SET (fillfactor = 20);
  2. 发出 VACUUM FULL,因为这会写入一个全新版本的表文件,因此暗示会写入一个具有新填充因子的新表文件

重新运行我的测试,即使数据库达到我需要的数百万行,我也没有发现性能下降。

TL;DR …

postgresql sql-server database-size fragmentation

12
推荐指数
2
解决办法
6935
查看次数

从 PostgreSQL 获取随机行?

我想通过 id 从我的表中随机获取一行。

我的表:

ID|Word     |Dificult|Category_id|
1 |'Dumb'   |'Easy'  | 3         |
2 |'Leopard'|'Medium'| 6         |
Run Code Online (Sandbox Code Playgroud)

如果我的用户选择了一个类别和一个困难,我会选择一个带有用户参数的随机单词,例如:

idRaffle := raffle.id;
   -- raffle.id = An id that postgres will bring me by some raffle function. 
d := 'Easy';
c := 3;
select * from words where id=idRaffle and Dificult=d and Category_id=c

raffle.id
Run Code Online (Sandbox Code Playgroud)

我不知道如何获得那个随机行 id ( raffle.id)。

注意它必须遵循用户的选择条件。

postgresql plpgsql

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

处理源 LOB 列时避免“逐行”获取方法

我有一个旧的 PostgreSQL 数据库源 (ODBC),我正在尝试使用 SSIS 将其迁移到新的 SQL Server 架构。我收到警告说:

强制执行“逐行”提取方法,因为该表具有 LOB 列。列内容为 LOB

问题是,没有一个列真的需要是 LOB。有一些是 TEXT 类型,但可以很容易地放在 varchar(max) 中。更奇怪的是,大多数已经varchars,但似乎 varchar(128) 上的任何内容都被视为 LOB(预先属性,数据类型为 DT_NTEXT)。

我尝试执行手动 SQL 命令,其中我在 select 语句中将每个字符串类型显式转换为适当长度的 varchar,并且它们仍然在 ODBC 源中设置为 DT_NTEXT。

我不是 DBA,所以我完全有可能在做一些非常愚蠢的事情。我只想知道确保类型最终成为 varchars 的最佳方法,以便我可以批量获取。有任何想法吗?

以防万一,我在 Visual Studio 2013 中使用 SSIS-BI 2014。

postgresql sql-server migration odbc ssis

12
推荐指数
1
解决办法
1万
查看次数

在 postgresql.conf 中设置 shared_buffers 好像没有生效

我们使用 CentOS 6.6 版,PostgreSQL 8.4.20 版。(是的,这不是最前沿的。)

postgresql.conf,我们有:

shared_buffers = 4096MB
Run Code Online (Sandbox Code Playgroud)

内核 shm 值设置得很好且很高:

[root@green data]# sysctl -a | grep shm
kernel.shmmax = 15922077696
kernel.shmall = 3887226
kernel.shmmni = 4096
kernel.shm_rmid_forced = 0
Run Code Online (Sandbox Code Playgroud)

我们有足够的内存:

[root@green data]# free
             total       used       free     shared    buffers     cached
Mem:      31097812   30474972     622840    2873672    1961088   20565360
-/+ buffers/cache:    7948524   23149288
Swap:      1959920      93852    1866068
Run Code Online (Sandbox Code Playgroud)

然而,shared_buffersreported by的值pg_settings只有 512MB,而不是 4GB 中设置的postgresql.conf

postgres=# select name, setting, min_val, max_val, context from  
pg_settings where …
Run Code Online (Sandbox Code Playgroud)

postgresql performance configuration performance-tuning

12
推荐指数
2
解决办法
2万
查看次数

将两个事件表合并为一个时间线

给定两个表:

CREATE TABLE foo (ts timestamp, foo text);
CREATE TABLE bar (ts timestamp, bar text);
Run Code Online (Sandbox Code Playgroud)

我想编写一个查询,对于回报值tsfoo以及bar代表最新的值的统一视图。换句话说,如果foo包含:

ts | foo
--------
1  | A
7  | B
Run Code Online (Sandbox Code Playgroud)

bar包含:

ts | bar
--------
3  | C
5  | D
9  | E
Run Code Online (Sandbox Code Playgroud)

我想要一个返回的查询:

ts | foo | bar
--------------
1  | A   | null
3  | A   | C
5  | A   | D
7  | B   | D
9  | B …
Run Code Online (Sandbox Code Playgroud)

postgresql join window-functions

12
推荐指数
1
解决办法
2992
查看次数

通过 PostgreSQL 中的视图和触发器跟踪当前用户

我有一个 PostgreSQL (9.4) 数据库,它根据当前用户限制对记录的访问,并跟踪用户所做的更改。这是通过视图和触发器实现的,并且在大多数情况下效果很好,但是我在需要INSTEAD OF触发器的视图上遇到了问题。我试图减少问题,但我提前道歉,这仍然很长。

情况

到数据库的所有连接都是通过单个帐户从 Web 前端建立的dbweb。连接后,角色将通过SET ROLEWeb 界面更改为对应的人,所有此类角色都属于组角色dbuser。(有关详细信息,请参阅此答案)。让我们假设用户是alice

我的大部分表都放置在一个架构中,在这里我将调用该架构private并属于dbowner. 这些表不能直接dbuser被其他角色访问,但可以被其他角色访问dbview。例如:

SET SESSION AUTHORIZATION dbowner;
CREATE TABLE private.incident
(
  incident_id serial PRIMARY KEY,
  incident_name character varying NOT NULL,
  incident_owner character varying NOT NULL
);
GRANT ALL ON TABLE private.incident TO dbview;
Run Code Online (Sandbox Code Playgroud)

特定行对当前用户的可用性alice由其他视图确定。一个简化的例子(可以减少,但需要以这种方式来支持更一般的情况)是:

-- Simplified case, but in principle could join multiple tables to determine allowed ids …
Run Code Online (Sandbox Code Playgroud)

postgresql trigger view

12
推荐指数
1
解决办法
4780
查看次数

\l 中何时列出权限,何时不列出?

\l 什么时候列出访问权限,什么时候不列出?\l 列出的访问权限可以在授予和撤销后更改:

$ createuser -EP my_readonly
$ psql development
development=# \l
                                           List of databases
            Name             |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
-----------------------------+----------+----------+-------------+-------------+-----------------------
 development                 | vagrant  | UTF8     | en_GB.UTF-8 | en_GB.UTF-8 | 
...
development=# grant usage on schema public to my_readonly;
development=# grant connect on database development to my_readonly;
development=# \l
                                             List of databases
            Name             |  Owner   | Encoding |   Collate   |    Ctype    |     Access privileges      
-----------------------------+----------+----------+-------------+-------------+----------------------------
 development                 | vagrant  | UTF8     | en_GB.UTF-8 …
Run Code Online (Sandbox Code Playgroud)

postgresql permissions psql

12
推荐指数
1
解决办法
1108
查看次数

Postgres 函数将两个具有重叠键的 json 对象合并为一个对象

我有以下 JSON 对象:

{
    "a" : {
        "0" : 2,
        "1" : 4,
        "3" : 6,
    },
    "b" : {
        "2" : 8,
        "1" : 10, /*note this key exists in "a" too*/
        "4" : 12,
    }
}
Run Code Online (Sandbox Code Playgroud)

我想生成以下对象,然后能够像这样从中提取元素:

{
        "0" : 2,
        "1" : 10,
        "2" : 8,
        "3" : 6,
        "4" : 12,
}
Run Code Online (Sandbox Code Playgroud)

提取:object->>'1'应该返回'10'

基本上,我有两个键可能重叠的数组,我想合并这两个数组,给一个数组优先级。

我怎样才能做到这一点?理想情况下,我会调用一个类似的函数arrayMerge(a, b),它的'a'优先级高于'b'

postgresql json

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

通过批量迭代表来更新比 PostgreSQL 中的整个表更快

我有一个大约有一百万行的表。

它正在生产中使用,我运行了一个UPDATE覆盖了大约 95% 的行。

之后5小时我取消了请求,因为它正在采取这么长时间。


该表有一个自动递增的 ID 列,因此我尝试将WHERE查询条件扩展为包含id BETWEEN 1 AND 500.

此更新在大约两秒钟内完成。然后我手动迭代了id500 个批次,例如BETWEEN 500 AND 1000, then BETWEEN 1000 AND 1500

按照这个速度,更新整个表需要 2000 个批次,每批次 500 个。

每 2 秒更新 2000 个批次只需一个多小时


我的问题是:

  1. 造成这种差异的原因是什么?
  2. 我不关心事务隔离,所以有没有办法模拟这种“批量更新”,而不必编写 2000 个更新的脚本来单独运行。

postgresql performance update

12
推荐指数
1
解决办法
1万
查看次数

什么是数据库中的表膨胀?

有人可以解释一下数据库术语中的膨胀是什么意思吗?例如,说索引膨胀是什么意思。我试图寻找它,但没有解释什么是腹胀,只有它引起了什么或它是由什么引起的。

postgresql terminology

12
推荐指数
2
解决办法
2万
查看次数