KingbaseES toast技术原理及实现
前言
1、TOAST的作用
TOAST全称是The Oversized-Attribute Storage Technique, 超大属性存储技术,就是超长字段在数据库中的存储方式。主要用来应对物理数据行超大的场景。
在KingbaseES中,页是数据在文件存储中的基本单位,它的大小是固定的,并且只能在编译期指定,默认的大小为8kb。同时不允许一行数据跨页存储。因此页大小就是行大小的硬上限,因此,引入了TOAST技术,TOAST技术是采用压缩和切片的方式,使得行的大小变小。需要说明这一技术对用户来说是完全透明的。
2、关于toast压缩
我们创建的每个表都有自己关联且唯一的TOAST表。当数据超过TOAST_TUPLE_THRESHOLD(默认2KB)时,数据库将压缩数据。
如果对大列数据的压缩后没有得到更小的块(<2KB),那么它将被拆分为更小的块,并存储在相关TOAST表中多个物理行(行外存储)。
每个原始表字段值都被一个指针替换,实际上根据这个指针可以找到对应toast表中行外存储的数据。
3、数据库中表字段的TOAST策略
PLAIN: 避免压缩和行外存储。
EXTENDED:允许压缩和行外存储。
EXTERNAL: 允许行外存储,但不允许压缩。
MAIN: 允许压缩,但不允许行外存储。
4、查看表字段的TOAST策略
[
](javascript:void(0)
EST=# \d+ t1
Table "PUBLIC.T1"
Column | Type | Modifiers | Storage | Stats target | Description
--------+-------------------+-----------+----------+--------------+-------------
ID | INTEGER | | plain | |
NAME | CHARACTER VARYING | | extended | |
[
](javascript:void(0)
其中的Storage对应字段使用的TOAST策略。
5、修改表字段的TOAST策略
alter table tablename alter column column_name set storage EXTENDED;
toast技术的实现方式:
[
](javascript:void(0)
创建一张 tosttest 表
test=# create table tosttest(id int, tad text, name text);
CREATE TABLE
TEST=# \d+ tosttest;
Table "public.tosttest"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
id | integer | | | | plain | |
tad | text | | | | extended | |
name | text | | | | extended | |
Access method: heap
如上,interger类型默认TOAST策略为plain,而text类型为extended,所以对于非变长数据类型默认是不需要toast存储的。如果表中字段需要用到TOAST,那么数据库会自动创建一张TOAST表负责行外存储。
test=# select relname,relfilenode,reltoastrelid from sys_class where relname='tosttest';
relname | relfilenode | reltoastrelid
----------+-------------+---------------
tosttest | 92932 | 92935
(1 row)
如上,我们查到 tosttest 表的 oid为92932,其对应 TOAST 表的 oid为92935,其对应TOAST表名则为:pg_toast.pg_toast_92932,我们可以看下定义:
test=# \d+ pg_toast.pg_toast_92932;
TOAST table "pg_toast.pg_toast_92932"
Column | Type | Storage
------------+---------+---------
chunk_id | oid | plain
chunk_seq | integer | plain
chunk_data | bytea | plain
验证toast表:
test=# insert into tosttest values(1, 'tad', '0123456789');
INSERT 0 1
test=# select * from tosttest;
id | tad | name
----+-------+------------
1 | tad | 0123456789
(1 row)
test=# select * from pg_toast.pg_toast_92932;
chunk_id | chunk_seq | chunk_data
----------+-----------+------------
(0 rows)
可以看到因为name只有10个字符,所以没有压缩,也没有行外存储。下面增加 name 的长度,看看会发生什么
test=# update tosttest set name=name||name where id=1;
UPDATE 1
test=# select id,tad,length(name) from tosttest;
id | tad | length
----+-------+--------
1 | tad | 20
(1 row)
test=# select * from pg_toast.pg_toast_92932;
chunk_id | chunk_seq | chunk_data
----------+-----------+------------
(0 rows)
反复执行如上过程,直到 pg_toast_92932 表中有数据:
test=# select id,tad,length(name) from tosttest;
id | tad | length
----+-------+--------
1 | tad | 327680
(1 row)
TEST=# select chunk_id,chunk_seq,length(chunk_data) from pg_toast.pg_toast_92932;
chunk_id | chunk_seq | length
----------+-----------+--------
92938 | 0 | 1988
92938 | 1 | 1781
(2 rows)
可以看到,直到 name 的长度为327680时,对应 TOAST 表中有了2行数据,且长度都是略小于2K,这是因为 extended 策略下,先启用了压缩,然后才使用行外存储。
下面我们将 name字段的 TOAST 策略改为 EXTERNA ,禁止压缩。
test=# alter table tosttest alter name set storage external;
ALTER TABLE
test=# \d+ tosttest;
Table "public.tosttest"
Column | Type | Modifiers | Storage | Stats target | Description
---------+---------+-----------+----------+--------------+-------------
id | integer | | plain | |
tad | text | | extended | |
name | text | | external | |
然后我们重新插入一条数据:
test=# insert into tosttest values(2, 'tad', '0123456789');
INSERT 0 1
test=# select id,tad,length(name) from tosttest;
id | tad | length
----+-------+--------
1 | tad | 327680
2 | tad | 10
(2 rows)
再次重复以上步骤,直到TOAST表中产生新的行:
test=# update tosttest set name=name||name where id=2;
UPDATE 1
TEST=# select id,tad,length(name) from tosttest;
id | tad | length
----+-----+--------
1 | tad | 327680
2 | tad | 5120
(2 rows)
TEST=# select chunk_id,chunk_seq,length(chunk_data) from pg_toast.pg_toast_92932;
chunk_id | chunk_seq | length
----------+-----------+--------
92938 | 0 | 1988
92938 | 1 | 1781
92940 | 0 | 1988
92940 | 1 | 1988
92940 | 2 | 1144
(5 rows)我们看到当, TOAST 表中产生了新的3条 chunk_id 为92940的行,且3行数据的 chunk_data 的长度之和正好等于name字段长度5120,所以这里并没有压缩。
[
](javascript:void(0)
总结:
如果存储策略允许压缩,则TOAST优先选择压缩。
不管是否压缩,一旦数据超过2KB,就会启用行外存储,数据存储到toast表中。
修改TOAST策略,不会影响现有数据的存储方式。
KingbaseES toast技术原理及实现的更多相关文章
- Atitit.ide技术原理与实践attilax总结
Atitit.ide技术原理与实践attilax总结 1.1. 语法着色1 1.2. 智能提示1 1.3. 类成员outline..func list1 1.4. 类型推导(type inferenc ...
- Atitit.异步编程技术原理与实践attilax总结
Atitit.异步编程技术原理与实践attilax总结 1. 俩种实现模式 类库方式,以及语言方式,java futuretask ,c# await1 2. 事件(中断)机制1 3. Await 模 ...
- Atitit 语音识别的技术原理
Atitit 语音识别的技术原理 1.1. 语音识别技术,也被称为自动语音识别Automatic Speech Recognition,(ASR),2 1.2. 模型目前,主流的大词汇量语音识别系统多 ...
- Atitit.gui api自动化调用技术原理与实践
Atitit.gui api自动化调用技术原理与实践 gui接口实现分类(h5,win gui, paint opengl,,swing,,.net winform,)1 Solu cate1 Sol ...
- 新手入门:史上最全Web端即时通讯技术原理详解
前言 有关IM(InstantMessaging)聊天应用(如:微信,QQ).消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为 ...
- Web端即时通讯技术原理详解
前言 有关IM(InstantMessaging)聊天应用(如:微信,QQ).消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为 ...
- <转>VPN技术原理
原文地址:VPN技术原理 VPN,Virtual Private Network(虚拟专用 网络),被定义为通过一个公用网络(通常是因特网)建立一个临时的.安全的连接,是一条穿过公用网络的安全.稳定的 ...
- seo伪原创技术原理分析,php实现伪原创示例
seo伪原创技术原理分析,php实现伪原创示例 现在seo伪原创一般采用分词引擎以及动态同义词库,模拟百度(baidu),谷歌(google)等中文切词进行伪原创,生成后的伪原创文章更准确更贴近百度和 ...
- 液晶常用接口“LVDS、TTL、RSDS、TMDS”技术原理介绍
液晶常用接口“LVDS.TTL.RSDS.TMDS”技术原理介绍 1:Lvds Low-Voltage Differential Signaling 低压差分信号 1994年由美国国家半导体公司提出之 ...
- Ajax 技术原理(转)
Ajax 技术原理 2010-01-04 原文出处:http://www.nowamagic.net/ajax/ajax_AjaxPrinciple.php 在写这篇文章之前,曾经写过一篇关于AJAX ...
随机推荐
- numpy数组初始化方法总结
1 使用list初始化 a=np.array([[1,2,3],[4,5,6]],dtype='float32') #a=[[1. 2. 3.],[4. 5. 6.]] 2 赋值与复制 (1)赋值 a ...
- 【Android】MediaCodec详解
1 前言 MediaCodec 主要用于视频解码和编码操作,可以实现视频倍速播放.全关键帧转换.视频倒放等功能. MediaCodec 的工作原理图如下: MediaCodec 的主要接口 ...
- Swoole从入门到入土(19)——WebSocket服务器[文件传输]
要利用WebSocket进行文件传输,我们需要讨论两种情况,分别是:发送方可以是客户端,和 发送方是服务端. 1.发送方是客户端 1)服务端接收 $server->on('message', ...
- SpringBoot相关注解使用
@MapperScan注解和@Mapper @Mapper常用在相应的 *Mapper类上,但是每个类都使用相对麻烦,所以后来用@MapperScan替代 ,@MapperScan注解使用在启动类上. ...
- MySQL写入SQL整个执行流程
innodb存储引擎中一条sql写入的详细流程 第0步:会先去看缓冲区有没有这条数据,如果有就不进行缓存,直接进入第三步. 第1步:会将要修改的那一行数据所在的一整页加载到缓冲池Buffe ...
- 关于 try... catch
在逛论坛看见一个有意思的帖子,有点意思,记录下 关于"异常捕捉"(try catch)是否存在悖论? 一些我觉得有用的回复,放到下面了, 1. 当某些错误状况难以完全避免时,try ...
- 封装一些常用的 qt 控件
在 qt 中需要做 toast 效果和图片 tip 效果,故开发了下面一个类 后续会继续添加一些常用的控件 tool_tip.h #include <qlabel.h> #include ...
- String - 一些测试(持续更新)
void main() { char *buffer = new char(1000); memset(buffer, 0, 1000); char buffer1[1000] = {}; buffe ...
- 微服务程序运行步骤及nameko入门案例
首先一个微服务应用程序需要有服务的生产者和服务的消费者,另外还需要一个注册中心来管理和调度服务 1.服务提供方,即生产者启动服务,并将服务提交到注册中心注册服务 2.服务需求方,即消费者连接到注册中心 ...
- 【C++ OOP 03 友元】各种友元例子以及如何类外写成员函数
[友元] 在程序里,有些私有属性 也想让类外特殊的一些函数或者类进行访问,就需要用到友元的技术 友元的目的就是让一个函数或者类 访问另一个类中私有成员 友元的关键字为 friend 友元的三种实现 全 ...