PostgreSQL 数据压缩 LZ4 OR PGLZ 为什么都说要用新的压缩方式

开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请联系 liuaustin3 ,(共2200人左右 1 + 2 + 3 + 4 +5) 新人奖直接分配到5群,另欢迎 OpenGauss 的技术人员加入。

9b6b35917a9eccfb5e43720fc4106460.png

最近有人问了关于POSTGRESQL 数据压缩的问题,其中有一个问题是关于修改了参数后,无法应用,并且数据库无法启动的问题,我们先从这里说起新的压缩模式。

首先从数据压缩的角度上来说,对于PG 数据库 TOAST 数据存储方式是对于一些大的字段的数据进行压缩和存储的一种模式。默认这样数据压缩的模式是PGLZ的模式。

postgres=# select name,setting,boot_val from pg_settings where name like '%toast%';
-[ RECORD 1 ]-----------------------
name     | default_toast_compression
setting  | pglz
boot_val | pglz

在数据存入到toast 表文件的时候,会对相关的数据采用压缩的方式进行存储,存储的模式目前在PG16上提供两种选择

1 pglz

2 LZ4

配置可以在系统配置文件中进行配置,如上图进行配置,但配置以后有可能会出现下面的错误,这个错误本身来自于修改参数后,PG无法调用LZ4压缩的组件导致的问题。

postgres@pg16:~$ pg_ctl -D /pgdata/data/ restart
waiting for server to shut down.... done
server stopped
waiting for server to start....  [] 2024-04-09 07:59:31.414 UTC [310971]  postmaster 22023 0 LOG:  invalid value for parameter "default_toast_compression": "lz4"
  [] 2024-04-09 07:59:31.414 UTC [310971]  postmaster 22023 0 HINT:  Available values: pglz.
  [] 2024-04-09 07:59:31.414 UTC [310971]  postmaster F0000 0 FATAL:  configuration file "/pgdata/data/postgresql.conf" contains errors
 stopped waiting
pg_ctl: could not start server
Examine the log output.
postgres@pg16:~$

解决方案,对于数据库层面来说,只能重新编译,先确认 liblz4-dev是否安装了,同时后面需要确认在编译的时候,是否带上 -with-lz4的编译配置选项。

root@pg16:~/postgresql-16.0# sudo apt-get install liblz4-dev
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
liblz4-dev is already the newest version (1.9.3-2build2).
0 upgraded, 0 newly installed, 0 to remove and 112 not upgraded.
root@pg16:~/postgresql-16.0# ./configure --prefix=/usr/local/postgres --bindir=/usr/local/postgres/bin --sysconfdir=/etc --libdir=/usr/local/postgres/libs --includedir=/usr/local/postgres/includes --datadir=/pgdata --datarootdir=/pgdata/root --with-pgport=5432 --with-openssl --with-pam --with-systemd --with-libxml --with-segsize=4 --with-ossp-uuid  --with-lz4

操作步骤:

1 停止数据库

2 (非生产数据库) 删除PG可 执行文件目录中的文件

3  重新编译带有 lz4的配置文件,同时在重新编译前需要删除之前已经编译的目录中的文件

4  重新进行应用程序编译 

5  启动数据库,并修改参数

Expanded display is on.
postgres=# select * from pg_settings where name like '%toast%';
-[ RECORD 1 ]---+-------------------------------------------------------------
name            | default_toast_compression
setting         | pglz
unit            | 
category        | Client Connection Defaults / Statement Behavior
short_desc      | Sets the default compression method for compressible values.
extra_desc      | 
context         | user
vartype         | enum
source          | configuration file
min_val         | 
max_val         | 
enumvals        | {pglz,lz4}
boot_val        | pglz
reset_val       | pglz
sourcefile      | /pgdata/data/postgresql.conf
sourceline      | 690
pending_restart | f

postgres=# SET default_toast_compression = lz4;
SET
postgres=# select * from pg_settings where name like '%toast%';
-[ RECORD 1 ]---+-------------------------------------------------------------
name            | default_toast_compression
setting         | lz4
unit            | 
category        | Client Connection Defaults / Statement Behavior
short_desc      | Sets the default compression method for compressible values.
extra_desc      | 
context         | user
vartype         | enum
source          | session
min_val         | 
max_val         | 
enumvals        | {pglz,lz4}
boot_val        | pglz
reset_val       | pglz
sourcefile      | 
sourceline      | 
pending_restart | f

然后我们在让系统支持了LZ4 后,我们来进一些测试和实验,来看看两种数据压缩方式的不同。

我们通过下面的示例可以看到,两个表在数据插入之间的区别,一个是使用LZ4 来进行数据压缩处理的,一个是使用PGLZ方式来进行数据处理的。可以看到明显的使用 LZ4 压缩方式的比 PGLZ 方式数据插入的速度快了 2.5倍。

lz4_test=# CREATE TABLE messages (message text compression lz4);
CREATE TABLE
Time: 10.249 ms
lz4_test=# INSERT INTO messages 
SELECT (SELECT string_agg(chr(floor(random() * 26)::int + 65), '') FROM generate_series(1,10000)) 
FROM generate_series(1,10000);
INSERT 0 10000
Time: 1929.160 ms (00:01.929)
lz4_test=# 
lz4_test=# 
lz4_test=# \c pglz_test
You are now connected to database "pglz_test" as user "postgres".
pglz_test=# 
pglz_test=# 
pglz_test=# CREATE TABLE messages (message text compression pglz);
ERROR:  relation "messages" already exists
Time: 0.709 ms
pglz_test=# INSERT INTO messages 
SELECT (SELECT string_agg(chr(floor(random() * 26)::int + 65), '') FROM generate_series(1,10000)) 
FROM generate_series(1,10000);
INSERT 0 10000
Time: 4889.017 ms (00:04.889)
pglz_test=#

同时我们在启用了 LZ4 后,来查看两个不同压缩方式后的表的大小,可以明显的看出,使用LZ4的表大小是由 119MB 而 使用PGLZ的压缩方式的表的大小为238MB 。

pglz_test=# SELECT
    pg_size_pretty(pg_total_relation_size('messages')) AS total_size,
    pg_size_pretty(pg_relation_size('messages')) AS table_size,
    pg_size_pretty(pg_total_relation_size('messages') - pg_relation_size('messages')) AS index_size;
 total_size | table_size | index_size 
------------+------------+------------
 238 MB     | 1024 kB    | 237 MB
(1 row)

Time: 1.850 ms
pglz_test=# \c lz4_test
You are now connected to database "lz4_test" as user "postgres".
lz4_test=# 
lz4_test=# SELECT
    pg_size_pretty(pg_total_relation_size('messages')) AS total_size,
    pg_size_pretty(pg_relation_size('messages')) AS table_size,
    pg_size_pretty(pg_total_relation_size('messages') - pg_relation_size('messages')) AS index_size;
 total_size | table_size | index_size 
------------+------------+------------
 119 MB     | 512 kB     | 119 MB
(1 row)

Time: 2.492 ms

另外有同学问如果我将这个表的压缩模式进行修改,那么会发生什么

1 表重新建立

2 表的新的数据插入会使用新的压缩模式来进行数据插入

到底是那个结果我们可以看一下,下面的图,注意表在修改了压缩模式后,filename 是否改变,结果显而易见,还是没有变化,文件也没有重写,并且文件还是原来的大小。

b73ea0a63e44af855ac287f784bb8d08.png

69c31a00c5b9cf057db51e5f67ad8803.png

c5a92db7e2a71582bcbb9f5202989412.png

最后我们truncate 表后再次插入数据看是否压缩的模式变化了,下图验证了,的确压缩的模式变化了。

06371d78fd53839e07c3b4c62ca9aba5.png

写到最后,在数据库安装时如果你将默认的压缩模式变为LZ4 那么上面的部分你都不用担心,他默认会选择LZ4作为数据压缩的方案,而不是PLGZ,但如果你没有改,那么你就需要在建立表格的时候,来重新对字段进行设置。

6989166b7c49587166f5e008cfe2658f.png

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值