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
參數即可。相關細節可參考 #Enable data checksumming。(一旦資料庫啟動,你可以使用[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#Databases。
最後,啟動並啟用 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
=> \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" 僅用於 Unix 域套接字連接 local all all trust
改為:
/var/lib/postgres/data/pg_hba.conf
# TYPE DATABASE USER ADDRESS METHOD # "local" 僅用於 Unix 域套接字連接 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" 僅用於 Unix 域套接字連接 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'
您可以使用 '*'
來監聽所有可用地址。
然後在認證配置中添加如下行:
/var/lib/postgres/data/pg_hba.conf
# TYPE DATABASE USER ADDRESS METHOD # IPv4 本地連接: 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 本地連接: 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
來附加配置片段,以覆蓋 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
initdb
時使用了 -E UTF8
或在使用 UTF-8 區域設置時,這些步驟不是必需的。在創建新資料庫時(例如使用 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 — 基於 Web 的 PostgreSQL 管理工具。
- pgAdmin-desktop — pgAdmin 的桌面用戶界面,一個全面的 PostgreSQL 設計和管理的圖形用戶界面。
- pgAdmin — 全面的 PostgreSQL 設計和管理圖形用戶界面。
- https://www.pgadmin.org/ || pgadmin4包[損壞的連結:package not found]
- pgModeler — PostgreSQL 的圖形化模式設計工具。
- Postbird — 跨平台的 PostgreSQL 圖形用戶界面客戶端,使用 JavaScript 編寫,基於 Electron 運行。
- rainfrog — Postgres 的資料庫管理 TUI
支持多種資料庫管理系統的工具,請參見 List of applications/Documents#Database tools。
設置備份
建議為包含重要數據的資料庫設置備份。請參閱 PostgreSQL 文檔中的 備份與恢復 章節。PostgreSQL 維基中還有一個 備份工具列表,儘管它可能不是最新的或完整的。請記住,除非您定期執行測試恢復,否則不能信任備份系統!
升級 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
。檢查 單元狀態 以 確保 PostgreSQL 已正確停止。如果停止失敗,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
文件,你可能需要臨時修改它以允許從本地系統完全訪問舊資料庫集群。升級完成後,將你的自定義設置應用到新資料庫集群並 restartpostgresql.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/ # 仅当安装了 postgis 时 [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。但請注意 注意事項。
PostgreSQL database unable to start after package update when using extensions
The cause in this case is mostly the existing package is not compiled for the newer version (and it may be up-to-date), the solution is rebuilding the package either manually or waiting for an update to the extension package.
Failing to start a PostgreSQL server with the older version of the database while upgrading to the newer version with extensions
This is caused because the old version of postgres from the package postgresql-old-upgrade包 does not have the required extensions (.so files) in its lib directory, the current solution is dirty, and might cause a lot of problems so keep a backup of the database just in case, basically copy the required extension .so files from /usr/lib/postgresql/
to /opt/pgsql-XX/lib/
(remember to replace XX with the major version of postgresql-old-upgrade包).
For example, for timescaledb
# cp /usr/lib/postgresql/timescaledb*.so /opt/pgsql-13/lib/
/opt/pgsql-XX/
.to know the exact files to copy, check the contant of the package of the extension using :
$ 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.
That means collation provider library (glibc包 or icu包) was updated which might have made some indexes invalid. So that means need to reindex those databases.
You can do that with:
[postgres]$ psql -c 'REINDEX DATABASE' postgres [postgres]$ psql -c 'ALTER DATABASE postgres REFRESH COLLATION VERSION'
Repeat this above for all other databases by replacing postgres with respective DB name.
C.UTF-8
, C
, POSIX
or ucs_basic
locale for the database cluster.