尝试操作OrioleDB
这篇文章是2023年12月4日 PostgreSQL灯节的文章。
OrioleDB是什么?
OrioleDB是由PostgreSQL开发者Alexander Korotkov开发的新型数据库软件。它基于PostgreSQL,旨在解决与PostgreSQL的基本架构相关的各种限制和问题,其中包括”Row-level WAL”、”Lock-less buffer access”和”Undo log”等大型实施替换。
与此同时,OrioleDB仅以扩展模块的形式提供PostgreSQL的表访问方法等。目前,虽然存在对PostgreSQL本体的修补程序,但这些修补程序的目的是为了将所需功能作为扩展模块引入,而功能的提供则由扩展模块来描述。
我最近参与了由日本PostgreSQL用户协会主办的PostgreSQL Conference 2023作为管理者,邀请Alexander Korotkov先生就OrioleDB进行了演讲。本文作为对介绍可能在日本尚不为人所知的OrioleDB的补充,将介绍实际操作步骤等内容。
有关OrioleDB的架构,请参考发布物中的文档、会议演讲资料以及先前的演讲资料。
安裝步驟
如果已经以源代码方式安装过PostgreSQL或者构建并安装过扩展模块,那么安装OrioleDB并不是太难。所需的构建环境与PostgreSQL大致相同。以下是在崭新的Rocky Linux 9.1上执行的命令。
# dnf install -y git gcc bison flex python perl
# dnf install -y zlib-devel readline-devel libicu-devel openssl-devel libzstd-devel lz4-devel
# dnf install -y pip # 後で testgres を導入するため
为了创建比较用的postgres用户,我们需要先安装常规的PostgreSQL 16包。
# dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
# dnf -qy module disable postgresql
# dnf install -y postgresql16-server
首先,我们将安装应用了 OrioleDB 补丁的 PostgreSQL。它以 git 存储库的形式提供,但由于包含整个 PostgreSQL 并且大小较大,因此只需获取最新的快照即可。”orioledb” 的 README.md 文件中为每个 PostgreSQL 主要版本系列都提供了相应的链接。下面我们将介绍如何安装适用于 PostgreSQL 16.x 的 18 版本的补丁。
# mkdir /usr/local/pgsql
# chown postgres:postgres /usr/local/pgsql
# su - postgres
$ wget https://github.com/orioledb/postgres/archive/refs/tags/patches16_18.zip
$ unzip patches16_18.zip
$ cd postgres-patches16_18/
$ ./configure --prefix=/usr/local/pgsql/16orioledb --enable-debug --with-openssl --with-zstd --with-lz4
$ make world-bin
$ make install-world-bin
$ cd -
安装带有补丁的PostgreSQL后,请设置一下环境变量路径。另外,也要设置好PGDATA环境变量。
$ cat > 16orioledb.env <<EOF
export PATH=/usr/local/pgsql/16orioledb/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/pgsql/16orioledb/lib:$LD_LIBRARY_PATH
export PGDATA=/var/lib/pgsql/16/odata
EOF
$ . 16orioledb.env
$ echo ". 16orioledb.env" >> .bash_profile
接下来,我们将引入 orioledb 扩展。使用最新的仓库版本(截至 2023年12月2日文章撰写时)。
安装过程遵循一般的扩展安装步骤。需要注意的是要明确指定 Makefile 变量 ORIOLEDB_PATCHSET_VERSION。虽然在 README.md 的 Installation 部分没有提及,但如果不指定,可能会导致自动判断出现问题。
$ git clone https://github.com/orioledb/orioledb.git
$ cd orioledb
$ make USE_PGXS=1 ORIOLEDB_PATCHSET_VERSION=18
$ make USE_PGXS=1 ORIOLEDB_PATCHSET_VERSION=18 install
如果安装了orioledb扩展,那么执行initdb并进行配置。
$ initdb --no-locale -E UTF8
$ vi $PGDATA/postgresql.conf
(以下を設定)
shared_preload_libraries = 'orioledb'
logging_collector = on
$ pg_ctl start
如果安装了包含 OrioleDB 扩展的 PostgreSQL(即 OrioleDB),那么在启动时,建议执行回归测试。这是使用存储库最新版本时的重要步骤。由于 testgres 工具用于 OrioleDB 的回归测试,因此请先通过 pip 本地安装该工具。
$ pip install testgres
$ make USE_PGXS=1 ORIOLEDB_PATCHSET_VERSION=18 installcheck
这个测试的规模相当大,要等几分钟才能结束。在本环境中,我们成功地通过了所有的检查,测试顺利完成。
试着动一下
首先,创建一个名为db1的数据库,将orioledb作为默认的表访问方法。
$ psql
postgres=# CREATE DATABASE db1;
postgres=# ALTER DATABASE db1 SET default_table_access_method TO orioledb;
postgres=# \q
对于 orioledb,有各种不同的 postgresql.conf 配置参数可供选择,但首先让我们尝试在不进行任何调整的情况下运行 pgbench。执行的机器是 Azure 的 Standard D2s v3(2 个虚拟 CPU、8 GiB 内存)。这样做是为了尝试读写数据并与普通的 PostgreSQL 进行简单比较。
$ pgbench -i -s 10 db1
$ pgbench -c 16 -T 120 -s 10 db1
pgbench (16rc1)
pgbench: warning: scale option ignored, using count from pgbench_branches table (10)
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 10
query mode: simple
number of clients: 16
number of threads: 1
maximum number of tries: 1
duration: 120 s
number of transactions actually processed: 159175
number of failed transactions: 0 (0.000%)
latency average = 12.062 ms
initial connection time = 45.113 ms
tps = 1326.491695 (without initial connection time)
运行3次,tps分别为1326.491695、1264.996140、1387.240085。
在普通的PostgreSQL 16中在同一服务器上运行时,tps为1305.715921、1278.107693、1282.910015。
仅通过这样的比较来说,稍微比普通的PostgreSQL快一点,并没有太大意义。重要的是,不需要考虑任何事情,不需要进行任何调整,它可以以相同的方式运行并具有相同的性能水平。
即使扩展的与PostgreSQL兼容的数据库软件可以比普通的PostgreSQL具有更好的性能,但如果为此需要复杂的设置,那就变得不太方便。认为使用起来与普通的PostgreSQL相同,不会发生什么不好的事情,这是一个重要的优点。
我尝试进行复制
接下来我们将建立流式复制。
同样地,让我们像执行普通 PostgreSQL 一样执行命令而不加考虑。
事先在1号机的postgresql.conf中设置listen_addresses = ‘*’,在pg_hba.conf中设置允许2号机的复制连接使用trust身份验证方式。
[postgres@orioledb1 ~]$ vi $PGDATA/postgresql.conf
(以下を設定)
listen_addresses = '*'
[postgres@orioledb1 ~]$ vi $PGDATA/pg_hba.conf
(以下を設定)
host replication all 10.0.0.5/32 trust
[postgres@orioledb2 ~]$ pg_basebackup -D $PGDATA -h 10.0.0.4 -R
[postgres@orioledb2 ~]$ pg_ctl start
waiting for server to start....2023-12-03 13:58:38.378 UTC [6301] LOG: registered custom resource manager "OrioleDB resource manager" with ID 129
2023-12-03 13:58:38.449 UTC [6301] LOG: OrioleDB public beta 3 started
2023-12-03 13:58:38.497 UTC [6301] LOG: redirecting log output to logging collector process
2023-12-03 13:58:38.497 UTC [6301] HINT: Future log output will appear in directory "log".
done
server started
使用-R选项自动生成热备份设置,指定1号机器(10.0.0.4)的-h选项,并执行pg_basebackup命令。
完毕后使用pg_ctl start启动。步骤与普通的PostgreSQL相同。
然而,通过使用ps命令来检查进程,我们可以发现orioledb独特的机制正在运作。有6个”orioledb recovery worker”进程正在并行执行。
[postgres@orioledb2 ~]$ ps x
PID TTY STAT TIME COMMAND
4770 pts/1 S 0:00 -bash
6301 ? Ss 0:00 /usr/local/pgsql/16orioledb/bin/postgres
6302 ? Ss 0:00 postgres: logger
6303 ? Ss 0:00 postgres: checkpointer
6304 ? Ss 0:00 postgres: background writer
6305 ? Ss 0:00 postgres: startup recovering 0000000100000000000000
6306 ? Ss 0:00 postgres: orioledb background writer
6307 ? Ss 0:00 postgres: orioledb recovery worker 3
6308 ? Ss 0:00 postgres: orioledb recovery worker 2
6309 ? Ss 0:00 postgres: orioledb recovery worker 1
6310 ? Ss 0:00 postgres: orioledb recovery worker 0
6311 ? Ss 0:00 postgres: orioledb recovery worker 5
6312 ? Ss 0:00 postgres: orioledb recovery worker 4
6313 ? Ss 0:00 postgres: walreceiver streaming 0/16000060
6314 pts/1 R+ 0:00 ps x
能够在使用 orioledb 作为默认表访问方法的 db1 中进行复制操作。
[postgres@orioledb1 ~]$ psql db1
db1=# UPDATE pgbench_accounts SET filler = 'test' WHERE aid = 12345;
UPDATE 1
[postgres@orioledb2 ~]$ psql db1
db1=# SELECT * FROM pgbench_accounts WHERE aid = 12345;
aid | bid | abalance | filler
-------+-----+----------+-------------------------------------------------------
-------------------------------
12345 | 1 | 0 | test
(1 row)
使用orioledb扩展可以实现对未使用的数据库进行复制。
[postgres@orioledb1 ~]$ createdb db2
[postgres@orioledb1 ~]$ psql db2
db2=# CREATE TABLE t2 (id int primary key, v text);
CREATE TABLE
db2=# INSERT INTO t2 VALUES (1, 'foo');
INSERT 0 1
[postgres@orioledb2 ~]$ psql db2
db2=# SELECT * FROM t2;
id | v
----+-----
1 | foo
(1 row)
一般的的PostgreSQL复制和扩展功能无缝运行。
我看看目录中有什么
由于 OrioleDB 是一种完全不同于 PostgreSQL 标准的存储引擎,所以数据库集群目录的内容应该也会有所不同。它会是什么样呢?
当使用 psql 来引用将 orioledb 设置为默认表访问方法的 db1 数据库时,将自动创建四个系统视图。这些视图将显示与表压缩状态和表索引相关的 orioledb 特定信息。
[postgres@orioledb1 ~]$ psql db1
psql (16rc1)
Type "help" for help.
db1=# \d
List of relations
Schema | Name | Type | Owner
--------+----------------------+-------+----------
public | orioledb_index | view | postgres
public | orioledb_index_descr | view | postgres
public | orioledb_table | view | postgres
public | orioledb_table_descr | view | postgres
public | pgbench_accounts | table | postgres
public | pgbench_branches | table | postgres
public | pgbench_history | table | postgres
public | pgbench_tellers | table | postgres
(8 rows)
此外,当使用oriole表访问方法来查看表的执行计划时,我们发现执行计划是基于自定义扫描的。
b1=# EXPLAIN SELECT * FROM pgbench_accounts WHERE aid = 1234;
QUERY PLAN
-----------------------------------------------------------------------------
Custom Scan (o_scan) on pgbench_accounts (cost=0.17..8.19 rows=1 width=97)
Forward index scan of: pgbench_accounts_pkey
Conds: (aid = 1234)
(3 rows)
数据库群集目录现在是什么样子呢?新增了 orioledb_data、orioledb_undo 目录。
$ cd $PGDATA/
$ ls
PG_VERSION pg_commit_ts pg_replslot pg_twophase
base pg_dynshmem pg_serial pg_wal
current_logfiles pg_hba.conf pg_snapshots pg_xact
global pg_ident.conf pg_stat postgresql.auto.conf
log pg_logical pg_stat_tmp postgresql.conf
orioledb_data pg_multixact pg_subtrans postmaster.opts
orioledb_undo pg_notify pg_tblspc postmaster.pid
$ ls orioledb_data/
0000000000.xidmap 1 16388 6.xid control
$ ls orioledb_data/16388/
16462 16477-5.tmp 16482-7.map 16488-6.map 16489-7.tmp 16498
16476 16477-6.map 16483 16488-7.evt 16495 16498-5.map
16476-3.map 16477-6.tmp 16483-5.tmp 16488-7.map 16496 16498-6.map
16476-6.map 16482 16483-6.map 16489 16496-5.map
16476-7.evt 16482-3.map 16483-6.tmp 16489-6.map 16496-6.map
16476-7.map 16482-6.map 16488 16489-6.tmp 16496-7.evt
16477 16482-7.evt 16488-3.map 16489-7.map 16496-7.map
$ ls orioledb_undo/
0000000002 0000000003 0000000004
orioledb_data是数据的目录。每个数据库都有一个子目录,其中存放着表的数据文件。
orioledb_undo是UNDO日志的目录。当有更新工作负载时,该文件会增加并轮替。
这是迄今为止的总结。
请问您对本篇文章的印象如何?
OrioleDB的出色之处在于它采用了不同的架构,同时保持了与常规的PostgreSQL相同的易用性,这使得我们能够使用一种全新的数据库软件。
如果有机会,我想在另一个场合的文章中讨论OrioleDB的独特功能,性能提升能力以及有效使用方法等方面的内容。