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參數即可。相關細節可參考 #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。以 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'; 重新添加每個用戶的密碼。
在最初創建集群時,將 -c listen_addresses='' 附加到 initdb 命令中。
對於現有集群,編輯 postgresql.conf 並在連接和認證部分設置:
/var/lib/postgres/data/postgresql.conf
listen_addresses = ''
這將完全禁用網絡監聽。
之後,您應該重啟 postgresql.service 以使更改生效。
在連接和認證部分,根據需要設置 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。
例如,與上述相同的配置,但啟用了 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
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。
- pgweb — 跨平台的 PostgreSQL 資料庫 Web 客戶端。
支持多種資料庫管理系統的工具,請參見 List of applications/Documents#Database tools。
建議為包含重要數據的資料庫設置備份。請參閱 PostgreSQL 文檔中的 備份與恢復 章節。PostgreSQL 維基中還有一個 備份工具列表,儘管它可能不是最新的或完整的。請記住,除非您定期執行測試恢復,否則不能信任備份系統!
升級 PostgreSQL 大版本(例如從 14.x 升級到 15.y)需要一些額外的維護工作。
通過以下命令獲取當前使用的資料庫版本:
# cat /var/lib/postgres/data/PG_VERSION
為了避免意外升級到不兼容的資料庫版本,建議 跳過更新 PostgreSQL 包。
小版本升級是安全的。然而,如果你意外升級到一個不同的大版本,你可能無法訪問任何數據。請務必查看 PostgreSQL 主頁 以確認每個升級所需的步驟。有關為什麼會出現這種情況的更多信息,請參閱 版本策略。
有兩種主要的方法可以升級你的 PostgreSQL 資料庫。請閱讀官方文檔以獲取詳細信息。
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目錄。 - 如果你使用 pgbackrest包,請運行 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-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
你可能會看到類似這樣的信息:
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 區域設置創建資料庫集群可以避免此問題。