pg中支持创建unlogged table,顾名思义就是不记录日志的表,这个和oracle创建表时的nologging选项类似。
unlogged table主要有几个特点:
1、unlogged table不记录wal日志,写入速度快,备库无数据,只有结构。
2、当数据库crash后,数据库重启时自动清空unlogged table的数据。
3、正常关闭数据库,再启动时,unlogged table有数据。
4、unlogged table通常用于中间结果,频繁变更的会话数据
性能压测:
–普通表
1、创建测试表
create table t_normal(
id int8,
c1 int8 default 0,
c2 int8 default 0,
c3 int8 default 0,
c4 float8 default 0,
c5 text default 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
ts timestamp default clock_timestamp()
) with (autovacuum_enabled=off, toast.autovacuum_enabled=off);
do language plpgsql $$
declare
begin
for i in 1..1024 loop
execute format('create unlogged table t_normal%s (like t_normal including all) inherits (t_normal) with (autovacuum_enabled=off, toast.autovacuum_enabled=off) '||case when mod(i,2)=0 then 'tablespace testdb' else '' end, i);
end loop;
end;
$$;
2、创建测试函数
create or replace function ins_normal(int, int) returns void as $$
declare
begin
execute format('insert into t_normal%s (id) select generate_series(1,%s)', $1, $2);
-- 为了拼接表名,使用了动态SQL,硬解析耗时。
-- 导致测试结果有出入,至少不会比单表无索引写入性能差。
-- 批量写入的话,硬解析的问题可以被掩盖。
end;
$$ language plpgsql strict;
3、创建测试脚本
vi test1.sql
\set sid random(1,1024)
select ins_normal(:sid, 1000);
4、性能压测
pg12@oracle-> pgbench -M prepared -n -r -f ./test1.sql -P 5 -c 32 -j 32 -T 60
transaction type: ./test1.sql
scaling factor: 1
query mode: prepared
number of clients: 32
number of threads: 32
duration: 60 s
number of transactions actually processed: 63739
latency average = 30.126 ms
latency stddev = 62.176 ms
tps = 1060.268771 (including connections establishing)
tps = 1060.877189 (excluding connections establishing)
statement latencies in milliseconds:
0.001 \set sid random(1,1024)
30.104 select ins_normal(:sid, 1000);
–unlogged table
1、创建测试表
create unlogged table t_sensor(
id int8,
c1 int8 default 0,
c2 int8 default 0,
c3 int8 default 0,
c4 float8 default 0,
c5 text default 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
ts timestamp default clock_timestamp()
) with (autovacuum_enabled=off, toast.autovacuum_enabled=off);
do language plpgsql $$
declare
begin
for i in 1..1024 loop
execute format('create unlogged table t_sensor%s (like t_sensor including all) inherits (t_sensor) with (autovacuum_enabled=off, toast.autovacuum_enabled=off) '||case when mod(i,2)=0 then 'tablespace testdb' else '' end, i);
end loop;
end;
$$;
2、创建测试函数
create or replace function ins_sensor(int, int) returns void as $$
declare
begin
execute format('insert into t_sensor%s (id) select generate_series(1,%s)', $1, $2);
-- 为了拼接表名,使用了动态SQL,硬解析耗时。
-- 导致测试结果有出入,至少不会比单表无索引写入性能差。
-- 批量写入的话,硬解析的问题可以被掩盖。
end;
$$ language plpgsql strict;
3、创建测试脚本
vi test2.sql
\set sid random(1,1024)
select ins_sensor(:sid, 1000);
4、性能压测
pg12@oracle-> pgbench -M prepared -n -r -f ./test2.sql -P 5 -c 32 -j 32 -T 60
transaction type: ./test2.sql
scaling factor: 1
query mode: prepared
number of clients: 32
number of threads: 32
duration: 60 s
number of transactions actually processed: 67614
latency average = 28.489 ms
latency stddev = 38.002 ms
tps = 1120.687326 (including connections establishing)
tps = 1121.126034 (excluding connections establishing)
statement latencies in milliseconds:
0.001 \set sid random(1,1024)
28.489 select ins_sensor(:sid, 1000);
对比可以发现unlogged table的写性能是要强于普通表的。
小结:
1、写性能
unlogged table > 普通表(异步事务) > 普通表(同步事务)
2、资源消耗
unlogged table 不写WAL,IO开销小。
3、适应场景
批量计算的中间结果,频繁变更的会话数据。
4、注意事项
4.1、unlogged table不记录wal日志,写入速度快,备库无数据,只有结构。
4.2、当数据库crash后,数据库重启时自动清空unlogged table的数据。