尝试操作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的独特功能,性能提升能力以及有效使用方法等方面的内容。

广告
将在 10 秒后关闭
bannerAds