原創文章,轉載須註明出處。訪問我的Github(地址:https://guobo507.github.io)查看最新文章列表。
PGDG 中提供了針對多個系統版本都提供了多個版本的 PostgreSQL 的 RPM 安裝包,在生產中使用PGDG安裝PostgreSQL數據庫軟件包是非常方便的途徑。
在如今國產化、自主可控的浪潮之下,很多時候我們想要在國產的平臺、(所謂)國產的操作系統中使用PostgreSQL數據庫,大多數時候系統中自帶的PostgreSQL版本很可能不符合我們的要求。因此,本文的目的是演示如何在指定平臺上編譯安裝想要的 PostgreSQL 版本?如何使用 PG 源代碼在指定的硬件平臺上創建該平臺專用的 PostgreSQL 的 RPM 安裝包?
編譯和安裝PostgreSQL
本文討論的是針對RedHat系列Linux(我是用的是 CentOS 7)上的實踐,使用的平臺也是 x86_64 平臺。雖然在該平臺可以直接從 PGDG 進行安裝,但本文的目的在於演示整個操作的過程。我將以安裝PG 12.1版本爲例說明。
首先,我的系統環境如下:
[root@pgbuild ~]# cat /etc/centos-release
CentOS Linux release 7.6.1810 (Core)
[root@pgbuild ~]# uname -a
Linux pgbuild 3.10.0-957.5.1.el7.x86_64 #1 SMP Fri Feb 1 14:54:57 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
根據需要,我設置我的語言環境爲我比較習慣的英文環境:
export LANG=en_US.UTF-8
從操作系統光盤或者在線的系統倉庫安裝如下的必須的編譯所需軟件包:
yum install -y make # VERSION >= 3.80
yum install -y gcc # Recent versions of GCC are recommended.
yum install -y tar gzip bzip2 # The GNU Readline library is used by default.
yum install -y readline readline-static
yum install -y zlib zlib-static # The zlib compression library is used by default.
下面的安裝包是可選的,在默認配置的情況下不需要下面這些安裝包。請根據下面的描述和實際需要進行安裝:
yum install -y perl perl-libs perl-ExtUtils-Embed perl-ExtUtils-MakeMaker # VERSION >= 5.8.3
perl -V |grep usemultiplicity
yum install -y python python-libs python-devel # VERSION >= 2.4, Or Python3 3.1 or later.
yum install -y tcl tcl-devel # VERSION >= 8.4
yum install -y nls
yum install -y openssl openssl-static # VERSION >= 0.9.8
yum install -y docbook-dtds docbook-style-xsl fop libxslt
yum install -y pam pam-devel
# You need Kerberos, OpenLDAP, and/or PAM, if you want to support authentication using those services.
yum install -y krb5-devel krb5-libs krb5-server pam_krb5
爲了讓 PostgreSQL 支持 LLVMJIT 即時編譯,我們還需要安裝 llvm-config(3.9及以上版本) 和clang(與llvm-config相匹配版本):
cat << EOF > /etc/yum.repos.d/c7-devtoolset-7-x86_64.repo
[c7-devtoolset-7]
name=c7-devtoolset-7
baseurl=https://buildlogs.centos.org/c7-devtoolset-7.x86_64/
gpgcheck=0
enabled=1
[c7-llvm-toolset-7]
name=c7-llvm-toolset-7
baseurl=https://buildlogs.centos.org/c7-llvm-toolset-7.x86_64/
gpgcheck=0
enabled=1
[fedoraproject-epel-7]
name=fedoraproject-epel-7
baseurl=https://download-ib01.fedoraproject.org/pub/epel/7/x86_64/
gpgcheck=0
enabled=1
EOF
yum install -y llvm5.0-devel llvm-toolset-7-clang
我的實例中安裝的clang和llvm都是5.0版本,如下所示:
[root@pgbuild ~]# rpm -qa |grep llvm |sort
llvm5.0-5.0.1-7.el7.x86_64
llvm5.0-devel-5.0.1-7.el7.x86_64
llvm5.0-libs-5.0.1-7.el7.x86_64
llvm-toolset-7-clang-5.0.1-4.el7.x86_64
llvm-toolset-7-clang-libs-5.0.1-4.el7.x86_64
llvm-toolset-7-compiler-rt-5.0.1-2.el7.x86_64
llvm-toolset-7-libomp-5.0.1-2.el7.x86_64
llvm-toolset-7-llvm-libs-5.0.1-8.el7.x86_64
llvm-toolset-7-runtime-5.0.1-4.el7.x86_64
這些軟件包裝完後,主要涉及如下的三個目錄:
/usr/lib64/llvm5.0/
: 提供llvm-config
工具;/opt/rh/devtoolset-7/root/
: 在編譯階段,爲編譯工具提供g++
命令(系統提供的g++命令版本過低,不符合要求);/opt/rh/llvm-toolset-7/root/
: 在編譯階段,爲編譯工具提供clang
命令;
接下來就是編譯安裝 PostgreSQL 軟件了。你至少需要有 100MB 的空間用於源代碼編譯,以及 20MB 空間用於安裝文件。一個空的數據庫集羣大約需要 35MB 的存儲空間,但通常需要 5 倍該數量的空間以確保數據庫正常運行。
下面的這些包也是編譯必須的:
yum install -y libxslt libxslt-devel
yum install -y libxml2 libxml2-devel
yum install -y systemd-devel
yum install -y rpm-build
創建一個操作系統用戶用於運行和管理 PostgreSQL 數據庫:
groupadd -g 5432 yhpg
useradd -u 5432 -g yhpg -s /usr/bin/bash -m yhpg
echo 123456 |passwd --stdin yhpg
你可能需要提前到官方網站下載好源代碼包,例如:https://download.postgresql.org/pub/source/,本例中我們已經提前下載好了。
執行下面的編譯過程:
su - yhpg
BASEDIR=/home/yhpg
VERSION=postgresql-11.5
PREFIX=/usr/pgsql-11
cd $BASEDIR
wget http://192.168.18.3/tools/postgresql/pg_source/$VERSION.tar.bz2
tar -xjf $VERSION.tar.bz2
mkdir -p ./$VERSION/build_dir
cd ./$VERSION/build_dir
export PATH=/opt/rh/llvm-toolset-7/root/usr/bin:/opt/rh/devtoolset-7/root/usr/bin:$PATH
$BASEDIR/$VERSION/configure \
--prefix=$PREFIX \
--bindir=$PREFIX/bin \
--sysconfdir=$PREFIX/etc \
--includedir=$PREFIX/include \
--datarootdir=$PREFIX/share \
--enable-nls='en zh' \
--with-pgport=5432 \
--with-systemd \
--with-openssl \
--with-perl \
--with-python \
--with-tcl \
--with-libxml \
--with-libxslt \
--with-llvm \
--with-pam \
--with-systemd \
--with-llvm LLVM_CONFIG='/usr/lib64/llvm5.0/bin/llvm-config'
make -j 8 all
make
命令執行完後,你可以看到如下的輸出:
......
make[2]: Leaving directory `/home/yhpg/postgresql-11.5/build_dir/src/backend/jit/llvm'
make[1]: Leaving directory `/home/yhpg/postgresql-11.5/build_dir/src'
All of PostgreSQL successfully made. Ready to install.
接下來,你可以直接將編譯好的 PostgreSQL 安裝到服務器上,可以參考如下的命令來將PostgreSQL安裝到服務器上。由於我們使用普通用戶yhpg進行編譯,但是安裝目錄爲/usr/pgsql-11
,默認該用戶沒有權限,因此我們先用root用戶創建該目錄,並設置正確的權限:
su - root
mkdir /usr/pgsql-11
chown -R yhpg:yhpg /usr/pgsql-11
chmod 755 /usr/pgsql-11
然後,在使用yhpg用戶執行安裝:
su - yhpg
cd /home/yhpg/postgresql-11.5/build_dir
make install-world
安裝完成後,你會看到類似如下的輸出:
......
make[2]: Leaving directory `/home/yhpg/postgresql-11.5/build_dir/contrib/ltree_plpython'
make[1]: Leaving directory `/home/yhpg/postgresql-11.5/build_dir/contrib'
PostgreSQL, contrib, and documentation installation complete.
檢查一下安裝目錄:
[yhpg@pgbuild build_dir]$ cd /usr/pgsql-11
[yhpg@pgbuild pgsql-11]$ ls -l
total 20
drwxrwxr-x 2 yhpg yhpg 4096 Jan 16 09:16 bin
drwxrwxr-x 6 yhpg yhpg 4096 Jan 16 09:16 include
drwxrwxr-x 5 yhpg yhpg 4096 Jan 16 09:16 lib
drwxrwxr-x 8 yhpg yhpg 4096 Jan 16 09:16 share
[yhpg@pgbuild pgsql-11]$ du -hs ./*
12M ./bin
5.8M ./include
28M ./lib
22M ./share
[yhpg@pgbuild pgsql-11]$ ls -l ./bin
total 11892
-rwxr-xr-x 1 yhpg yhpg 63880 Jan 16 09:16 clusterdb
-rwxr-xr-x 1 yhpg yhpg 63664 Jan 16 09:16 createdb
-rwxr-xr-x 1 yhpg yhpg 68472 Jan 16 09:16 createuser
-rwxr-xr-x 1 yhpg yhpg 59040 Jan 16 09:16 dropdb
-rwxr-xr-x 1 yhpg yhpg 59008 Jan 16 09:16 dropuser
-rwxr-xr-x 1 yhpg yhpg 933744 Jan 16 09:16 ecpg
-rwxr-xr-x 1 yhpg yhpg 136728 Jan 16 09:16 initdb
-rwxr-xr-x 1 yhpg yhpg 33808 Jan 16 09:16 oid2name
-rwxr-xr-x 1 yhpg yhpg 30424 Jan 16 09:16 pg_archivecleanup
-rwxr-xr-x 1 yhpg yhpg 120616 Jan 16 09:16 pg_basebackup
-rwxr-xr-x 1 yhpg yhpg 154464 Jan 16 09:16 pgbench
-rwxr-xr-x 1 yhpg yhpg 33936 Jan 16 09:16 pg_config
-rwxr-xr-x 1 yhpg yhpg 46984 Jan 16 09:16 pg_controldata
-rwxr-xr-x 1 yhpg yhpg 58160 Jan 16 09:16 pg_ctl
-rwxr-xr-x 1 yhpg yhpg 413112 Jan 16 09:16 pg_dump
-rwxr-xr-x 1 yhpg yhpg 94896 Jan 16 09:16 pg_dumpall
-rwxr-xr-x 1 yhpg yhpg 63152 Jan 16 09:16 pg_isready
-rwxr-xr-x 1 yhpg yhpg 79248 Jan 16 09:16 pg_receivewal
-rwxr-xr-x 1 yhpg yhpg 84128 Jan 16 09:16 pg_recvlogical
-rwxr-xr-x 1 yhpg yhpg 57272 Jan 16 09:16 pg_resetwal
-rwxr-xr-x 1 yhpg yhpg 173968 Jan 16 09:16 pg_restore
-rwxr-xr-x 1 yhpg yhpg 91440 Jan 16 09:16 pg_rewind
-rwxr-xr-x 1 yhpg yhpg 30360 Jan 16 09:16 pg_standby
-rwxr-xr-x 1 yhpg yhpg 35344 Jan 16 09:16 pg_test_fsync
-rwxr-xr-x 1 yhpg yhpg 30136 Jan 16 09:16 pg_test_timing
-rwxr-xr-x 1 yhpg yhpg 134608 Jan 16 09:16 pg_upgrade
-rwxr-xr-x 1 yhpg yhpg 43584 Jan 16 09:16 pg_verify_checksums
-rwxr-xr-x 1 yhpg yhpg 90200 Jan 16 09:16 pg_waldump
-rwxr-xr-x 1 yhpg yhpg 8013104 Jan 16 09:16 postgres
lrwxrwxrwx 1 yhpg yhpg 8 Jan 16 09:16 postmaster -> postgres
-rwxr-xr-x 1 yhpg yhpg 640400 Jan 16 09:16 psql
-rwxr-xr-x 1 yhpg yhpg 68072 Jan 16 09:16 reindexdb
-rwxr-xr-x 1 yhpg yhpg 72760 Jan 16 09:16 vacuumdb
-rwxr-xr-x 1 yhpg yhpg 29688 Jan 16 09:16 vacuumlo
[yhpg@pgbuild pgsql-11]$ ls -l ./share/extension/
total 1304
-rw-r--r-- 1 yhpg yhpg 274 Jan 16 09:16 adminpack--1.0--1.1.sql
-rw-r--r-- 1 yhpg yhpg 1535 Jan 16 09:16 adminpack--1.0.sql
-rw-r--r-- 1 yhpg yhpg 1682 Jan 16 09:16 adminpack--1.1--2.0.sql
-rw-r--r-- 1 yhpg yhpg 176 Jan 16 09:16 adminpack.control
-rw-r--r-- 1 yhpg yhpg 931 Jan 16 09:16 amcheck--1.0--1.1.sql
-rw-r--r-- 1 yhpg yhpg 704 Jan 16 09:16 amcheck--1.0.sql
-rw-r--r-- 1 yhpg yhpg 154 Jan 16 09:16 amcheck.control
-rw-r--r-- 1 yhpg yhpg 249 Jan 16 09:16 autoinc--1.0.sql
-rw-r--r-- 1 yhpg yhpg 149 Jan 16 09:16 autoinc.control
-rw-r--r-- 1 yhpg yhpg 250 Jan 16 09:16 autoinc--unpackaged--1.0.sql
-rw-r--r-- 1 yhpg yhpg 666 Jan 16 09:16 bloom--1.0.sql
-rw-r--r-- 1 yhpg yhpg 156 Jan 16 09:16 bloom.control
-rw-r--r-- 1 yhpg yhpg 1372 Jan 16 09:16 btree_gin--1.0--1.1.sql
-rw-r--r-- 1 yhpg yhpg 24818 Jan 16 09:16 btree_gin--1.0.sql
-rw-r--r-- 1 yhpg yhpg 1445 Jan 16 09:16 btree_gin--1.1--1.2.sql
-rw-r--r-- 1 yhpg yhpg 4571 Jan 16 09:16 btree_gin--1.2--1.3.sql
......
使用yhpg用戶,執行下面的命令創建一個數據庫集羣實例來測試一下安裝的結果:
su - yhpg
export PGHOME=/usr/pgsql-11
export PGDATA=/home/yhpg/data
export PATH=$PGHOME/bin:$PATH
mkdir -p $PGDATA
chmod 700 $PGDATA
echo 1qaz2wsx > /tmp/.super_password
initdb --username=yhpg --pgdata=$PGDATA --auth=trust --encoding=UTF-8 --locale=C --pwfile=/tmp/.super_password
rm -f /tmp/.super_password
pg_ctl -D $PGDATA -l $PGDATA/postgresql.log start
查看後臺進程:
[yhpg@pgbuild ~]$ ps -ef |grep postgres
yhpg 4222 1 0 09:21 pts/1 00:00:00 /usr/pgsql-11/bin/postgres -D /home/yhpg/data
yhpg 4224 4222 0 09:21 ? 00:00:00 postgres: checkpointer
yhpg 4225 4222 0 09:21 ? 00:00:00 postgres: background writer
yhpg 4226 4222 0 09:21 ? 00:00:00 postgres: walwriter
yhpg 4227 4222 0 09:21 ? 00:00:00 postgres: autovacuum launcher
yhpg 4228 4222 0 09:21 ? 00:00:00 postgres: stats collector
yhpg 4229 4222 0 09:21 ? 00:00:00 postgres: logical replication launcher
yhpg 4234 4043 0 09:21 pts/1 00:00:00 grep --color=auto postgres
創建一個測試數據庫,並嘗試安裝插件:
[yhpg@pgbuild ~]$ createdb test
[yhpg@pgbuild ~]$ psql test -c 'create extension pg_stat_statements;'
CREATE EXTENSION
[yhpg@pgbuild ~]$ psql test -c '\list'
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+-------+----------+---------+-------+-------------------
postgres | yhpg | UTF8 | C | C |
template0 | yhpg | UTF8 | C | C | =c/yhpg +
| | | | | yhpg=CTc/yhpg
template1 | yhpg | UTF8 | C | C | =c/yhpg +
| | | | | yhpg=CTc/yhpg
test | yhpg | UTF8 | C | C |
(4 rows)
[yhpg@pgbuild ~]$ psql test -c '\dx'
List of installed extensions
Name | Version | Schema | Description
--------------------+---------+------------+-----------------------------------------------------------
pg_stat_statements | 1.6 | public | track execution statistics of all SQL statements executed
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
(2 rows)
停止該數據庫實例可以使用下面的命令:
pg_ctl -D $PGDATA -l $PGDATA/postgresql.log -m fast stop
到這裏,你已經成功在CentOS 7上編譯和安裝了 PostgreSQL 軟件,並運行了一個數據庫實例。
創建PostgreSQL RPM安裝包
從這裏開始,我會展示如何創建 PostgreSQL 的 RPM 軟件包。
這裏我們要用到一個項目dennis-apter/pgrpms
,可以從Github上找到該項目。實際過程中你需要現將該項目克隆到服務器上,具體的步驟及命令這省略了。我的環境中,我已經提前下載好了該項目的源碼包;因此,我們就直接開始吧:
su - yhpg
cd /home/yhpg
wget http://192.168.18.3/tools/postgresql/pg_source/pgrpms.tar.gz
tar -xzf pgrpms.tar.gz
mkdir -p -v ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
cp ~/pgrpms/rpm/redhat/11/postgresql/EL-7/* ~/rpmbuild/SOURCES/
cd ~/rpmbuild/SOURCES/
sed -i "2 a%global pgmajorversion 11" postgresql-11.spec
wget http://192.168.18.3/tools/postgresql/pg_source/postgresql-11.5.tar.bz2
wget http://192.168.18.3/tools/postgresql/pg_source/postgresql-11-A4.pdf
rpmbuild -bb postgresql-11.spec
執行完成後你可以在~/rpmbuild/RPMS/
目錄中找到生成的RPM包:
cd ~/rpmbuild/RPMS/x86_64/
ls -l
參照上面的步驟,你就可以在服務器上生成任意版本的PostgreSQL的RPM安裝包了。
如果你有其他需求,可以根據需要拷貝合適的文件至~/rpmbuild/SOURCES/
下,並進行深度定製。這裏我已經根據我們的實際需要,定製好了一個在Linux 7上生成PostgreSQL 12的軟件包的項目,地址是:https://github.com/guobo507/yhpg-12-rpmbuild/,你可以參考該項目進行RPM打包。