opengauss存储引擎分两种类型
磁盘存储引擎 和 内存存储引擎,磁盘存储引擎是将数据持久化存储到磁盘的实现方法,根据表的特点又分为行存储和列存储两类。
行存储主要用oltp事务类的需求,列存储多用于数据分析与统计类的场景。
opengauss行存储引擎有两种astore和ustore 区别在于
Astore采用追加更新模式,即同一个page页中既存在前映像也存在当前值,只是前映像会被标记为删除。Astore是opengauss的默认存储引擎,Astore存储引擎由于同一个块中包含太多的前映像,如果频繁的更新操作会导致大量的磁盘“垃圾”,因为在执行查询操作的时候即使标记了删除也会扫描,所以大大的降低性能,建议定期执行VACUUM或者VACUUM full进行清理。
Ustore(In-place Update)存储引擎是openGauss 2.1.0版本新增的特性。此前的版本使用的行存储引擎是Append Update(追加更新)模式。追加更新对于业务中的增、删以及HOT(HeapOnly Tuple)Update(即同一页面内更新)有很好的表现,但对于跨数据页面的非HOT UPDATE场景,垃圾回收不够高效。因此,Ustore存储引擎应运而生。
Ustore 可以提供高性能:对插入、更新、删除等不同负载的业务,性能以及资源使用表现相对均衡。更新操作采用原地更新模式在频繁更新类的业务场景下可拥有更高、更平稳的性能表现。适应“短”(事务短)、“频”(更新操作频繁)、“快”(性能要求高)的典型OLTP类业务场景。
高效存储:支持最大限度的原位更新, 极大节约了空间;将回滚段、数据页面分离存储,具备更高效、平稳的IO使用能力,UNDO子系统采用NUMA-aware设计,具有更好的多核扩展性,UNDO空间统一分配,集中回收,复用效率更高,存储空间使用更加高效、平稳。
cstore 列存储格式
cstore列存储格式整体框架。与行存储格式不同,cstore列存储的主体数据文件以CU为I/O单元,只支持追加写操作,因此cstore只有读共享缓冲区。CU间和CU内的可见性由对应的CUDESE表(astore表)决定,因此其可见性和并发控制原理与行存储astore基本相同。
扩展格式
mstore 内存存储格式
mstore内存引擎面向超低时延和超高吞吐量的OLTP场景。数据以元组粒度存储于内存介质中,得益于内存介质读、写操作的超低时延(与磁盘介质相比),内存引擎可以提供极致的OLTP业务性能。内存引擎通过openGauss的外表访存接口实现与SQL引擎的数据交互
新建表进行插入,更新 ,删除测试
(1)astore
默认创建的Astore的表,通过设置enable_default_ustore_table参数为on可以修改为默认创建Ustore的表,当然在创建表的时候可以指定storage_parameter参数选择存储引擎
CREATE TABLE astore_httab (
id character(10) NOT NULL,
name character(50),
saler numeric(10,2),
dept_no character(10)
)
WITH (STORAGE_TYPE=ASTORE);
(2)Ustore
CREATE TABLE ustore_httab (
id character(10) NOT NULL,
name character(50),
saler numeric(10,2),
dept_no character(10)
)
WITH (STORAGE_TYPE=USTORE);
(3)cstore
CREATE TABLE cstore_httab (
id character(10) NOT NULL,
name character(50),
saler numeric(10,2),
dept_no character(2)
)
WITH (ORIENTATION = COLUMN);
(4)mstore
create FOREIGN TABLE mstore_httab (
id character(10) NOT NULL,
name character(50),
saler numeric(10,2),
dept_no character(10)
);
mydb(# );
ERROR: Cannot create MOT tables while incremental checkpoint is enabled.
需要修改参数enable_incremental_checkpoint,重启数据库后可创建MOT表。
检查点相关参数描述参见《开发者指南》中“GUC参数说明 > 预写式日志 > 检查点”章节。其中"enable_incremental_checkpoint"为on时,设置自动WAL检查点之间的最长时间将由"incremental_checkpoint_timeout"决定,如果不采用默认值并将其改大,将可能导致实例重启时会有大量日志需要回放,进而影响到容灾指标RTO变大,无法达到特性规格。
/opt/opengauss/data/dn/postgresql.conf
enable_incremental_checkpoint = on # enable incremental checkpoint
需要更改enable_incremental_checkpoint为off 重启数据库
三循环插入数据
(1)
CREATE OR REPLACE PROCEDURE astore_httab_loop(maxval in integer)
AS
DECLARE
i int :=1;
BEGIN
WHILE i < maxval LOOP
INSERT INTO astore_httab VALUES(i,'奥德彪','34000','01');
i:=i+1;
END LOOP;
END;
/
--调用函数
CALL astore_httab_loop(20000);
(2)
CREATE OR REPLACE PROCEDURE ustore_httab_loop(maxval in integer)
AS
DECLARE
i int :=1;
BEGIN
WHILE i < maxval LOOP
INSERT INTO ustore_httab VALUES(i,'奥德彪','34000','01');
i:=i+1;
END LOOP;
END;
/
--调用函数
CALL ustore_httab_loop(20000);
(3)
CREATE OR REPLACE PROCEDURE cstore_httab_loop(maxval in integer)
AS
DECLARE
i int :=1;
BEGIN
WHILE i < maxval LOOP
INSERT INTO cstore_httab VALUES(i,'奥德彪','34000','01');
i:=i+1;
END LOOP;
END;
/
--调用函数
CALL cstore_httab_loop(20000);
行表插入很慢
(4)
CREATE OR REPLACE PROCEDURE mstore_httab_loop(maxval in integer)
AS
DECLARE
i int :=1;
BEGIN
WHILE i < maxval LOOP
INSERT INTO mstore_httab VALUES(i,'奥德彪','34000','01');
i:=i+1;
END LOOP;
END;
/
--调用函数
CALL mstore_httab_loop(10000);
更新astore和ustore表全部更新一遍
再查询两张表的大小
更新as表
CREATE OR REPLACE PROCEDURE astore_httab_up_loop(maxval in integer)
AS
DECLARE
i int :=1;
BEGIN
WHILE i < maxval LOOP
UPDATE FROM astore_httab VALUES(i,'奥德彪','44000','01') where name='奥德彪';
i:=i+1;
END LOOP;
END;
/
--调用函数
CALL astore_httab_up_loop(10000);
更新us表
CREATE OR REPLACE PROCEDURE ustore_httab_up_loop(maxval in integer)
AS
DECLARE
i int :=1;
BEGIN
WHILE i < maxval LOOP
UPDATE FROM ustore_httab VALUES(i,'奥德彪','44000','01') where name='奥德彪';
i:=i+1;
END LOOP;
END;
/
--调用函数
CALL ustore_httab_up_loop(10000);
四查询表的基础信息
astore_httab ustore_httab cstore_httab
mydb=# select pg_relation_filepath('astore_httab');
pg_relation_filepath
base/16399/16407
(1 row)
mydb=#
mydb=# select pg_size_pretty(pg_relation_size('astore_httab'));
pg_size_pretty
2136 kB
(1 row)
mydb=# select pg_size_pretty(pg_relation_size('ustore_httab'));
pg_size_pretty
1912 kB
(1 row)
mydb=# select pg_size_pretty(pg_relation_size('cstore_httab'));
pg_size_pretty
325 MB
(1 row)
更新表
mydb=# update astore_httab SET saler = saler + 100 where name='奥德彪';
UPDATE 19999
mydb=# update ustore_httab SET saler = saler + 100 where name='奥德彪';
UPDATE 19999
mydb=# update cstore_httab SET saler = saler + 100 where name='奥德彪';
UPDATE 19999
mydb=# select pg_size_pretty(pg_relation_size('astore_httab'));
pg_size_pretty
4272 kB
(1 row)
mydb=# select pg_size_pretty(pg_relation_size('ustore_httab'));
pg_size_pretty
1912 kB
(1 row)
mydb=# select pg_size_pretty(pg_relation_size('cstore_httab'));
pg_size_pretty
326 MB
(1 row)
astore存储引擎更新后数据表大小增加。
删除部分数据
mydb=# delete from astore_httab where id>15000;
DELETE 4999
mydb=# delete from ustore_httab where id>15000;
DELETE 4999
mydb=# delete from cstore_httab where id>15000;
DELETE 4999
mydb=# select pg_size_pretty(pg_relation_size('astore_httab'));
pg_size_pretty
4272 kB
(1 row)
mydb=# select pg_size_pretty(pg_relation_size('ustore_httab'));
pg_size_pretty
1912 kB
(1 row)
mydb=# select pg_size_pretty(pg_relation_size('cstore_httab'));
pg_size_pretty
326 MB
(1 row)
mydb=#
删除数据表不会缩小。