PostgreSQL码农集散地

电信天翼云开源 XStore 数据库镜像

本期播客


为了体验电信 OpenTeleDB 开源 XStore, 做了个 Docker 镜像

OpenTeleDB 项目介绍

https://github.com/OpenTeleDB/OpenTeleDB

天翼云OpenTeleDB是在中国电信云改数转大背景诞生的,结合TeleDB在电信集团业务和天翼云客户实战打磨的企业级特性,着重解决PostgreSQL存在的并发连接瓶颈,存储空间膨胀,高可用切换的外部依赖等问题。OpenTeleDB本次新增XProxy、XStore、XRaft三大能力,并完美兼容PostgreSQL,基于PostgreSQL的相关业务系统可以无缝的迁移到OpenTeleDB。

  • XProxy:能够提供十万级原生连接上限的接入能力,支持自动读写分离与负载均衡,实现系统的横向扩展,提升整体性能与可用性,让资源利用更充分。
  • Xstore:相较于原生PostgreSQL在高并发更新下,因MVCC机制易导致存储空间持续膨胀,且周期性Vacuum回收会引发性能剧烈波动,执行TPCC模型时性能波动常超40%。OpenTeleDB通过XStore存储引擎对存储层进行全链路重构:通过原位更新与Undo日志管理,从根本杜绝空间膨胀,表空间占用几乎零增长;同时对索引采用原位更新,彻底告别扫表式Vacuum,将执行TPCC模型时性能波动压制在5%以内。
  • XRaft:在数据库核内完成自动高可用,杜绝脑裂,而不依赖第三方外部组件,结构简单,有效保障业务高可用。

为了体验电信openteledb 开源PG XStore, 做了个docker镜像

制作镜像

略

arm64 image

docker pull registry.cn-hangzhou.aliyuncs.com/digoal/opensource_database:openteledb-17-arm64  

x86_64 image

docker pull registry.cn-hangzhou.aliyuncs.com/digoal/opensource_database:openteledb-17-amd64  

用起来:

mkdir -p ~/openteledb_docker_data1  

cd ~/openteledb_docker_data1  
PG_DATA=`pwd`  
PG_USER="postgres"
PG_PASSWORD="123456"

docker run -d -it -p 0.0.0.0:5433:5432 --add-host=host.docker.internal:host-gateway \
  -u root -w /var/lib/postgresql -e LANG=en_US.utf8 \
  -e POSTGRES_INITDB_ARGS="-E UTF8 --locale=C --lc-ctype=en_US.utf8" \
  -v $PG_DATA:/var/lib/postgresql/data \
  -e PGDATA=/var/lib/postgresql/data \
  --cap-add=SYS_PTRACE --cap-add SYS_ADMIN --privileged=true --shm-size=1g \
  -e POSTGRES_USER=$PG_USER -e POSTGRES_PASSWORD=$PG_PASSWORD \
  --name openteledb-test1 \
  registry.cn-hangzhou.aliyuncs.com/digoal/opensource_database:openteledb-17-arm64  

XStore vs HEAP 测试

修改配置文件

psql


\! echo"shared_buffers = 2GB  
maintenance_work_mem = 1GB  
autovacuum_work_mem = -1  
synchronous_commit = off  
wal_writer_delay = 10ms  
max_wal_size = 6GB  
min_wal_size = 1GB  
autovacuum = on  
autovacuum_max_workers = 3  
autovacuum_vacuum_cost_delay = 2ms  
autovacuum_vacuum_cost_limit = -1"
 >> /var/lib/postgresql/data/postgresql.auto.conf  

重启容器后继续测试

create extension if not exists xstore ;    
drop table if exists tbl_xstore ;  
create  table tbl_xstore (id serial primary key, info text, ts timestamp) using xstore;    
insert into tbl_xstore (info, ts) select md5(random()::text), clock_timestamp() from generate_series(1,5000000);    
select pg_size_pretty(pg_total_relation_size('tbl_xstore'));  

 pg_size_pretty   
----------------  
 570 MB  -- 主要是 xbtree 索引较大, 未来有文章来分析xbtree索引为什么更大? 
(1 row)  

drop table if exists tbl_heap ;  
create  table tbl_heap (id serial primary key, info text, ts timestamp) using heap;    
insert into tbl_heap (info, ts) select md5(random()::text), clock_timestamp() from generate_series(1,5000000);    
select pg_size_pretty(pg_total_relation_size('tbl_heap'));  

 pg_size_pretty   
----------------  
 472 MB  
(1 row)  

xstore 表更新压测

\! echo"\set id random(1,5000000)  
update tbl_xstore set info=md5(random()::text), ts=clock_timestamp() where id=:id;"
 > ~/xstore.sql  

\! pgbench -M prepared -n -r -P 1 -f ~/xstore.sql -c 8 -j 8 -T 300  

heap 表更新压测

checkpoint;  


\! echo"\set id random(1,5000000)  
update tbl_heap set info=md5(random()::text), ts=clock_timestamp() where id=:id;"
 > ~/heap.sql  

\! pgbench -M prepared -n -r -P 1 -f ~/heap.sql -c 8 -j 8 -T 300  

对比更新效率和膨胀率

引擎
更新 tps
膨胀率
xstore
107831
0 (570MB 大小无变化)
heap
104360
6.1% (472MB 膨胀到 501MB)

更新抖动情况: XStore 比 HEAP 平稳. 由于 heap 开始膨胀, 相信如果持续拉长测试时间, xstore的表现会更好.


Image

把 XStore 打爆了, 啥情况?

后又运行了3000秒的以上 update 负载, heap 表膨胀到507MB后不再膨胀, 而xstore表崩溃了. 报如下日志:

INFO:  undo record discontinuous,logno 131073, buffer 77453, startingByte 601, page start 24, page end 8192, alreadyWritten 0, lastPageWritten 0, diffpage true, urp 9223442407746503257, newpage true.

-- AI 认为是如下参数配置太小, 但实际上已经很大. 可能是 bug? 

postgres=# show xstore.undo_max_size_per_transaction;
 xstore.undo_max_size_per_transaction 
--------------------------------------
 32GB
(1 row)

postgres=# show xstore.undo_max_total_size;
 xstore.undo_max_total_size 
----------------------------
 256GB
(1 row)