PostgreSQL
PostgreSQL 是一个开源的、社区驱动的、符合标准的面向对象的关系型数据库系统。
安装
安装 postgresql 软件包。它还将创建一个名为 postgres 的系统用户。
现在您可以使用 权限提升程序 切换到 postgres 用户。
初始配置
在 PostgreSQL 正常运行之前,必须初始化数据库集群
[postgres]$ initdb -D /var/lib/postgres/data
其中 -D
是数据库集群必须存储的默认位置(如果您想使用不同的位置,请参阅 #更改默认数据目录)。initdb
接受许多额外的参数
- 默认情况下,数据库集群的区域设置和编码 派生自您当前的环境(使用 $LANG 值)。如果这不是您想要的,您可以使用
--locale=locale
(其中 locale 是从系统的 可用区域设置 中选择的)和--encoding=encoding
(必须与选择的区域设置匹配)来覆盖默认值。(数据库启动后,您可以使用[postgres]$ psql -l
检查使用了哪些值。) - 如果您的数据目录位于没有数据校验和的文件系统上,您可能希望启用 PostgreSQL 的内置 校验和 以提高完整性保证 - 添加
--data-checksums
参数即可实现。阅读 #启用数据校验和 了解更多信息。(数据库启动后,您可以使用[postgres]$ psql --tuples-only -c "SHOW data_checksums"
检查是否已启用。)
- 默认情况下使用 trust 身份验证方法,这意味着主机上的任何人都可以在不提供密码的情况下以任何数据库用户的身份连接。您可以使用
--auth-local=peer --auth-host=scram-sha-256
来获得更安全的身份验证方法。 -c
/--set
选项可用于设置任何postgresql.conf
参数,从而避免手动编辑postgresql.conf
的需要。- 有关更多选项,请参阅
initdb --help
和 官方文档。
示例
[postgres]$ initdb --locale=C.UTF-8 --encoding=UTF8 -D /var/lib/postgres/data --data-checksums
现在屏幕上应该出现许多行,其中几行以 ... ok
结尾
The files belonging to this database system will be owned by user "postgres". This user must also own the server process. The database cluster will be initialized with locale "C.UTF-8". The default text search configuration will be set to "english". Data page checksums are enabled. creating directory /var/lib/postgres/data ... ok creating subdirectories ... ok selecting dynamic shared memory implementation ... posix selecting default max_connections ... 100 selecting default shared_buffers ... 128MB selecting default time zone ... UTC creating configuration files ... ok running bootstrap script ... ok performing post-bootstrap initialization ... ok syncing data to disk ... ok initdb: warning: enabling "trust" authentication for local connections initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb. Success. You can now start the database server using: pg_ctl -D /var/lib/postgres/data -l logfile start
如果您看到的是这些行,则表示该过程成功。使用 exit
返回到常规用户。
- 要了解有关此 initdb 警告的更多信息,请参阅 #默认限制对数据库超级用户的访问权限。
- 如果数据库位于 Btrfs 文件系统上,您应该考虑在创建任何数据库之前禁用该目录的 写入时复制。
- 如果数据库位于 ZFS 文件系统上,您应该在创建任何数据库之前查阅 ZFS#数据库。
最后,启动 并 启用 postgresql.service
。
创建您的第一个数据库/用户
成为 postgres 用户。使用 createuser 命令添加新的数据库角色/用户
[postgres]$ createuser --interactive
创建一个新数据库,上面的用户具有该数据库的读/写权限,使用 createdb 命令(如果数据库用户名与您的 Linux 用户名相同,则从您的登录 shell 执行此命令,否则在以下命令中添加 -O database-username
)
$ createdb myDatabaseName
-U postgres
。熟悉 PostgreSQL
访问数据库 shell
成为 postgres 用户。启动主数据库 shell,psql,您可以在其中完成所有数据库/表的创建、删除、设置权限和运行原始 SQL 命令。使用 -d
选项连接到您创建的数据库(如果不指定数据库,psql
将尝试访问与您的用户名匹配的数据库)。
[postgres]$ psql -d myDatabaseName
一些有用的命令
获取帮助
=> \help
列出所有数据库
=> \l
连接到特定数据库
=> \c database
列出所有用户及其权限级别
=> \du
显示当前数据库中所有表的摘要信息
=> \dt
退出/退出 psql
shell
=> \q
或按 Ctrl+d
。
当然还有更多元命令,但这些应该可以帮助您入门。要查看所有元命令,请运行
=> \?
可选配置
PostgreSQL 数据库服务器配置文件是 postgresql.conf
。此文件位于服务器的数据目录中,通常为 /var/lib/postgres/data
。此文件夹还包含其他主要配置文件,包括 pg_hba.conf
,它定义了 本地用户 和 其他主机 的身份验证设置。
find
和 locate
找不到配置文件的原因。默认限制对数据库超级用户的访问权限
默认的 pg_hba.conf
允许任何本地用户以任何数据库用户的身份连接,包括数据库超级用户。这可能不是您想要的,因此为了限制对 postgres 用户的全局访问,请更改以下行
/var/lib/postgres/data/pg_hba.conf
# TYPE DATABASE USER ADDRESS METHOD # "local" is for Unix domain socket connections only local all all trust
改为
/var/lib/postgres/data/pg_hba.conf
# TYPE DATABASE USER ADDRESS METHOD # "local" is for Unix domain socket connections only local all postgres peer
您稍后可能会根据您的需求或软件需求添加其他行。
登录需要密码
编辑 /var/lib/postgres/data/pg_hba.conf
并将每个用户(或 all
以影响所有用户)的身份验证方法设置为 scram-sha-256
/var/lib/postgres/data/pg_hba.conf
# TYPE DATABASE USER ADDRESS METHOD # "local" is for Unix domain socket connections only local all user scram-sha-256
重启 postgresql.service
,然后使用 ALTER USER user WITH ENCRYPTED PASSWORD 'password';
重新添加每个用户的密码。
配置 PostgreSQL 以仅通过 UNIX 套接字访问
当 初始创建集群 时,将 -c listen_addresses=''
附加到 initdb 命令。
对于现有集群,编辑 postgresql.conf
并在连接和身份验证部分设置
/var/lib/postgres/data/postgresql.conf
listen_addresses = ''
这将完全禁用网络监听。之后,您应该 重启 postgresql.service
以使更改生效。
配置 PostgreSQL 以从远程主机访问
在连接和身份验证部分中,根据您的需要设置 listen_addresses
行
/var/lib/postgres/data/postgresql.conf
listen_addresses = 'localhost,my_local_ip_address'
您可以使用 '*'
来监听所有可用的地址。
5432
进行远程连接。确保您的 防火墙 中打开了此端口,并且能够接收传入连接。您也可以在配置文件中更改它,就在 listen_addresses
下面然后添加如下行到身份验证配置中
/var/lib/postgres/data/pg_hba.conf
# TYPE DATABASE USER ADDRESS METHOD # IPv4 local connections: host all all ip_address/32 scram-sha-256
其中 ip_address
是远程客户端的 IP 地址。
请参阅 pg_hba.conf 的文档。
之后,您应该 重启 postgresql.service
以使更改生效。
要进行故障排除,请查看服务器日志文件
# journalctl -u postgresql.service
配置 PostgreSQL 以针对 PAM 进行身份验证
PostgreSQL 提供了许多身份验证方法。如果您想允许用户使用其系统密码进行身份验证,则需要执行其他步骤。首先,您需要为连接启用 PAM。
例如,与上面相同的配置,但启用了 PAM
/var/lib/postgres/data/pg_hba.conf
# IPv4 local connections: host all all my_remote_client_ip_address/32 pam
但是,PostgreSQL 服务器在没有 root 权限的情况下运行,将无法访问 /etc/shadow
。我们可以通过允许 postgres 组访问此文件来解决此问题
# setfacl -m g:postgres:r /etc/shadow
更改默认数据目录
所有新创建的数据库将存储的默认目录是 /var/lib/postgres/data
。要更改此目录,请按照以下步骤操作
创建新目录并使 postgres 用户成为其所有者
# mkdir -p /pathto/pgroot/data # chown -R postgres:postgres /pathto/pgroot
成为 postgres 用户,并初始化新集群
[postgres]$ initdb -D /pathto/pgroot/data
编辑 postgresql.service
以创建 drop-in 文件 并覆盖 Environment
和 PIDFile
设置。例如
/etc/systemd/system/postgresql.service.d/PGROOT.conf
[Service] Environment=PGROOT=/pathto/pgroot PIDFile=/pathto/pgroot/data/postmaster.pid
如果您想将 /home
目录用于默认目录或表空间,请在此文件中添加另一行
ProtectHome=false
将新数据库的默认编码更改为 UTF-8
-E UTF8
或在使用 UTF-8 区域设置的情况下运行了 initdb
,则无需执行这些步骤。在创建新数据库时(例如,使用 createdb blog
),PostgreSQL 实际上会复制模板数据库。有两个预定义的模板:template0
是原始模板,而 template1
用作管理员可更改的现场模板,并且默认使用。为了更改新数据库的编码,一种选择是更改现场 template1
。为此,请登录 PostgreSQL shell (psql
) 并执行以下操作
首先,我们需要删除 template1
。模板无法删除,因此我们首先修改它,使其成为一个普通数据库
UPDATE pg_database SET datistemplate = FALSE WHERE datname = 'template1';
现在我们可以删除它
DROP DATABASE template1;
下一步是从 template0
创建一个新数据库,并使用新的默认编码
CREATE DATABASE template1 WITH TEMPLATE = template0 ENCODING = 'UNICODE';
现在修改 template1
,使其实际上成为一个模板
UPDATE pg_database SET datistemplate = TRUE WHERE datname = 'template1';
可选地,如果您不希望任何人连接到此模板,请将 datallowconn
设置为 FALSE
UPDATE pg_database SET datallowconn = FALSE WHERE datname = 'template1';
pg_upgrade
升级时产生问题。现在您可以创建一个新数据库
[postgres]$ createdb blog
如果您重新登录到 psql
并检查数据库,您应该会看到新数据库的正确编码
\l
List of databases Name | Owner | Encoding | Collation | Ctype | Access privileges -----------+----------+-----------+-----------+-------+---------------------- blog | postgres | UTF8 | C | C | postgres | postgres | SQL_ASCII | C | C | template0 | postgres | SQL_ASCII | C | C | =c/postgres : postgres=CTc/postgres template1 | postgres | UTF8 | C | C |
启用数据校验和
如果您的数据库文件位于没有校验和的文件系统上,则其数据容易受到由于位衰减和硬件损坏引起的静默数据损坏。虽然这些事件很少发生,但如果您关心数据完整性,您可能希望启用 PostgreSQL 的内置数据校验和。此功能必须在集群级别启用,而不是每个数据库或每个表。
- 存在 最小的性能影响,尤其是在从磁盘读取大型数据集时。内存操作不受影响。
- PostgreSQL 无法修复损坏的数据 - 它只会中止从损坏页面读取的事务,以防止进一步损坏或无效的执行结果。
- 校验和仅覆盖磁盘上的数据(行)页,而不覆盖元数据或控制结构。内存中的页面未进行校验和。纠错存储和 ECC 内存仍然有益。
- 要在集群创建期间启用校验和,请将
--data-checksums
参数添加到initdb
。 - 要验证是否启用了校验和,请运行
[postgres]$ psql --tuples-only -c "SHOW data_checksums"
(应打印off
或on
)。 - 要在现有集群上切换校验和
- 停止
postgresql.service
。 - 运行
[postgres]$ pg_checksums --pgdata /var/lib/postgres/data --enable
(如果您不再需要校验和,则为--disable
)。启用校验和将重写所有数据库页面,对于大型数据库实例,这将需要一段时间。 - 启动
postgresql.service
。
图形工具
- phpPgAdmin — 用于 PostgreSQL 的基于 Web 的管理工具。
- pgAdmin-desktop — pgAdmin 的桌面用户界面,pgAdmin 是用于 PostgreSQL 的综合设计和管理 GUI。
- pgAdmin — 用于 PostgreSQL 的综合设计和管理 GUI。
- https://www.pgadmin.org/ || pgadmin4[链接已损坏: 软件包未找到]
- pgModeler — 用于 PostgreSQL 的图形化模式设计器。
- Postbird — 跨平台 PostgreSQL GUI 客户端,用 JavaScript 编写,使用 Electron 运行。
- rainfrog — Postgres 的数据库管理 TUI。
- pgweb — 用于 PostgreSQL 数据库的跨平台 Web 客户端。
对于支持多种 DBMS 的工具,请参阅 应用程序列表/文档#数据库工具。
设置备份
建议为包含有价值数据的数据库设置备份。请参阅 PostgreSQL 文档中的 备份和恢复 章节。PostgreSQL wiki 中还有一个 备份工具列表,尽管它可能不是最新的或完整的。请记住,除非您不时执行测试还原,否则备份系统是不可信任的!
升级 PostgreSQL
升级 PostgreSQL 主要版本(例如,从版本 14.x 到版本 15.y)需要一些额外的维护。
通过以下方式获取当前使用的数据库版本
# cat /var/lib/postgres/data/PG_VERSION
为确保您不会意外地将数据库升级到不兼容的版本,建议 跳过更新 PostgreSQL 软件包。
次要版本升级可以安全执行。但是,如果您意外升级到不同的主要版本,您可能无法访问您的任何数据。始终查看 PostgreSQL 主页,以确保了解每次升级所需的步骤。有关为什么会发生这种情况的更多信息,请参阅 版本控制策略。
有两种主要方法可以升级您的 PostgreSQL 数据库。阅读官方文档以了解详细信息。
pg_upgrade
pg_upgrade
实用程序尝试在集群之间复制尽可能多的兼容数据,并升级所有其他内容。通常,它是升级大多数实例的最快方法,尽管它需要访问源和目标 PostgreSQL 版本的二进制文件。阅读 pg_upgrade(1) 手册页,以了解它执行的操作。对于非平凡的实例(例如,具有流复制或日志传送),请先阅读上游文档。
对于希望使用 pg_upgrade
的用户,可以使用 postgresql-old-upgrade 软件包,该软件包始终比实际 PostgreSQL 软件包落后一个主要版本。这可以与新版本的 PostgreSQL 并排安装。要从旧版本的 PostgreSQL 升级,可以使用 AUR 软件包,例如 postgresql-12-upgradeAUR。(您必须使用与您要升级到的 PostgreSQL 版本一起打包的 pg_upgrade
版本。)
请注意,数据库集群目录不会随版本而更改,因此在运行 pg_upgrade
之前,必须重命名现有数据目录并迁移到新目录。必须使用与旧集群相同的参数初始化新数据库集群。
当您准备好开始升级时
- 在旧数据库集群仍然在线时,收集用于创建它的
initdb
参数。有关更多信息,请参阅 #初始配置。 - 停止
postgresql.service
。检查 单元状态 以确保 PostgresSQL 已正确停止。如果失败,pg_upgrade
将失败并显示The source cluster was not shut down cleanly
。 - 升级 postgresql、postgresql-libs 和 postgresql-old-upgrade。
- 确保
/var/lib/postgres/olddata
不存在。如果您在上一次升级后没有删除它,请立即删除。 - 重命名旧集群目录,然后创建新集群和临时工作目录
# mv /var/lib/postgres/data /var/lib/postgres/olddata # mkdir /var/lib/postgres/data /var/lib/postgres/tmp # chown postgres:postgres /var/lib/postgres/data /var/lib/postgres/tmp [postgres]$ cd /var/lib/postgres/tmp
- 使用与旧集群相同的
initdb
参数初始化新集群[postgres]$ initdb -D /var/lib/postgres/data --locale=C.UTF-8 --encoding=UTF8 --data-checksums
- 升级集群,将下面的
PG_VERSION
替换为旧 PostgreSQL 版本号(例如15
)[postgres]$ pg_upgrade -b /opt/pgsql-PG_VERSION/bin -B /usr/bin -d /var/lib/postgres/olddata -D /var/lib/postgres/data
如有必要,调整新集群的配置文件(例如pg_hba.conf
和postgresql.conf
)以匹配旧集群。 - 启动
postgresql.service
再次。 - 可选: 运行
[postgres]$ vacuumdb --all --analyze-in-stages
以重新计算查询分析器统计信息,这 应该在升级后不久提高查询性能。(添加--jobs=NUMBER_OF_CPU_CORES
参数可能会提高此命令的性能。) - 可选: 备份
/var/lib/postgres/olddata
目录,以防您需要恢复到以前的 PostgreSQL 版本。 - 删除包含旧集群数据的
/var/lib/postgres/olddata
目录。 - 删除
/var/lib/postgres/tmp
目录。 - 如果您使用 pgbackrestAUR,请运行 stanza-upgrade 命令。
手动转储和重载
您也可以执行类似以下操作(在升级和安装 postgresql-old-upgrade 之后)。
- 以下是从 PostgreSQL 14 升级的命令。您可以在
/opt/
中找到与您的 PostgreSQL 集群版本类似的命令,前提是您安装了匹配版本的 postgresql-old-upgrade 软件包。 - 如果您自定义了
pg_hba.conf
文件,您可能需要临时修改它以允许从本地系统完全访问旧数据库集群。升级完成后,将您的自定义设置也应用于新数据库集群,并 重启postgresql.service
。
停止 postgresql.service
# mv /var/lib/postgres/data /var/lib/postgres/olddata # mkdir /var/lib/postgres/data # chown postgres:postgres /var/lib/postgres/data [postgres]$ initdb -D /var/lib/postgres/data --locale=C.UTF-8 --encoding=UTF8 --data-checksums [postgres]$ /opt/pgsql-14/bin/pg_ctl -D /var/lib/postgres/olddata/ start # cp /usr/lib/postgresql/postgis-3.so /opt/pgsql-14/lib/ # Only if postgis installed [postgres]$ pg_dumpall -h /tmp -f /tmp/old_backup.sql [postgres]$ /opt/pgsql-14/bin/pg_ctl -D /var/lib/postgres/olddata/ stop
启动 postgresql.service
[postgres]$ psql -f /tmp/old_backup.sql postgres
故障排除
提高小事务的性能
如果您在本地机器上使用 PostgresSQL 进行开发,并且它看起来很慢,您可以尝试在配置中关闭 synchronous_commit。但是,请注意 注意事项。
/var/lib/postgres/data/postgresql.conf
synchronous_commit = off
使用扩展时,PostgreSQL 数据库在软件包更新后无法启动
这种情况的主要原因是现有软件包未针对较新版本编译(并且它可能是最新的),解决方案是重新构建软件包,可以手动重新构建,也可以等待扩展软件包的更新。
在升级到带有扩展的新版本时,无法使用旧版本的数据库启动 PostgreSQL 服务器
这是因为来自软件包 postgresql-old-upgrade 的旧版本 postgres 在其 lib 目录中没有所需的扩展(.so 文件),当前的解决方案很脏,并且可能会导致很多问题,因此请备份数据库以防万一,基本上是将所需的扩展 .so 文件从 /usr/lib/postgresql/
复制到 /opt/pgsql-XX/lib/
(记住将 XX 替换为 postgresql-old-upgrade 的主要版本)。
例如,对于 timescaledb
# cp /usr/lib/postgresql/timescaledb*.so /opt/pgsql-13/lib/
/opt/pgsql-XX/
下的正确目录。要了解要复制的确切文件,请使用以下命令检查扩展软件包的内容
$ pacman -Ql package_name
警告:数据库 "postgres" 存在排序规则版本不匹配
您可能会看到类似这样的内容
WARNING: database "postgres" has a collation version mismatch DETAIL: The database was created using collation version X.YY, but the operating system provides version X.ZZ. HINT: Rebuild all objects in this database that use the default collation and run ALTER DATABASE postgres REFRESH COLLATION VERSION, or build PostgreSQL with the right library version.
这意味着排序规则提供程序库(glibc 或 icu)已更新,这可能导致某些索引无效。因此,这意味着需要重新索引这些数据库。
您可以使用以下命令执行此操作
[postgres]$ psql -c 'REINDEX DATABASE' postgres [postgres]$ psql -c 'ALTER DATABASE postgres REFRESH COLLATION VERSION'
通过将 postgres 替换为相应的数据库名称,对所有其他数据库重复上述操作。
C.UTF-8
、C
、POSIX
或 ucs_basic
区域设置来避免此问题。