Greenplum数据加密功能前瞻(一):堆表的存储管理

系列简介

为了满足客户对于数据安全的严苛要求,Greenplum开发团队正在为Greenplum数据库设计开发数据加密功能,保证磁盘上的数据是加密存储的。在这个系列文章中,我们将对这一功能做一个简要介绍,主要介绍数据加密功能的主要原理和它所能带来的价值。

Greenplum的存储管理器

为了理解数据加密功能的原理,首先需要了解Greenplum是如何将数据存储到磁盘上的。通常,磁盘是由操作系统中的文件系统来管理的,文件系统提供了一个磁盘的“文件视图”,即磁盘上数据是以文件为基本单位进行组织和管理的。而对于Greenplum来说,它需要的是一个磁盘的“块视图”,即以“块”为基本单位对数据进行组织和管理。一个“块”指的是一个较小(在Greenplum中默认为32 KB)的区域,数据的读写都以块为基本单位。这是因为Greenplum在很多时候仅需要访问很小一部分数据,如某一行记录。在这种情况下以块为单位进行读写可以很大程度上避免读写无用的数据,同时又能够保证管理过程本身方便高效,从而保证数据库系统的高效运行。

在Greenplum数据库中,存储管理器(Storage Manager,简称 smgr)的主要任务就是充当这两种视图的“桥梁”。一方面,在操作系统层面上,数据在磁盘上还是以文件的形式进行组织和管理的;另一方面,Greenplum是以块为单位对数据进行访问的。因此,存储管理器需要将Greenplum对数据“块”的访问操作转换成对数据“文件”的访问操作,这样,这些操作才能够被操作系统所执行,从而满足Greenplum的数据访问需求。

堆表的存储管理需求

堆表是Greenplum默认的数据存储方式。在堆表中,数据是以块为单位读写的,而且块的大小是固定的。因此,Greenplum可以通过块号指明所需读写的块。由于文件系统是通过文件名确定文件的,存储管理器需要根据块号确定块所在的文件的文件名和文件内的起始位置,然后调用文件系统的相关函数完成数据的读写操作。

文件名的确定

将对数据块的操作转换成对数据文件的操作的首要问题就是如何确定一个数据块所对应的数据文件的文件名。考虑到某些操作系统不能支持过大的文件,对于堆表来说,Greenplum限制了每个数据文件的大小的上限(默认为1 GB)。一旦数据文件超过这个上限,Greenplum会创建一个新文件存放数据。这样,每个文件实际上只存储一个数据表的一段(Segment)。每一段都由一个段号标识。不同的表使用不同的文件存储。于是,对于某一个数据块,只需知道它所在的表和表内的段就能确定它所在的数据文件的文件名。

Greenplum为每个表分配了一个对象标识(Object ID),这个标识在表创建的时候分配,在表的整个生命周期内都不会改变。然而,在Grenplum中,某些SQL命令,例如VACUUM FULL,会导致表中的数据从一个文件转移到另一个文件。因此,Greenplum不能使用表的对象标识作为文件名。为了解决这一问题,Greenplum另外为每个表分配了一个文件号,它在一般情况下是不变的,而只当数据在不同文件间转移时会发生改变。表的文件号存在数据库的系统目录(Catalog)的pg_class 表中。通过文件号可以找到一个表的数据所在的所有文件。

找到了一个表的数据所在的所有文件之后,如何确定某个数据块在哪一个文件中呢?这就需要确定数据块所在的段。对于堆表来说,数据块在不同的段中是按照块号从小到大排布的,即从第0块开始,先排第0个段,排满后再排第1个段,排满后再排第2个段……以此类推。因此,一个数据块所在的段号可以由如下公式计算得出:段号 = 块号 * 块大小 / 段大小的上限。由于除以的是上限,若得到结果不是整数,则需要向下取整。

文件内起始位置的确定

为了让文件系统对某一个数据块的读写操作不涉及其他无关数据,在确定了数据块所在的文件之后,还需要确定数据块在文件中的起始位置。这个“起始位置”指的是数据块是从文件的第几个字节开始的。由于数据块在同一个段中也是按照块号从小到大依次排布的,因此,一个数据块的起始位置可以由如下公式计算得出:起始位置 = 块号 * 块大小 % 段大小的上限,其中 % 表示求余操作。之所以需要求余操作,是因为块号是所有文件统一编号,而不是各个文件独立编号的。统一编号使得Greenplum的数据访问相对更为简单。

在确定了数据块所在的文件名和文件内起始位置之后,对于任意一个对数据块的访问操作,存储管理器就能够精确定位到需要让文件系统访问的是哪一个文件的哪一个部分了。

操作的转换

在完成了数据块的定位之后,存储管理器还需要进行数据访问操作的转换,即将对数据块的操作转换为对文件的操作。Greenplum对于数据块的操作主要有以下四种:

  • 分配一个新的数据块
  • 将某个数据块的数据读到内存中
  • 将内存中的数据写到某个数据块中
  • 删除数据块

存储管理器将这四种操作分别转换成对应的文件系统的操作,其中

  • 对于分配数据块的操作,存储管理器会在对应文件末尾追加写入一个空白的块以留出空间
  • 对于数据块的读写操作,存储管理器会使用文件系统提供的带偏移的文件读写操作,即pread和pwrite,从数据块在文件内的起始位置开始读写大小等于块大小的数据。
  • 对于删除数据块的操作,存储管理器会使用文件系统提供的ftruncate删除文件的一部分数据,或者使用unlink删除整个文件。

经过操作的转换,存储管理器就完成了从Greenplum的“块视图”到文件系统的“文件视图”的转换,这为Grenplum对磁盘上的数据的访问和管理提供了便利。

存储管理与数据加密

为了保证磁盘上的数据是加密的,我们将Greenplum的存储管理器进行了修改,在数据块读写的过程中增加了对数据块进行加解密的操作,当数据块从内存写入磁盘前对其进行加密,而在数据从磁盘读出后立即将其解密,从而满足客户对数据安全的需求。

关注微信公众号

VMware 中国研发中心