Greenplum 列存原理

Greenplum 在表的存储结构上分为 HEAP 表、AO 表。

其中 HEAP 表是 PG 数据库原生存储格式,也是 Greenplum 的默认存储格式,但是只支持行存储,并且不能压缩。AO 表为 append optimized 表,支持行存储、列存储,支持多种压缩算法与压缩级别。

AO 表原理

Greenplum 4.3 之前 AO 表为 appendonly 表,只能追加,即只能进行插入,不能更新和删除。Greenplum 4.3 之后,AO 表优化为 append optimized 表,支持插入、更新、删除。插入即在最后追加记录;删除通过维护一张 bitmap 表,标记被删除的行;更新则为删除和插入 2 个操作的组合。所以 append optimized 表在大量更新或删除之后,标记为无效的数据不会自动清除,需要使用 vaccum 命令回收这部分空间。

bitmap 表如下,通过 bit 位以及偏移量来判定 AO 表上的某一行是否被删除(其中 82342 为 AO 表的 relid,bitmap 表就为 pg_aoseg.pg_aovisimap_{relid}):

lzk=# select * from pg_aoseg.pg_aovisimap_82342;
segno | first_row_no |               visimap                

-------+--------------+----------------------------------------
    2 |     1081344 | \x0100000081002cbc002000008c00
    2 |     2064384 | \x0100000084002ff2ff00c80000000bfcbd80
    2 |     1114112 | \x0100000084002ff2ff266c00020000bfca48
    2 |     3440640 | \x0100000081002f5c000020008180
    2 |     4259840 | \x0100000084002ff2ff28bc00000100bfc9b4
    2 |     5079040 | \x01000000804022dc000800008380
    2 |     3211264 | \x0100000082002ff26dc00400000a34
    2 |     1638400 | \x0100000082002ff25dc00080000a74
    2 |       458752 | \x0100000084002ff2ff2ff223c00000020b54
(9 rows)

对于 heap 表,由 tupleid 决定每条记录的位置(tupleid 包含记录在文件中偏移位置),而对于 AO 表,数据是压缩的,没法确定 value 在文件中偏移位置,因此使用了 rownum,每条记录都有自己的 rownum,rownum 一直增长,每个 block 中记录了起始 rownum 以及 block 在文件中偏移位置,所以只要给定一个 rownum,就能定位到所在的 block,然后从 block 中就可以遍历到这个 rownum 对应的记录。

列存原理

列存只能是 AO 表,所以上一节中所有的 AO 表原理都适用。列存表,按列,每列对应一个或一批文件,每个列占用一个至多个文件,最多 128 个(预留 128 个 id),不同列的值不会同时出现一个文件。

列存表的文件存储,即(25854.1,25854.2 为第一列,25854.129、25854.130 为第二列,以此类推):

[gpadmin@host10372181 /data1/primary/gpseg0/base/82341]$ll|grep 25854
-rw------- 1 gpadmin gpadmin         0 Jul 14 16:48 25854
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.1
-rw------- 1 gpadmin gpadmin       6168 Jul 16 14:14 25854.1025
-rw------- 1 gpadmin gpadmin   3108976 Jul 15 15:47 25854.1026
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.1153
-rw------- 1 gpadmin gpadmin   1476776 Jul 15 15:47 25854.1154
-rw------- 1 gpadmin gpadmin       5976 Jul 16 14:14 25854.1281
-rw------- 1 gpadmin gpadmin   2746744 Jul 15 15:47 25854.1282
-rw------- 1 gpadmin gpadmin       6160 Jul 16 14:14 25854.129
-rw------- 1 gpadmin gpadmin   2626616 Jul 15 15:47 25854.130
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.1409
-rw------- 1 gpadmin gpadmin   1360584 Jul 15 15:47 25854.1410
-rw------- 1 gpadmin gpadmin       5848 Jul 16 14:14 25854.1537
-rw------- 1 gpadmin gpadmin   2559240 Jul 15 15:47 25854.1538
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.1665
-rw------- 1 gpadmin gpadmin   1257912 Jul 15 15:47 25854.1666
-rw------- 1 gpadmin gpadmin       6368 Jul 16 14:14 25854.1793
-rw------- 1 gpadmin gpadmin   2106232 Jul 15 15:47 25854.1794
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.1921
-rw------- 1 gpadmin gpadmin   17856504 Jul 15 15:47 25854.1922
-rw------- 1 gpadmin gpadmin     279528 Jul 15 15:47 25854.2
-rw------- 1 gpadmin gpadmin       7016 Jul 16 14:14 25854.2049
-rw------- 1 gpadmin gpadmin   66013896 Jul 15 15:47 25854.2050
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.2177
-rw------- 1 gpadmin gpadmin   16055520 Jul 15 15:47 25854.2178
-rw------- 1 gpadmin gpadmin       6208 Jul 16 14:14 25854.2305
-rw------- 1 gpadmin gpadmin   22774616 Jul 15 15:47 25854.2306
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.2433
-rw------- 1 gpadmin gpadmin   7181688 Jul 15 15:47 25854.2434
-rw------- 1 gpadmin gpadmin       7032 Jul 16 14:14 25854.2561
-rw------- 1 gpadmin gpadmin   14922064 Jul 15 15:47 25854.2562
-rw------- 1 gpadmin gpadmin     11176 Jul 16 14:14 25854.257
-rw------- 1 gpadmin gpadmin   11304392 Jul 15 15:47 25854.258
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.2689
-rw------- 1 gpadmin gpadmin   5351744 Jul 15 15:47 25854.2690
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.2817
-rw------- 1 gpadmin gpadmin     201488 Jul 15 15:47 25854.2818
-rw------- 1 gpadmin gpadmin       6160 Jul 16 14:14 25854.2945
-rw------- 1 gpadmin gpadmin   3593248 Jul 15 15:47 25854.2946
-rw------- 1 gpadmin gpadmin       9824 Jul 16 14:14 25854.3073
-rw------- 1 gpadmin gpadmin   12571176 Jul 15 15:47 25854.3074
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.3201
-rw------- 1 gpadmin gpadmin   3308464 Jul 15 15:47 25854.3202
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.3329
-rw------- 1 gpadmin gpadmin   3258376 Jul 15 15:47 25854.3330
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.3457
-rw------- 1 gpadmin gpadmin   1604200 Jul 15 15:47 25854.3458
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.3585
-rw------- 1 gpadmin gpadmin   3483096 Jul 15 15:47 25854.3586
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.3713
-rw------- 1 gpadmin gpadmin     354840 Jul 15 15:47 25854.3714
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.3841
-rw------- 1 gpadmin gpadmin     329024 Jul 15 15:47 25854.3842
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.385
-rw------- 1 gpadmin gpadmin   1204480 Jul 15 15:47 25854.386
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.3969
-rw------- 1 gpadmin gpadmin     363400 Jul 15 15:47 25854.3970
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.4097
-rw------- 1 gpadmin gpadmin     368080 Jul 15 15:47 25854.4098
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.4225
-rw------- 1 gpadmin gpadmin     213120 Jul 15 15:47 25854.4226
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.4353
-rw------- 1 gpadmin gpadmin     187264 Jul 15 15:47 25854.4354
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.4481
-rw------- 1 gpadmin gpadmin     218800 Jul 15 15:47 25854.4482
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.4609
-rw------- 1 gpadmin gpadmin   1687376 Jul 15 15:47 25854.4610
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.4737
-rw------- 1 gpadmin gpadmin     761744 Jul 15 15:47 25854.4738
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.4865
-rw------- 1 gpadmin gpadmin   10054680 Jul 15 15:47 25854.4866
-rw------- 1 gpadmin gpadmin       6624 Jul 16 14:14 25854.513
-rw------- 1 gpadmin gpadmin   2743616 Jul 15 15:47 25854.514
-rw------- 1 gpadmin gpadmin       5280 Jul 16 14:14 25854.641
-rw------- 1 gpadmin gpadmin   1149328 Jul 15 15:47 25854.642
-rw------- 1 gpadmin gpadmin       5632 Jul 16 14:14 25854.769
-rw------- 1 gpadmin gpadmin   1861056 Jul 15 15:47 25854.770
-rw------- 1 gpadmin gpadmin       6160 Jul 16 14:14 25854.897
-rw------- 1 gpadmin gpadmin   2020608 Jul 15 15:47 25854.898

若只更新某1列或某几列,对于列存 AO 表,每个列文件之间并没有指针或其他关联,依靠相同的 rownum 来定位一行数据,所有列文件中该 rownum 数据全部作废,然后使用更新后的数据插入到新的一行中,此行中的所有 rownum 保留。因此,此时的数据更新,并不是只更新指定的列。所以单条 update 带来的 IO 开销很大,需要对每一个列文件都写入。

小结

对于 Greenplum 中的 AO 表,其实无论是行存或列存,更新所带来的性能降低是可以预估的。一条 SQL 语句的执行时间基本上可以简单的分为 IO 消耗的时间和计算时间。一张表在大量更新之后只会线性的增加 IO 时间,计算时间并不会受到影响。即假设表 A 通过 update 更新了 30% 的数据,同样的一条 SQL 执行时间的延长理论上不高于 30%。并且可以通过 vacuum 回收被删除数据的空间来恢复原有的查询性能。

发表评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据