CN118861127A - 数据库的大对象排重处理方法、存储介质及设备 - Google Patents
数据库的大对象排重处理方法、存储介质及设备 Download PDFInfo
- Publication number
- CN118861127A CN118861127A CN202411048060.0A CN202411048060A CN118861127A CN 118861127 A CN118861127 A CN 118861127A CN 202411048060 A CN202411048060 A CN 202411048060A CN 118861127 A CN118861127 A CN 118861127A
- Authority
- CN
- China
- Prior art keywords
- storage
- slice
- deduplication
- database
- data
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
Classifications
-
- G—PHYSICS
- G06—COMPUTING OR CALCULATING; COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/24—Querying
- G06F16/245—Query processing
- G06F16/2458—Special types of queries, e.g. statistical queries, fuzzy queries or distributed queries
- G06F16/2462—Approximate or statistical queries
-
- G—PHYSICS
- G06—COMPUTING OR CALCULATING; COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/22—Indexing; Data structures therefor; Storage structures
- G06F16/2228—Indexing structures
- G06F16/2255—Hash tables
-
- G—PHYSICS
- G06—COMPUTING OR CALCULATING; COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/22—Indexing; Data structures therefor; Storage structures
- G06F16/2282—Tablespace storage structures; Management thereof
-
- G—PHYSICS
- G06—COMPUTING OR CALCULATING; COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/23—Updating
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Physics & Mathematics (AREA)
- Databases & Information Systems (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Data Mining & Analysis (AREA)
- Software Systems (AREA)
- Probability & Statistics with Applications (AREA)
- Fuzzy Systems (AREA)
- Mathematical Physics (AREA)
- Computational Linguistics (AREA)
- Information Retrieval, Db Structures And Fs Structures Therefor (AREA)
Abstract
本发明提供了一种数据库的大对象排重处理方法、存储介质及设备。其中,数据库的大对象排重处理方法包括:获取数据库的数据基表,数据基表具有至少一列大对象列;在大对象列或针对大对象列的列分区上,按照排重特征值为每个待排重对象进行分组统计;筛选重复出现的排重特征值,将重复出现的排重特征值及其出现次数写入数据库预创建的特征值排重统计表中;启动排重事务,利用排重事务对特征值排重统计表中的待排重对象进行排重处理,并更新待排重对象的引用标识和引用计数。本发明的优点是可以提高数据库中大对象的排重效率和排重准确性。
Description
技术领域
本发明涉及数据库技术领域,特别是涉及一种数据库的大对象排重处理方法、存储介质及设备。
背景技术
大对象(Large Object)是数据库中的一类特殊的数据类型,主要有二进制大对象(Binary Large Object,简称BLOB)和大文本对象(Character Large Object/NationalCharacter Large Object,简称CLOB/NCLOB)两大类。BLOB用来存储二进制大型对象数据,例如图像、音频文件、视频或其他非文本格式的数据;CLOB和NCLOB则用于存储大量的字符数据,适合于存放长文本如文章、报告或者XML文档等。这类数据单个数据项的体量上限很高,最高可达GB级甚至TB级,同时体量差异又很大,数据量小的也可以小到几个字节,甚至为空。
在现有的数据库系统中,大对象可能占用大量的存储空间,如果多个记录中存储了相同的大对象数据,那么这些数据就会在数据库中多次重复出现,导致存储空间的浪费和性能的下降,这使得大对象的排重成为数据库管理的重要任务之一。然而,传统的排重方法在处理大对象时,排重效率低下,容易出现排重错误的问题,因此还有待改善。
发明内容
本发明第一方面的一个目的是要提高数据库中大对象的排重效率和排重准确性。
本发明第一方面的另一个目的是要合理去除行内存储的小型对象,减少数据库的冗余数据。
本发明第一方面的又一个目的是要合理去除不同大型对象之间相同的存储切片。
特别地,根据本发明的第一方面,本发明提供了一种数据库的大对象排重处理方法,包括:
获取所述数据库的数据基表,所述数据基表具有至少一列大对象列;
在所述大对象列或针对所述大对象列的列分区上,按照排重特征值为每个待排重对象进行分组统计;
筛选重复出现的排重特征值,将重复出现的排重特征值及其出现次数写入所述数据库预创建的特征值排重统计表中;
启动排重事务,利用所述排重事务对所述特征值排重统计表中的待排重对象进行排重处理,并更新所述待排重对象的引用标识和引用计数。
可选地,所述待排重对象包括行外存储的小型对象,所述小型对象的数据大小小于等于预设阈值,利用所述排重事务对所述特征值排重统计表中的待排重对象进行排重处理,并更新所述待排重对象的引用标识和引用计数的步骤包括:
从所述特征值排重统计表中获取一组排重特征值相同的小型对象;
选取其中一个小型对象作为基准对象;
遍历其余的小型对象,并将其余的小型对象与所述基准对象进行比对;
若比对结果相同,将当前被比对的小型对象的引用标识更新为所述基准对象的标识,并增加所述基准对象的引用计数;
提交所述排重事务。
可选地,所述小型对象的对象记录中设置有引用标识字段,若所述小型对象存在引用关系,则所述引用标识字段中的值为被引用对象的标识,若所述小型对象不存在引用关系,则所述引用标识字段中的值被设置为空。
可选地,所述待排重对象包括行外存储的大型对象的存储切片,所述大型对象的数据大小大于预设阈值,并且被分割为多个存储切片进行存储,利用所述排重事务对所述特征值排重统计表中的待排重对象进行排重处理,并更新所述待排重对象的引用标识和引用计数的步骤包括:
从所述特征值排重统计表中获取一组排重特征值相同的存储切片;
选取其中一个存储切片作为基准切片;
遍历其余的存储切片,并将其余的存储切片与所述基准切片进行比对;
若比对结果相同,则将当前被比对的存储切片的引用标识更新为所述基准切片的标识,并增加所述基准切片的引用计数;
提交所述排重事务。
可选地,所述存储切片的切片记录中设置有引用标识字段,若所述存储切片在引用关系,则所述引用标识字段中的值为被引用切片的标识,若所述存储切片不存在引用关系,则所述引用标识字段中的值被设置为空。
可选地,在将其余的存储切片与所述基准切片进行比对的步骤之后,还包括:
若当前被比对的存储切片与所述基准切片的比对结果不同,则顺序选取下一个被比对的存储切片。可选地,将重复出现的排重特征值及其出现次数写入所述数据库预创建的特征值排重统计表中的步骤包括:
按照出现次数对重复出现的排重特征值进行排序;
将排序后的排重特征值及出现次数写入所述特征值排重统计表中。
可选地,所述特征值排重统计表基于所述数据库的创建指令创建,并具有唯一标识符。
根据本发明的第二方面,本发明提供了一种机器可读存储介质,其上存储有计算机程序,所述计算机程序被处理器执行时实现上述中任意一种数据库的大对象排重处理方法。
根据本发明的第二方面,本发明提供了一种计算机设备,包括存储器、处理器及存储在所述存储器上并在所述处理器上运行的计算机程序,并且所述处理器执行所述计算机程序时实现上述中任意一种数据库的大对象排重处理方法。
本发明的数据库的大对象排重处理方法,在处理具有至少一列大对象列的数据基表时,可以在大对象列或针对大对象列的列分区上,按照排重特征值为每个待排重对象进行分组统计,然后筛选重复出现的排重特征值,将重复出现的排重特征值及其出现次数写入数据库预创建的特征值排重统计表中,最后利用排重事务对特征值排重统计表中的待排重对象进行排重处理,通过直接更新待排重对象的引用标识和引用计数,可以确保数据库中的数据一致性和完整性,有利于提高数据库中大对象的排重效率,并降低排重错误的问题。
进一步地,本发明的数据库的大对象排重处理方法,在对小型对象进行排重的过程中,可以从排重特征值相同的小型对象中选取一个小型对象作为基准对象,然后将其余的小型对象与基准对象进行比对,若比对结果相同,将当前被比对的小型对象的引用标识更新为基准对象的标识,并增加基准对象的引用计数。这样后续可以整体删除重复的小型对象,不仅去除了小型对象的冗余数据,还提高了数据的质量。同时,通过更新引用标识和引用计数,维护了数据库的引用完整性,减少了数据冲突和不一致的可能性。
进一步地,本发明的数据库的大对象排重处理方法,大型对象被分割为多个存储切片进行存储,可以从排重特征值相同的存储切片中选取一个存储切片作为基准切片,然后将其余的存储切片与基准对象进行比对,若比对结果相同,将当前被比对的存储切片的引用标识更新为基准对象的标识,并增加基准对象的引用计数。这样,不仅去除了大型对象的冗余存储切片,还维护了大型对象的完整性。大量重复的存储切片都被关联到同一个大型对象上,可减少数据的重复存储和浪费。
根据下文结合附图对本发明具体实施例的详细描述,本领域技术人员将会更加明了本发明的上述以及其他目的、优点和特征。
附图说明
通过阅读下文优选实施方式的详细描述,各种其他的优点和益处对于本领域普通技术人员将变得清楚明了。附图仅用于示出优选实施方式的目的,而并不认为是对本发明的限制。而且在整个附图中,用相同的参考符号表示相同的部件。在附图中:
图1是根据本发明一个实施例的具有大对象列的数据表中表结构的示意图;
图2是根据本发明一个实施例的具有大对象列的数据表中系统表的示意图;
图3是根据本发明一个实施例的具有大对象列的数据表中一种可选大对象控制块的示意图;
图4是根据本发明一个实施例的具有大对象列的数据表中另一种可选大对象控制块的示意图;
图5是根据本发明一个实施例的具有大对象列的数据表中对象与存储切片表的示意图;
图6是根据本发明一个实施例的具有大对象列的数据表中存储切片互相引用的示意图;
图7是根据本发明一个实施例的临时大对象登记表的表结构的示意图;
图8是根据本发明一个实施例的数据库的大对象排重处理方法的流程图;
图9是根据本发明一个实施例的数据库的大对象排重处理方法中对小型对象进行排重的流程图;
图10是根据本发明一个实施例的数据库的大对象排重处理方法中对大型对象存储切片进行排重的流程图;
图11根据本发明一个实施例的计算机可读存储介质的示意图;
图12根据本发明一个实施例的计算机设备的示意图。
具体实施方式
本领域技术人员应当理解的是,下文所描述的实施例仅仅是本发明的一部分实施例,而不是本发明的全部实施例,该一部分实施例旨在用于解释本发明的技术原理,并非用于限制本发明的保护范围。基于本发明提供的实施例,本领域普通技术人员在没有付出创造性劳动的情况下所获得的其它所有实施例,仍应落入到本发明的保护范围之内。
需要说明的是,在流程图中表示或在此以其他方式描述的逻辑和/或步骤,例如,可以被认为是用于实现逻辑功能的可执行指令的定序列表,可以具体实现在任何计算机可读介质中,以供指令执行系统、装置或设备(如基于计算机的系统、包括处理器的系统或其他可以从指令执行系统、装置或设备取指令并执行指令的系统)使用,或结合这些指令执行系统、装置或设备而使用。
本实施例提供了一种数据库的大对象排重处理方法,在对本申请实施例进行详细说明之前,首先对本实施例中的数据库进行说明,以便更好地理解本实施例所依赖的数据库环境,该数据库环境不仅支持大对象的存储和操作,并且能够提供足够的灵活性来执行复杂的排重处理任务。
本实施例的数据库建立有数据基表,数据基表可以为用户基表,根据创建语句进行创建。数据基表具有至少一列大对象列,并且大对象列中的至少部分大对象数据项被分割为多个存储切片进行存储。大对象列中的数据项可以为BLOB、CLOB/NCLOB或者其他类型的可变长度的二进制数据、字符数据、外部数据等。数据基表可以为用户基表,根据创建语句进行创建。大对象列的数量可以根据业务需求进行设置,例如设置为一列、两列或者更多列。
在数据库预设的大对象模式中,每个大对象列或者每个大对象列的分区设置有存储管理表空间,每个存储管理表空间存储有对应大对象列或者大对象列分区的对象与存储切片表,对象与存储切片表用于存储存储切片的描述信息及数据。
在一个示例中,建立数据基表的步骤包括:获取创建指令并根据创建指令生成数据基表,为数据基表的每个大对象列或者每个大对象列的分区生成列对象标识符;以及为对象与存储切片表根据列对象标识符进行命名,得到存储表对象标识符。创建指令可以使用例如SQL(Structured Query Language),以一个简单的情况为例,假设用户建立了一个业务表user_biz_data,其中包含两个大对象列col_x和col_y,(以及其他常规数据列col_a和col_b)并且用户没有将大对象列设置分区,创建语句可以为:
其中KLOB可以为本实施例数据库定义的大对象数据类型,其包括KBLOB、KCLOB、KNCLOB三种专有基类型,分别对应传统的BLOB、CLOB、NCLOB类型。在本实施例的数据库中,可以利用既有的Domain类型机制,将KBLOB、KCLOB和KNCLOB设置为BLOB、CLOB和NCLOB背后的可替换实现之一。这意味着,当用户在创建表或定义列时指定使用BLOB、CLOB或NCLOB类型时,实际上可以选择使用本实施例的专有基类型KBLOB、KCLOB或KNCLOB作为替代。
在用户建立user_biz_data的业务表(基表),其中包含两个未作分区的大对象列col_x和col_y。本方案将自动为这两个大对象列生成UUID(Universally UniqueIdentifier,列对象标识符,或称为通用唯一标识码)。
数据库预设的大对象模式可以为在数据库中创建的专用的模式(Schema),在一些实施例中,该大对象模式可以命名为sys_klob_schema,其定义了数据库的组织和结构。用户基表中的每一个大对象列及其列分区,数据库系统均可在上述Schema中建立一组表和索引来存储和管理大对象。对象本身将被切分为小的存储切片(Chunk)保存在这些表中。需要说明的是,大对象列可以根据需要进行分区,大对象列分区可被认为大对象列的一部分,每个大对象列分区具有一个对象与存储切片表。在一些实施例中,在不需要分区的情况下,每个大对象列具有一个对象与存储切片表。
例如sys_klob_sch Schema可以为两个未作分区的大对象列col_x和col_y分别设置配套的对象与存储切片表,分别命名为tab_colx_uuid,tab_coly_uuid。对象与存储切片表tab_colx_uuid,tab_coly_uuid分别以随机产生的UUID生成全局唯一标识。全局唯一标识的格式可以为前缀(例如上述tab_为前缀)与UUID的组合,以满足数据库对象的名称的命名要求。对象与存储切片表中的对象记录为对象的首条存储切片记录。在本实施例中,UUID用于标识一个大对象列或大对象列分区,数据表、索引、序列可以分别通过各自的前缀与UUID组合生成各自的名称。
数据库系统表中预设的大对象列元数据表中记录对象与存储切片表的描述信息。为管理大对象,数据库系统建立了一组专用的系统表,用于存储用户表中的大对象列与这些数据库对象之间的对应关系以及大对象列独有的存储参数。大对象列元数据表可被命名为sys_klob_column,为数据库系统专为大对象配置的一组系统表中的一个。
大对象列元数据表sys_klob_column还可以记录有基表的对象标识符(用于标识数据基表,可命名为rel_oid,在查找数据基表的元数据时使用)、大对象列的标识(可为大对象列在基表中的列编号,用于定位大对象列的位置,可命名为attr_no,与rel_oid配合可以唯一确定数据库的一个表列,在查找表列元数据时使用)。并且大对象列元数据表中记录的对象与存储切片表的描述信息包括存储表对象标识符(可命名为tab_oid,即上述对象与存储切片表的OID,在不做分区的情况下,每个大对象列具有一个对应的tab_oid,如果大对象列进行了分区,则每个大对象列分区具有一个对应的tab_oid)。
在数据基表中使用大对象控制块替代对应大对象数据项的位置,大对象控制块至少记录有大对象数据项的描述信息和数据项对象标识符。也即在最终的数据基表中,大对象数据项的位置为一个控制块,该控制块可以根据大对象数据的大小设置为不同的数据构造,至少包括的内容包括大对象数据项的描述信息和数据项对象标识符。其中大对象数据项的描述信息用于描述大对象数据项的类型、各种标志位、版本等。数据项对象标识符为该对象的全局唯一固定标识,是一个UUID类型的标识,在对象创建的时候随机生成,在对象的整个生命周期中保持不变。
数据库系统专为大对象配置的一组系统表还可以包括:存储参数历史表(可命名为sys_klob_store_params)、排重任务历史表(可命名为sys_klob_dedup_tasks),此外数据库系统表中的系统元数据表(可命名为pg_attribute)也记录有大对象列与其他常规数据类型一致的其他基本属性。
在一些实施例中,在数据库系统表中预设的存储参数历史表sys_klob_store_params中记录对象与存储切片表的存储表对象标识符tab_oid以及存储参数,这些存储参数可以包括存储参数版本号、存储选项、加密参数、任务标识等。存储参数历史表sys_klob_store_params的数据可以在大对象的压缩、加密等存储选项修改或者需要重新已有数据时使用。
在一些实施例中,在数据库系统表中预设的排重任务历史表sys_klob_dedup_tasks中记录对象与存储切片表的存储表对象标识符tab_oid以及排重任务信息,其中排重任务信息包括排重任务序号、排重任务标识,用于确定排重任务的执行状态。
数据库系统表的原有系统表也存储了大对象存储所用的表和索引本身的元数据,这与其他普通数据类型元数据记录基本一致,在此不做赘述。
每个存储管理表空间还存储有对象与存储切片表的主键索引。主键索引用于在对象与存储切片表中查找大对象数据项和/或存储切片;以及大对象列元数据表还记录有主键索引的信息。主键索引一般可以使用hash索引的方式。通过建立索引提高查找效率。
对象与存储切片表中还设置有引用列。引用列用于记录存储切片与其他存储切片的引用关系和/或大对象数据项与其他大对象数据项的引用关系。利用这些引用关系,可以避免重复存储相同大对象数据项和/或存储切片,节省存储空间资源。进一步地,每个存储管理表空间还可以存储有对象与存储切片表的引用列索引。引用列索引用于在对象与存储切片表查询引用关系;以及大对象列元数据表还记录有引用列索引的信息。通过建立引用列索引提高查找引用关系存储效率。
由于修改存储选项时重写数据和大对象排重均需要耗费大量的执行时间。为了尽量减小对用户日常业务的影响,上述操作一般在后台渐进式地进行。为了保证上述操作的正确执行,在一些实施例中,可以为对象与存储切片表创建数据重写任务序列(store_seq_<col/part uuid>)以及排重任务序列(dedup_seq_<col/part uuid>)。数据重写任务序列用于记录对象与存储切片表的重写过程,排重任务序列用于记录对象与存储切片表的排重过程,从而利用这两个序列分别跟踪修改存储选项时重写数据和大对象排重的任务。
在本实施例中,为了实现大对象的高效存储和管理,特别是在处理TB级大对象时,采用了基于表和索引的存储环境设计。这种方法避免了对数据库底层存储实现机制进行复杂的改造,而是通过在数据库中预设的大对象模式中为每个大对象列或每个大对象列的分区设置存储管理表空间。
仍以建立业务表user_biz_data,包含两个大对象列col_x和col_y为例进行介绍。图1是根据本发明一个实施例的具有大对象列的数据表中表结构的示意图。
在用户建立数据基表(业务表)user_biz_data时,数据库系统为其包含的col_x和col_y大对象列分别生成UUID(colx_uuid和coly_uuid)。生成数据库对象时,则在相应的UUID前加前缀,一方面是因为有些UUID文本形式首字符是数字,不符合数据库对象命名规则;另一方面是因为用于存储一个大对象列或列分区的是一组数据库对象,包括表、索引、Sequence(序列)等,其中,Sequence(序列)在数据库中的确是用来生成自增序列值的对象,通常用于为表中的记录提供唯一的标识符。在本方案中,为重写任务和排重任务分别生成序列号,主要目的是标识这些任务的执行顺序。由于这些序列号是在特定的列或列分区范围内生成的,并且考虑到这两类任务的执行次数通常不会太多,因此序列值回绕(即序列值达到上限后重新开始)的可能性确实很小。这确保了在这些范围内,序列号具有唯一性。另外,这些序列号并不是像UUID的全局唯一标识。UUID通常用于生成全局唯一的标识符,无论在哪里生成,UUID的冲突概率都非常低。而序列生成的唯一标识符只在特定的上下文或范围内有效,超出这个范围可能就不再唯一。如果col_x和col_y进行了分区,则每个分区具有各自的UUID。此外常规数据类型列col_a和col_b按照原有的存储逻辑进行存储。
整个数据库的结构包括:系统元数据模式pg_catalog schema、应用程序模式schema、大对象模式sys_klob_schema,其中系统元数据模式pg_catalog schema为数据库元数据,应用程序模式schema以及大对象模式sys_klob_schema主要为用户业务数据。
在系统表中,关系属性表(或称为系统元数据表,可命名为pg_attribute)用于并保存数据库一般普通数据类型和数据表的通用基本属性(包括大对象列与其他常规数据类型一致的基本属性)、大对象列元数据表sys_klob_column、存储参数历史表sys_klob_store_params、排重任务历史表sys_klob_dedup_tasks作为大数据的特有存储属性。大对象列元数据表sys_klob_column记录所创建的表和索引的Oid,以及大对象列特有的存储属性。表中的基表OID(rel_oid)和大对象列编号(attr_no)字段用于与数据库中原有的系统表相关联,表明这行数据记录的是哪个数据基表中的哪个列的属性。
为了跟踪排重任务以及修改大对象列存储选项时重写已有数据这些长时间任务的执行状态,并确保能从中断的任务中恢复,存储参数历史表sys_klob_store_params、排重任务历史表sys_klob_dedup_tasks用于记录存储参数和排重任务参数的历史。
大对象模式sys_klob_schema中包括col_x数据存储表空间、col_x数据存储表空间,如果大对象列具有分区,则每个分区具有各自的数据存储表空间。以col_x数据存储表空间为例,除了col_x对象与存储切片表进行数据存储外,还为对象与存储切片表的主键和引用列分别建立索引(可为hash索引)idx_<colx_uuid>、ref_<colx_uuid>。
col_x对象与存储切片表可以用tab_前缀加colx_uuid为名称,用于保存对象记录与存储切片记录,两者都以随机产生的UUID为全局唯一标识。对象记录本质上就是对象的第一条存储切片(Chunk)记录(Chunk)。tab_<colx_uuid>主键索引idx_<colx_uuid>可用于快速查找对象或存储切片Chunk。在支持对象排重的情况下,允许对象引用其他对象、Chunk引用其他Chunk,tab_<colx_uuid>引用列索引ref_<colx_uuid>可以用于加快引用关系的查询操作。
在基表user_biz_data中,大对象数据项的位置将由大对象控制块代替,其中会包含大对象数据项的实际存储位置。在一些实施例中,如果大对象数据项数据量很小时,为优化性能,也可以根据用户选择,将小数据量的数据项直接保存在大对象控制块中。
图2是根据本发明一个实施例的具有大对象列的数据表中系统表的示意图。与大对象相列关的系统表主要有4个:大对象列元数据表sys_klob_column、关系属性表pg_attribute、存储参数历史表sys_klob_store_params、大对象列排重任务历史表sys_klob_dedup_tasks。
关系属性表pg_attribute用于记录表列元数据,与其他常规数据类型的列一样,大对象列的基本属性也同样保存在这个表中。其中数据基表OID rel_oid和大对象列在基表中的列编号attr_no可以定位数据基表中的大对象列位置。
大对象列元数据表sys_klob_column用于保存大对象列及其列分区的特有属性,通过数据基表OID rel_oid和大对象列在基表中的列编号attr_no两个字段与关系属性表pg_attribute关联。在大对象列不分区的情况下,关系属性表pg_attribute中的每条记录在大对象列元数据表sys_klob_column中有一条对应的记录。在大对象列分区的情况下,每个分区也会在大对象列元数据表sys_klob_column中有一条对应的记录。
具体而言,大对象列元数据表sys_klob_column可以包括以下属性:
数据基表OID rel_oid,在查找基表相关的元数据时使用;
大对象列在基表中的列编号attr_no,与rel_oid配合可以确定唯一确定数据库中的一个表列,在查找表列元数据时使用;
对象与存储切片表OID tab_oid,用于存储大对象及其存储切片表的OID,在大对象列不分区的情况下,每个大对象列对应这样一个表,在大对象列分区的情况下,每个分区也会对应这样一个表;
主键索引OID idx_<colx_uuid>,对象与存储切片表主键列unit_id的索引(可为Hash索引)的OID,在大对象列不分区的情况下,每个大对象列对应于一个主键索引,在大对象列分区的情况下,则每个分区也会对应这样一个索引;
引用列索引OID ref_<colx_uuid>:对象与存储切片表应用对象/存储切片标识列ref_id的索引(Hash索引)的OID,在大对象列不分区的情况下,每个大对象列对应这样一个索引,在大对象列分区的情况下,则每个分区也会对应这样一个索引;
所属表空间OID tbs_oid,对象与存储切片表及其索引所在的表空间的OID;大对象列可以与其他数据放在不同的表空间,也可以将每个列分区放在不同的表空间,在用户需要的情况下,可以为每个大对象列(未分区情况下)或者大对象列分区(分区的情况下)指定一个独立的表空间;
存储参数版本号序列OID store_seq_oid,为大对象列或大对象列分区存储参数版本号序列store_seq_<col/part uuid>的OID,该序列store_seq_生成的整数用来标识大对象存储参数的版本及其先后次序;每个大对象列(未分区情况下)或者大对象列分区(分区的情况下)对应这样一个序列对象;
排重任务序号序列OID dedup_seq_oid,为大对象列或大对象列分区排重任务序号序列dedup_seq_<col/part uuid>的OID,排重任务序列dedup_seq生成的整数用来标识大对象排重任务参数的版本及其先后次序,每个大对象列(未分区情况下)或者大对象列分区(分区的情况下)对应这样一个序列对象;
存储切片chunk物理大小chunk_size,用于记录大对象的存储切片Chunk的大小,可以使用字节数为单位,Chunk的大小不受底层存储页大小的限制,可以在2K到1G之间选择,每个大对象列(未分区情况下)或者大对象列分区(分区的情况下)单独设置Chunk大小,从而满足不同大数据列的要求;
当前存储选项lob flags,为当前存储选项,这可以一个32位的位串,其中包含了存储位置、压缩、加密等方面的存储选项,存储参数历史表sys_klob_store_params同样完整记录了每个版本的存储选项,为了加速某些操作,当前存储选项lob flags保留了一个冗余字段,进行了重复的存储;
当前存储参数版本号store ver,是由大对象列/分区存储参数版本号序列生成的最新序号,用来与tab_oid共同标识当前存储参数对应于系统表sys_klob_store_params中的哪条记录;
dedup_ord:当前排重任务号,它是由大对象列或大对象列分区排重任务序号序列生成的最新序号,用来与tab_oid共同标识当前排重任务对应于大对象列排重任务历史表sys_klob_dedup_tasks中的哪条记录;
分区策略partstrat,用于记录分区策略,分区策略可以包括h哈希分区,l列表分区,r范围分区表,该属性仅在对象与存储切片分区表对应的行中有值;
分区键中的列数partnatts;仅在对象与Chunk分区表对应的行中有值;
默认分区partdefid:这个分区表的默认分区的pg_class项的OID,如果这个分区表没有默认分区则为零。仅在对象与Chunk分区表对应的行中有值;
分区键列号向量partattrs,是一个长度为partnatts值的数组,指示哪些表列是分区键的组成部分。例如,值1 3表示第一个和第三个表列组成了分区键。这个数组中的零表示对应的分区键列是一个表达式而不是简单的列引用,仅在对象与存储切片分区表对应的行中有;
分区键操作符类OID向量partclass,对于分区键中的每一个列,这个域包含要使用的操作符类的OID,仅在对象与存储切片分区表对应的行中有值;
分区键列排序规则OID向量partcollation,对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列不是一种可排序数据类型则对应值为零,仅在对象与存储切片分区表对应的行中有值。
分区键列表达式树partexprs,非简单列引用的分区键列的表达式树(以nodeToString()的表达方式),这是一个列表,partattrs中每一个零项都对应有一个元素。如果所有分区键列都是简单列引用,则这个域为空。仅在对象与Chunk分区表对应的行中有值;
单个分区边界的内部表达relpartbound,为分区边界的内部表达,仅在列分区对应的行中有值。
大对象列特有存储参数历史表sys_klob_store_params,用于保存数据库库中每个大对象列特有存储参数的所有历史版本,通过tab_oid列与sys_klob_column表中的记录相关联。在修改大对象的压缩、加密等存储选项需要重写已有的数据时,会用到这些历史数据。
具体而言,大对象列特有存储参数历史表sys_klob_store_params可以包括以下属性:
对象与存储切片表OID tab_oid;
存储参数版本号store_ver,由前述tab_oid为store_seq_<col/part uuid>的序列产生;
存储选项lob flags,其可以用于标识行外存储方式(包括表存储方式、文件存储方式、OSS(Object Storage Service,对象存储服务)等)、是否可用行内存储(可用或不可用)、是否加密(加密或不加密)、压缩级别(不压缩、低等级压缩、中等级压缩、高等级压缩)、加密算法标识(加密算法类型),上述标识的内容分别占用存储选项lob flags的一个或多个标识位,在一些实施例中,存储选项lob flags可以为一个32位的位串,由以上标识位拼接而成。
密钥过期UTC时间key_expr,用来加密大对象列的密钥的过期时间,可以采用UTC时间(Coordinated Universal Time,协调世界时);
密钥enc_key,为加密大对象列的密钥,以密文形式存储,用上级密钥加密;
加密&压缩任务标识enc_task_id,为大对象列加密与压缩任务的标识;可采用一个UUID形式的标识,在创建大对象列加密与压缩任务时随机生成,并在内存中的一个哈希表中登记;如果该表中记录的标识在当前内存中的加密与压缩任务登记表里找不到,则代表执行这个加密与压缩任务的进程已经退出。
大对象列特有存储参数历史表sys_klob_store_params中的tab_oid和store_ver字段合起来可以唯一确定库中一个大对象列或大对象列分区的一个存储参数版本。
大对象列排重任务历史表sys_klob_dedup_tasks,保存数据库中每个大对象列每一次排重任务的参数,通过tab_oid列与sys_klob_column表中的记录相关联,用于判定排重任务的执行状态。
具体而言,大对象列排重任务历史表sys_klob_dedup_tasks可以包括以下属性:
对象与存储切片表OID tab_oid,含义同以上其他系统表的tab_oid属性;
排重任务序号dedup_ord,由对象与存储切片表OID为大对象列或大对象列分区排重任务序号序列dedup_seq_<col/part uuid>的序列产生;
排重任务进程组唯一标识dedup_task_id,是一个UUID形式的标识,在创建大对象列排重任务时随机生成,并在内存中的一个哈希表中登记;如果该表中记录的标识在当前内存中的排重任务登记表里找不到,则代表执行这个排重任务的进程已经退出。
上述建立的专用的系统表记录对象与存储切片表的描述信息。这些专用的系统表用于存储用户表中的大对象列与上述用于存储大对象的数据库对象之间的对应关系以及大对象列独有的存储参数,使得数据管理更加高效,符合大对象的存储管理特点。
本实施例的方案中,在数据基表中使用大对象控制块替代对应大对象数据项的位置。大对象控制块可以包括行内大对象存储结构和行外大对象存储结构两种。
图3是根据本发明一个实施例的具有大对象列的数据表中一种可选大对象控制块的示意图。图3示出了行外大对象存储结构。大对象控制块varattrib_4b包括文件头varattrib_4b.va_header,以及数据varattrib_4b.va_data。其中数据varattrib_4b.va_data中包括大对象数据项的描述信息(LOB对象控制块描述字)和数据项对象标识符(LOB对象固定唯一标识)。
大对象数据项的描述信息可以描述控制块类型(行内或者行外)、行内是否有数据等标志位、控制块格式版本号等。上述内容可以分别占用描述信息的一个或多个标识位,在一些实施例中,大对象数据项的描述信息可以为一个32位的位串,由以上描述对应的标识位拼接而成。
数据项对象标识符是一个UUID类型的标识,在对象创建的时候随机生成,在对象的整个生命周期中保持不变。
行外大对象存储结构只包含其中的LOB对象控制块描述字和LOB对象固定唯一标识,这两个字段在对象的整个生命周期中保持不变,避免了在更新大对象内容时更新数据基表。
图4是根据本发明一个实施例的具有大对象列的数据表中另一种可选大对象控制块的示意图。图4示出了行内大对象存储结构。
行内大对象存储结构针对于数据量较小(例如32k之内)的大对象数据项,其在控制块内存储大对象数据(大对象数据的最大尺寸在设定范围内,例如最大为32k)。在数据varattrib_4b.va_data中除了LOB对象控制块描述字和LOB对象固定唯一标识还进一步包括:LOB对象存储选项、LOB数据。LOB对象存储选项可为一个位串,可以采用与系统表sys_klob_column和sys_klob_store_params中的lob_flags字段相同的格式。LOB数据包含大对象的数据。
通过区分行内大对象存储结构和行外大对象存储结构,满足了不同数据大小的大对象数据项的存储要求,仅将超过一定数据大小(例如32k)的数据存储在行外。
对象与存储切片表是实际存储大对象数据的表。在数据库运行期间,每个大对象列或列分区配套创建对象与存储切片表。本实施例对对象与存储切片表进行了优化改进,与现有PostgreSQL的明显不同,具有明显的优点。
在PostgreSQL的数据库方案中,大对象存储表pg_largeobject是个系统表,只用来存储存储切片数据,包含3个字段:loid、pageno、data。其中loid为大对象唯一标识,类型为OID(4字节无符号整数),在数据库范围内具有唯一性。pageno标识该chunk数据在大对象中的页号(从0开始),类型为4字节整数。data为Chunk数据,体量不超过数据库存储页大小的1/4,对于常见的8K存储页设置,其大小不超过2K。
在PostgreSQL的数据库中,全库大对象总容量受到单表数据量上限的限制,全库对象总数受到OID取值范围的限制。如果用户业务表中采用了int8等取值范围更大的数据类型,则大对象标识的数量可能不够用。而且,这种OID类型的标识只能确保在一个数据库内的唯一性,如果要将大对象导入其他数据库中,则必须重新分配标识,不利于对大对象的跟踪。大数据对象的每一行保存一个大对象的一个页的数据,从对象内部的字节偏移量(pageno*LOBLKSIZE)开始。允许稀疏存储,页面可能丢失,并且可能比LOBLKSIZE字节短(即便不是最后一页)。一个大对象中丢失的区域会被读出为0。也就是说,这种方案并不支持在大对象中间进行插入或删除操作,只支持内容的追加和替换,其行为模式不同于一般理解的编辑操作。
图5是根据本发明一个实施例的具有大对象列的数据表中对象与存储切片表的示意图。本实施例的方案中,对象与存储切片表存储的记录有两种类型。第一种类型为对象记录,它包含了对象元数据和前32K(例举,可以设置为其他数值)以内的数据,用于加速部分函数的操作。对于超过32K(例举,可以设置为其他数值)大小的对象还包含存储切片索引块,用于查找用户读写的数据位于哪些存储切片内。第二种类型是存储切片记录,包含了存储切片元数据和32K以上部分的数据。一个大体量(32K以上)的对象会由一条对象记录和若干条存储切片记录组成。对于每个大对象列或列分区,存储切片的大小可以在1G以内自由选择。如果列中对象的平均大小较小,则适合采用较小的存储切片数据尺寸;如果列中对象的平均大小很大,则适合采用较大的存储切片尺寸。例如对于TB级的大对象,可以使用最大的存储切片尺寸(1GB)。
具体而言,对象与存储切片表可以包括以下属性:对象固定唯一标识uint_id、系统内部使用的分区键part_key、存储参数版本号store_ver、引用对象标识ref_id、引用对象计数ref_count、对象排重特征值dedup_feat、对象前32k以内的数据prefetch、附加数据字段ext_data。
对象固定唯一标识uint_id,为一个UUID型的唯一标识,对于对象记录而言这是对象标识,对于存储切片而言这是存储切片标识。UUID型的标识可以认为在任何情况下都具有唯一性,即使将一个对象导入到其他数据库中,这种标识也可以保持不变,不会发生冲突。
part_key为系统内部使用的分区键,可为有符号整数。当用户选择用基表中的其他列作为大对象列的分区键时,用户所做的原始分区设置将被翻译成一种内部的列表分区形式,该字段包含内部使用的分区键;当用户选择基于对象/存储切片标识进行Hash分区时,此字段可为NULL。
store_ver是对象的存储参数版本号,在存储切片记录中则为NULL,该字段也可以用来区分对象记录和存储切片记录;
ref_id,对于对象记录而言,如果有值则为被引用对象的标识(UUID),代表该对象与被引用对象完全相同;对于存储切片记录,该字段如果有值则为被引用存储切片的标识(UUID),代表该存储切片与另一个存储切片完全相同。在该字段不为NULL的情况下,该记录的prefetch和ext_data字段都为NULL。另外,只有当一个对象与另一个对象完全相同时,两者才可能存在引用关系。如果只是部分存储切片相同,则只存在存储切片之间的引用关系,不存在对象间的引用关系。
ref_count,为在对象记录中代表本对象被其他对象的引用次数;在存储切片记录中代表该存储切片被其他存储切片的引用次数。如果对象或存储切片未被引用,则该字段值为0。
dedup_feat在存储切片记录中是存储切片本身的排重特征值,在对象记录中则是整个对象的排重特征值。这可是一个二进制数据块,其长度由排重特征值算法决定。若从未在对应的列或列分区上启用过排重功能,则该字段为NULL(初始状态)。对于行外存储的小型对象,如果DML操作改变了对象内容,那么在DML操作发生时:1、如果当前未启用排重,则将该字段置为NULL;2、如果当前已启用排重,则生成新的对象特征值,并填入该字段;对于行外存储的大型对象,如果DML操作改变了其下属切片内容,则在DML操作发生时:1、如果当前未启用排重,则将该字段置为NULL;2、如果当前已启用排重,则生成新的切片特征值,并填入该字段。排重任务执行时,会为尚无特征值的小型对象以及大型对象的切片生成特征值,并填入该字段。
prefetch,在对象记录中为对象前32K以内的数据,按照对象存储参数的设定进行存储,可能会压缩和加密;在存储切片记录中该字段总是为NULL。
ext_data,在对象记录中,该附加数据字段包含存储切片索引块,记录了对象所有存储切片的排列顺序、原始数据逻辑长度和唯一标识。这里所说的逻辑长度,是指按原始数据的单位计算的长度。对于BLOB单位是字节,对于CLOB/NCLOB而言,单位是字符。在存储切片记录中,该字段包含大对象32K以上部分的数据。无论是存储切片索引块还是存储切片数据,都会按照对象存储参数的设定进行存储,可能会压缩和加密。例如,在某个大对象的首个存储切片的记录中,该附加数据字段可以用来存储该大对象对应的所有存储切片的索引记录,也即存储切片索引块,在该大对象除去首个存储切片的其他存储切片中,该附加数据字段用于存储对应存储切片的数据。也即只有大对象的首个存储切片在附加数据字段用于存储存储切片索引块,其自身的数据存储于prefetch字段,其余存储切片在ext_data这一附加数据字段则会存储自身对应的数据内容。无论是存储切片索引块还是存储切片数据,都会按照对象存储参数的设定进行存储,可能会压缩和加密。在上述存储结构下,本方案的存储切片内容修改方式与现有技术中PostgreSQL数据库存在明显不同,可以高效地支持在大对象中间进行插入和删除操作,并采用与字符串插入、删除操作相同的语义。
在对象记录(即对象的第一个数据行)中,prefetch字段用来存对象的第一个切片,即对象头部有限长度的数据,这部分数据在有些场景下可以像常规字段一样直接读写,无需通过文件式的API;它的长度上限也低,不像后续切片可以设置得很大;ext_data字段用来存储切片索引块。在切片记录(即第二个及其后的切片所在的数据行)中,prefetch字段用不到,置NULL;ext_data字段用来存储切片的数据内容。
通过上述数据库的设计方式,可以在大对象被拆分为多个存储切片的情况下,首先数据基表(也即user_biz_data表)中确定大对象自身的全局唯一标识,并根据大对象全局唯一标识在对象与存储切片表中找到其所在的首个存储切片(大对象全局唯一标识便是首个存储切片的切片唯一标识);随后通过首个存储切片中记录的存储切片索引块确定查找的目标数据所在的目标存储切片的全局唯一标识,接着通过目标存储切片的全局唯一标识在对象与存储切片表中找到目标存储切片,最终在其ext_data列获取目标存储切片的具体数据。
除此之外,想要修改目标存储切片的数据也可以按照上述方法找到对应的目标存储切片并执行操作,随后同步更新首个存储切片的附加数据字段中存储切片索引块的内容。
存储切片的索引块是一个二进制数据块,包含了一个对象所有存储切片的定位信息,其中依次包含如下字段:存储切片索引库格式描述字、存储切片数量、存储切片长度数组、存储切片标识数组。
存储切片索引库格式描述字可为有符号整数,作为一个位串使用,其部分位(例如低8位)为存储切片索引块格式版本号,其他位可以作为保留。
存储切片总数,即后边存储切片数组的长度,类型为有符号整数。如果该字段为0,则代表不包含任何存储切片。
存储切片长度数组,长度为前边所说的存储切片总数,数组元素类型为有符号整数,按照存储切片在对象中的先后顺序排列。
存储切片标识数组,长度为存储切片总数,数组元素类型为UUID数,也按照存储切片在对象中的先后顺序排列。
从图5中可以看到,在存储切片索引块中,存储切片的元数据(长度和标识)不是按行存储,而是按列存储,即:先将所有的存储切片长度值连续存储,再将所有的存储切片标识值连续存储。由于大对象通常较少更新,其存储切片的长度值会存在很多重复值,这样做有助于提高压缩率。
在本实施例的方案中,存储切片的元数据(标识、长度等)与数据是分开存储的,存储切片的实际长度是可变的,存储切片在大对象中的顺序是由存储切片索引块记录的。因此,在大对象中间插入或删除数据时,只有插入或删除的数据涉及的存储切片需要重写,其他存储切片不动,大大减少了更新时需要重写的数据量,提升了性能。
相比较地,而PostgreSQL数据库采用定长的存储切片,存储切片元数据与数据保存在一条记录中,通过存储切片序号来表示其在对象中的位置,如果从中间插入或删除数据,就需要重写插入/删除点后的所有存储切片,性能远不如本实施例的方案。
通过加入引用对象/存储切片uint_id、、ref_id、ref_count,本实施例的方案的大对象存储支持排重操作,也即对重复的对象或存储切片进行简化。图6是根据本发明一个实施例的具有大对象列的数据表中存储切片互相引用的示意图。例如对于某一大对象数据项A的部分存储切片与另一大对象数据项B中存储切片相同,这些存储切片相对独立,具有唯一标识,但不存放实际数据,而保存对象数据项B的存储切片的标识。例如在存储切片102与存储切片201相同,存储切片104、存储切片105与存储切片204相同的情况下,存储切片102内存储存储切片201的标识,存储切片104、存储切片105分别保存存储切片204的标识。存储切片201、存储切片204分别记录引用计数。
相类似的,如果某一大对象数据项D与另一大对象数据项C相同,则大对象数据项D可以存储大对象数据项C的标识,而不必存储数据。大对象数据项C记录引用计数。当然,这仅是针对体量小于等于32K的大对象数据项而言的,对于更大的大对象数据项,由于判断其整体上是否重复的代价过高,完全匹配的概率较低,只在存储切片的粒度上排重才是更好的选择。
上述记录的引用计数可以在数据修改时,执行DML时避免数据出现错误。
使用上述存储结构中,大对象的存储形式可以分为三种:行内存储的小型对象、行外存储的小型对象、行外存储的大型对象。
其中,行内存储的小型对象的元数据和数据本体都存储在数据基表行内,其形式为一个行内控制块。行内存储的小型对象结构紧凑、占用空间小。
行外存储的小型对象的部分元数据存储在数据基表行内,其余元数据和数据本体存储在对象与存储切片表中,其形式为一个行外对象控制块和一条对象记录。行外存储的小型对象除了控制块和对象数据本身外,还包含支持分区、排重和渐进后台任务等其他特性的字段。
行外存储的大型对象的部分元数据存储在行内,其余元数据、前32K数据和存储切片索引块存储在一条对象记录中,32K以上的数据则存储在一组存储切片记录中。行外存储的大型对象包括一条对象记录和若干条存储切片记录组成。对象记录和若干条存储切片记录存储在同一个表中,使用同一种主键列。对象记录作为访问大对象数据的入口。
值得说明的是,虽然行外存储的大型对象也具有也具有上述小型对象的支持分区、排重和渐进后台任务等其他特性的字段,但区别在于,1、在大型对象的对象记录中,ref_id、ref_count、dedup_feat是用不到的,因为不对大型对象作整体排重,只做切片级排重;2、在大型对象的切片记录中:store_ver是用不到的,因为单个对象的所有内容采用统一的存储参数,比较符合用户普遍的预期;prefetch也用不到,因为用户读写大对象内指定的片段时,不需要快速获取切片头部的一小片数据。
另外,在数据库运行过程中,有时需要创建一些临时大对象,临时大对象并不属于任何一个用户业务表(数据基表)。为支持这种应用场景,在会话(Session)启动后,本实施例的方案将在临时表空间中创建临时大对象登记表和临时大对象存储表来存储临时大对象。
临时大对象登记表,以tmp_前缀加随机产生的UUID为表名,用于组织和查找活动(Session)范围内所有的临时大对象,不进行分区。临时大对象存储表是为临时大对象登记表中的3个大对象列配套创建的对象与存储切片表,不进行分区。
图7是根据本发明一个实施例的临时大对象登记表的表结构的示意图,如图7所示,临时大对象登记表中的字段包括:
lob_id:临时大对象的标识符,类型为UUID;
lob_type:大对象类型OID,为BLOB、CLOB、NCLOB三种类型的OID之一;
blob_val:BLOB列,若临时大对象为BLOB类型,则此列有值,否则为NULL;
clob_val:CLOB列,若临时大对象为BLOB类型,则此列有值,否则为NULL;
nclob_val:NCLOB列,若临时大对象为BLOB类型,则此列有值,否则为NULL。
在本实施例的方案中,临时大对象登记表充当了用户业务表(数据基表)的角色,临时大对象的处理逻辑与持久化大对象基本相同。临时大对象的生命周期由绑定它的变量的生命周期决定。最迟在活动(Session)结束时,临时大对象存储表会被删除,因此该活动(Session)中的所有临时大对象也会被删除。
前文提到,在现有的数据库系统中,大对象可能占用大量的存储空间,如果多个记录中存储了相同的大对象数据,那么这些数据就会在数据库中多次重复出现,导致存储空间的浪费和性能的下降。因此,大对象的排重成为数据库管理的重要任务之一。
图8是根据本发明一个实施例的数据库的大对象排重处理方法的流程图,如图8所述,该数据库的大对象排重处理方法至少包括以下步骤S801至步骤S804。
步骤S801,获取数据库的数据基表,数据基表具有至少一列大对象列。
步骤S802,在大对象列或针对大对象列的列分区上,按照排重特征值为每个待排重对象进行分组统计。
步骤S803,筛选重复出现的排重特征值,将重复出现的排重特征值及其出现次数写入数据库预创建的特征值排重统计表中。
步骤S804,启动排重事务,利用排重事务对特征值排重统计表中的待排重对象进行排重处理,并更新待排重对象的引用标识和引用计数。
上述实施例的数据库的大对象排重处理方法,在处理具有至少一列大对象列的数据基表时,可以在大对象列或针对大对象列的列分区上,按照排重特征值为每个待排重对象进行分组统计,然后筛选重复出现的排重特征值,将重复出现的排重特征值及其出现次数写入数据库预创建的特征值排重统计表中,最后利用排重事务对特征值排重统计表中的待排重对象进行排重处理,通过直接更新待排重对象的引用标识和引用计数,可以确保数据库中的数据一致性和完整性,有利于提高数据库中大对象的排重效率,并降低排重错误的问题。
在数据基表的大对象列/列分区中,大对象数据项的对象类型可以包括行内存储的小型对象、行外存储的小型对象以及行外存储的大型对象,并且行外存储的大型对象被分割为多个存储切片进行存储。
为了更好地管理数据库中的大对象数据,可以设定一个预设阈值来区分行外存储的小型对象和大型对象。例如,可以将数据大小小于等于32K的行外对象定义为小型对象,而将大于32K的对象定义为大型对象。当然,这个预设阈值并不是固定的,可以根据实际需求进行调整。
对于行内存储的小型对象,由于它们的大小通常较小,当读取包含这些对象的数据行时,这些对象会被完整地加载到内存中。因此,对这类对象进行排重处理不仅没有必要,还可能浪费系统资源。考虑到这一点,本实施例中不对行内存储的小型对象进行排重处理。
然而,对于行外对象,排重处理就显得尤为重要。这些对象可能占用大量的存储空间,并且其中可能包含重复的数据。为了有效地进行排重处理,通常会在列或列分区的范围内进行操作。
对于小于或等于32K的小型对象,可以采取整体排重的方法。这意味着系统会检查整个对象的内容,以确定是否存在重复项,并删除或标记这些重复项。这种整体排重的方式对于小型对象来说是高效且可行的。
对于大于32K的大型对象,整体排重可能会消耗大量的系统资源并影响性能。因此,本实施例仅对大型对象的存储切片进行排重。存储切片是将大型对象分割成较小的部分,这样可以更方便地进行管理和处理。通过对每个切片进行排重,可以在保持较高性能的同时,有效地删除重复数据。
因此,在本实施例方案中,待排重对象可以为行外存储的小型对象,或者为行外存储的大型对象的存储切片。
排重特征值的计算可以采用包括但不限于MD5(Message Digest Algorithm5,消息摘要算法)、SHA(Secure Hash Algorithm,安全散列算法)、SHA1(Secure HashAlgorithm 1,安全散列算法1)等任何一种数据摘要算法或者哈希算法,只要其输出结果的长度小,且结果长度是定值或有上界即可。
在一种特例中,如果原始数据的长度≤=数字摘要或哈希值的长度,则原始数据本身即可作为特征值,不必再计算特征值。对于LOB对象及其切片而言,这种特例比较少见。
在一些实施例中,计算行外存储的小型对象的排重特征值的步骤包括:获取小型对象的预取数据字段,即prefetch字段,行外存储的小型对象只有prefetch字段中包含对象数据,然后对预取数据字段中的二进制数据进行哈希计算,最后将得到的哈希值作为小型对象的排重特征值写入其排重特征字段,即dedup_feat字段。
进一步地,在计算小型对象的排重特征值之前,可以检查小型对象的排重特征值是否为空,若排重特征值为空,可以执行计算小型对象的排重特征值的步骤,若排重特征值不为空,需要回滚排重事务,防止出现数据不一致问题。
由于存储切片只有ext_data字段中包含对象数据,因此,可以用MD5(MessageDigest Algorithm 5,密码哈希函数)等算法对ext_data字段中的二进制数据做数字摘要,作为其排重特征值,写入其dedup_feat字段。
在一些实施例中,计算存储切片的排重特征值的步骤包括:获取存储切片的附加数据字段,即ext_data字段,对附加数据字段中的二进制数据进行哈希计算,将得到的哈希值作为存储切片的排重特征值写入其排重特征字段,即dedup_feat字段。
进一步地,在计算存储切片的排重特征值之后,还可以检查存储切片的排重特征值是否为空,若排重特征值为空,可以执行计算存储切片的排重特征值的步骤,若排重特征值不为空,需要顺序选取下一个存储切片,直至完成该大型对象的所有存储切片的排重特征值计算。
对于行外存储的大型对象,不计算其特征值,其dedup_feat字段设为NULL。由于大型对象包括多个存储切片,其中任何一个存储切片的变化都会导致其对象特征值过时,需要重新计算。
由于大型对象体量很大,无法一次性写入,只能通过多次修改或追加来完成写入操作,很难找到一个合适的时机来计算大型对象的特征值,同时还能确保该值有较长的有效期。因此,本实施例的方案不计算大型对象的特征值,以免无谓地浪费系统资源。
具体来说,当用户在指定的LOB列或列分区上启用排重之后:1、所有行外存储的小型对象插入或更新时,会自动计算和写入对象的排重特征值;2、所有行外存储的大型对象插入或更新时,会自动计算和写入存储切片的排重特征值;3、排重任务中对特征值的计算,主要是为那些在启用排重前插入或更新的对象或切片补上特征值;为减小对日常业务的影响,这个任务也不会做成一个大事务,而是尽量切分形成小事务逐步进行;因此,如果排重任务中发现一个对象或存储切片已经在插入或更新时写入的特征值,就可以简单跳过这个对象或存储切片的特征值计算,继续后边的工作。
值得说明的是,在排重功能启用期间,可能会因特殊情况而禁用排重,禁用排重就是停止排重,不再增加为排重付出的代价,正在进行的排重任务被终止,用于排重的后台定时任务不再触发。对于已经做过排重且建立了引用关系的对象和存储切片,不必恢复排重前的样子,即无需回滚排重事务。暂未排重的对象和存储切片不再继续排重,这种仅做了部分排重的状态是可以接收的。
另外,数据库系统中加入排重特性后,无论排重特性当前是否处于启用状态,DML(Data Manipulation Language)操作都可能遇到对象或切片之间有引用关系的情况。因为用户决策可能左右摇摆,先是启用了排重,然后过一阵子又禁用排重。
特别地,在启用排重又禁用排重的情况下,引用列索引需要先检查一下,如果有非空的索引键存在(即有对象或切片的引用关系存在),则需保留该索引,因为以后DML操作遇到引用关系还需靠它加速查找;否则删除该索引。
特征值不必在此时批量删除。因为基于数据库既有的MVCC(Multi-VersionConcurrency Control,多版本并发控制)机制,更新记录实际是在存储中追加一条新版的记录,并将旧版记录标记为已删除。在禁用排重的情况下,以后的DML操作中产生新版记录时不带特征值即可。这样系统代价最低。
图9是根据本发明一个实施例的数据库的大对象排重处理方法中对小型对象进行排重的流程图,如图9所示,若待排重对象为行外存储的小型对象,利用排重事务对特征值排重统计表中的待排重对象进行排重处理,并更新待排重对象的引用标识和引用计数可以包括以下步骤S901至步骤S905。
步骤S901,从特征值排重统计表中获取一组排重特征值相同的小型对象。这些小型对象被认为是潜在的重复对象,因为它们具有相同的排重特征值。
步骤S902,选取其中一个小型对象作为基准对象;通常第一个被获取到的对象会被作为基准对象,这个基准对象将用于后续的比对和引用更新。
步骤S903,遍历其余的小型对象,并将其余的小型对象与基准对象进行比对。比对的目的是确定这些对象的内容是否与基准对象的内容相同。这是通过检查整个对象的内容来实现的,以确保准确性。
步骤S904,若比对结果相同,将当前被比对的小型对象的引用标识更新为基准对象的标识,使得所有重复的对象都将引用同一个基准对象;增加基准对象的引用计数,每当一个重复对象被识别并更新为引用基准对象时,基准对象的引用计数就会增加。
步骤S905,提交排重事务,以确保所有更改都被永久地写入数据库。这样,在该组小型对象中,重复的小型对象都将被有效地删除或标记为已删除,保持了数据库中数据的一致性和准确性。
在提交排重事务后,数据库管理系统会进入下一个处理阶段,即处理特征值排重统计表中的下一组具有相同排重特征值的小型对象。这个过程是自动的,且会持续进行,直到处理完大对象列或列分区上所有的小型对象。
在本实施例中,小型对象的对象记录中设置了引用标识(ref_id)字段和引用计数(ref_count)字段,用于管理和跟踪对象的引用关系。这些字段在排重处理过程中起着关键作用。
如果小型对象存在引用关系,即它是某个其他对象的副本或重复项,ref_id字段中的值将被设置为被引用对象的标识。这个标识通常是对象的唯一标识符(如UUID、主键值等),用于建立对象之间的关联。如果小型对象不存在引用关系,即它是独立的、没有被其他对象引用的对象,ref_id字段中的值将被设置为空(NULL或空字符串)。
在排重处理后,仅基准对象中存储有实际数据(即对象的原始数据或主数据)。其他小型对象(重复项或副本)的引用标识(ref_id)字段将更新为基准对象的标识。同时,基准对象的引用计数(ref_count)字段将增加,以反映有多少个小型对象引用了它。这个计数是通过在每次识别到重复对象并将其引用标识更新为基准对象标识时递增的。
图10是根据本发明一个实施例的数据库的大对象排重处理方法中对大型对象存储切片进行排重的流程图,如图10所示,若待排重对象为行外存储的大型对象,利用排重事务对特征值排重统计表中的待排重对象进行排重处理,并更新待排重对象的引用标识和引用计数可以包括以下步骤S1001至步骤S1005。
步骤S1001,从特征值排重统计表中获取一组排重特征值相同的存储切片。这些存储切片来自同一个大对象列或列分区,被认为是在该大对象列或列分区上潜在的重复对象,因为它们具有相同的排重特征值。
步骤S1002,选取其中一个存储切片作为基准切片。通常第一个被获取到的对象会被作为基准切片,这个基准切片将用于后续的比对和引用更新。
步骤S1003,遍历其余的存储切片,并将其余的存储切片与基准切片进行比对。比对的目的是确定这些切片的内容是否与基准切片的内容相同。这是通过检查整个切片的内容来实现的,以确保准确性。
步骤S1004,若比对结果相同,则将当前被比对的存储切片的引用标识更新为基准切片的标识,使得所有重复的切片都将引用同一个基准切片;增加基准切片的引用计数。每当一个重复切片被识别并更新为引用基准切片时,基准切片的引用计数就会增加。
步骤S1005,提交排重事务,以确保所有更改都被永久地写入数据库。在事务提交后,任何重复的行外存储的大型对象的存储切片都将被有效地删除或标记为已删除,保持数据库中数据的一致性和准确性。
在排重处理流程中,如果当前的存储切片与基准切片的比对结果不同,说明它们的内容不一致,因此不能被视为重复或相同的切片。在这种情况下,系统需要继续检查其他的存储切片,以确定它们是否与基准对象相同。
类似地,在本实施例中,存储切片的切片记录中设置了引用标识(ref_id)字段和引用计数(ref_count)字段,用于管理和跟踪切片的引用关系。这些字段在排重处理过程中起着关键作用。
如果存储切片存在引用关系,即它是某个其他切片的副本或重复项,ref_id字段中的值将被设置为被引用切片的标识。这个标识通常是切片的唯一标识符(如UUID、主键值等),用于建立切片之间的关联。如果存储切片不存在引用关系,即它是独立的、没有被其他切片引用的切片,ref_id字段中的值将被设置为空(NULL或空字符串)。
在排重处理后,仅基准切片中存储有实际数据(即切片的原始数据或主数据)。其他存储切片(重复项或副本)的引用标识(ref_id)字段将更新为基准切片的标识。同时,基准切片的引用计数(ref_count)字段将增加,以反映有多少个存储切片引用了它。这个计数是通过在每次识别到重复切片并将其引用标识更新为基准切片标识时递增的。
本实施例的特征值排重统计表可以基于数据库的创建指令创建,并且具有一个唯一标识符以确保其唯一性和可识别性。在此用于在排重处理过程中存储和管理小型对象或存储切片的分组统计信息,包括排重特征值等关键信息。
在一些实施例中,将重复出现的排重特征值及其出现次数写入数据库预创建的特征值排重统计表中的步骤可以是按照出现次数对重复出现的排重特征值进行排序,将排序后的排重特征值及出现次数写入特征值排重统计表中。这样可以优先处理出现次数最多的特征值,从而提高排重效率
本实施例通过对不同类型的对象采取不同的排重策略,数据库管理系统可以更加高效地处理大对象数据,同时减少不必要的资源浪费。行内小型对象由于体积较小且会被一并读取,通常不进行排重处理;而行外对象则根据其大小,采用整体排重或对存储切片进行排重的方法,以确保系统的性能和效率。
本实施例提供的流程图并不旨在指示方法的操作将以任何特定的顺序执行,或者方法的所有操作都包括在所有的每种情况下。此外,方法可以包括附加操作。在本实施例方法提供的技术思路的范围内,可以对上述方法进行附加的变化。
应当理解,在一些实施例中,各部分可以用硬件、软件、固件或它们的组合来实现。在上述实施方式中,多个步骤或方法可以用存储在存储器中且由合适的指令执行系统执行的软件或固件来实现。
本实施例还提供了一种计算机可读存储介质20和计算机设备30。图11是根据本发明一个实施例的计算机可读存储介质20的示意图,图12是根据本发明一个实施例的计算机设备30的示意图。
计算机可读存储介质20,其上存储有上述计算机程序21,计算机程序21被处理器32执行时实现上述任一实施例的数据库的大对象排重处理方法的步骤。计算机设备30可以包括存储器31、处理器32及存储在存储器31上并在处理器32上运行的计算机程序21。
用于执行本发明操作的计算机程序21可以是汇编指令、指令集架构(InstructionSet Architecture,简称ISA)指令、机器指令、机器相关指令、微代码、固件指令、状态设置数据、集成电路的配置数据、或者以一种或多种编程语言和过程编程语言的任意组合编写的源代码或目标代码。计算机程序21可以完全在用户的计算机上执行,部分在用户的计算机上执行,作为独立的软件包执行,部分在用户的计算机上并且部分在远程计算机上执行,或者完全在远程计算机或服务器上执行。在后一种情况下,远程计算机可以通过任何类型的网络(包括局域网(Local Area Network,简称LAN)或广域网(Wide Area Network,简称WAN)连接到用户的计算机,或者可以连接到外部计算机(例如,使用因特网服务供应商通过因特网)。在一些实施例中,为了执行本发明的各方面,包括例如可编程逻辑电路、现场可编程门阵列(Field-Programmable Gate Array,简称FPGA)或可编程逻辑阵列(ProgrammableLogic Array,简称PLA)的电子电路可以通过利用计算机可读程序指令的状态信息来执行计算机可读程序指令以使电子电路个性化。
就本实施例的描述而言,计算机可读存储介质20是能够保留和存储计算机程序21的有形设备,其可以是任何可以包含、存储、通信、传播或传输程序21以供指令执行系统、装置或设备或结合这些指令执行系统、装置或设备而使用的装置。计算机可读存储介质20的更具体的示例(非穷尽性列表)包括以下:便携式计算机磁盘、硬盘、随机存取存储器(RAM)、只读存储器(ROM)、可擦除可编程只读存储器(EPROM或闪存)、静态随机存取存储器(SRAM)、便携式光盘只读存储器(CD-ROM)、数字多功能盘(DVD)、记忆棒、软盘、机械编码设备,以及上述的任何适当组合。
计算机设备30可以是例如服务器、台式计算机、笔记本式计算机、平板计算机或智能手机。在一些示例中,计算机设备30可以是云计算节点。计算机设备30可以在由计算机系统执行的计算机系统可执行指令(诸如程序模块)的一般语境下描述。通常,程序模块可以包括执行特定的任务或者实现特定的抽象数据类型的例程、程序、目标程序、组件、逻辑、数据结构等。计算机设备30可以在通过通信网络链接的远程处理设备执行任务的分布式云计算环境中实施。在分布式云计算环境中,程序模块可以位于包括存储设备的本地或远程计算系统存储介质上。
计算机设备30可以包括适于执行存储的指令的处理器32、在操作期间为所述指令的操作提供临时存储空间的存储器31。处理器32可以是单核处理器、多核处理器、计算集群或任何数量的其他配置。存储器31可以包括随机存取存储器(RAM)、只读存储器、闪存或任何其他合适的存储系统。
计算机设备30还可以包括网络适配器/接口和输入/输出(I/O)接口。I/O接口允许用可以连接到计算机设备的外部设备输入和输出数据。网络适配器/接口可以提供计算机设备与通常被示为通信网络的网络之间的通信。
至此,本领域技术人员应认识到,虽然本文已详尽示出和描述了本发明的多个示例性实施例,但是,在不脱离本发明精神和范围的情况下,仍可根据本发明公开的内容直接确定或推导出符合本发明原理的许多其他变型或修改。因此,本发明的范围应被理解和认定为覆盖了所有这些其他变型或修改。
Claims (10)
1.一种数据库的大对象排重处理方法,包括:
获取所述数据库的数据基表,所述数据基表具有至少一列大对象列;
在所述大对象列或针对所述大对象列的列分区上,按照排重特征值为每个待排重对象进行分组统计;
筛选重复出现的排重特征值,将重复出现的排重特征值及其出现次数写入所述数据库预创建的特征值排重统计表中;
启动排重事务,利用所述排重事务对所述特征值排重统计表中的待排重对象进行排重处理,并更新所述待排重对象的引用标识和引用计数。
2.根据权利要求1所述的数据库的大对象排重处理方法,其中,
所述待排重对象包括行外存储的小型对象,所述小型对象的数据大小小于等于预设阈值,利用所述排重事务对所述特征值排重统计表中的待排重对象进行排重处理,并更新所述待排重对象的引用标识和引用计数的步骤包括:
从所述特征值排重统计表中获取一组排重特征值相同的小型对象;
选取其中一个小型对象作为基准对象;
遍历其余的小型对象,并将其余的小型对象与所述基准对象进行比对;
若比对结果相同,将当前被比对的小型对象的引用标识更新为所述基准对象的标识,并增加所述基准对象的引用计数;
提交所述排重事务。
3.根据权利要求2所述的数据库的大对象排重处理方法,其中,
所述小型对象的对象记录中设置有引用标识字段,若所述小型对象存在引用关系,则所述引用标识字段中的值为被引用对象的标识,若所述小型对象不存在引用关系,则所述引用标识字段中的值被设置为空。
4.根据权利要求1所述的数据库的大对象排重处理方法,其中,
所述待排重对象包括行外存储的大型对象的存储切片,所述大型对象的数据大小大于预设阈值,并且被分割为多个存储切片进行存储,利用所述排重事务对所述特征值排重统计表中的待排重对象进行排重处理,并更新所述待排重对象的引用标识和引用计数的步骤包括:
从所述特征值排重统计表中获取一组排重特征值相同的存储切片;
选取其中一个存储切片作为基准切片;
遍历其余的存储切片,并将其余的存储切片与所述基准切片进行比对;
若比对结果相同,则将当前被比对的存储切片的引用标识更新为所述基准切片的标识,并增加所述基准切片的引用计数;
提交所述排重事务。
5.根据权利要求4所述的数据库的大对象排重处理方法,其中,
所述存储切片的切片记录中设置有引用标识字段,若所述存储切片在引用关系,则所述引用标识字段中的值为被引用切片的标识,若所述存储切片不存在引用关系,则所述引用标识字段中的值被设置为空。
6.根据权利要求4所述的数据库的大对象排重处理方法,其中,在将其余的存储切片与所述基准切片进行比对的步骤之后,还包括:
若当前被比对的存储切片与所述基准切片的比对结果不同,则顺序选取下一个被比对的存储切片。
7.根据权利要求1所述的数据库的大对象排重处理方法,其中,将重复出现的排重特征值及其出现次数写入所述数据库预创建的特征值排重统计表中的步骤包括:
按照出现次数对重复出现的排重特征值进行排序;
将排序后的排重特征值及出现次数写入所述特征值排重统计表中。
8.根据权利要求1所述的数据库的大对象排重处理方法,其中,
所述特征值排重统计表基于所述数据库的创建指令创建,并具有唯一标识符。
9.一种机器可读存储介质,其上存储有计算机程序,所述计算机程序被处理器执行时实现根据权利要求1-8任一项所述的数据库的大对象排重处理方法。
10.一种计算机设备,包括存储器、处理器及存储在所述存储器上并在所述处理器上运行的计算机程序,并且所述处理器执行所述计算机程序时实现根据权利要求1-8任一项所述的数据库的大对象排重处理方法。
Priority Applications (1)
| Application Number | Priority Date | Filing Date | Title |
|---|---|---|---|
| CN202411048060.0A CN118861127A (zh) | 2024-07-31 | 2024-07-31 | 数据库的大对象排重处理方法、存储介质及设备 |
Applications Claiming Priority (1)
| Application Number | Priority Date | Filing Date | Title |
|---|---|---|---|
| CN202411048060.0A CN118861127A (zh) | 2024-07-31 | 2024-07-31 | 数据库的大对象排重处理方法、存储介质及设备 |
Publications (1)
| Publication Number | Publication Date |
|---|---|
| CN118861127A true CN118861127A (zh) | 2024-10-29 |
Family
ID=93167921
Family Applications (1)
| Application Number | Title | Priority Date | Filing Date |
|---|---|---|---|
| CN202411048060.0A Pending CN118861127A (zh) | 2024-07-31 | 2024-07-31 | 数据库的大对象排重处理方法、存储介质及设备 |
Country Status (1)
| Country | Link |
|---|---|
| CN (1) | CN118861127A (zh) |
-
2024
- 2024-07-31 CN CN202411048060.0A patent/CN118861127A/zh active Pending
Similar Documents
| Publication | Publication Date | Title |
|---|---|---|
| US11182256B2 (en) | Backup item metadata including range information | |
| CA2723731C (en) | Managing storage of individually accessible data units | |
| US9639542B2 (en) | Dynamic mapping of extensible datasets to relational database schemas | |
| CN111522791B (zh) | 一种分布式文件重复数据删除系统及方法 | |
| CN105868228A (zh) | 为olap和oltp事务提供无锁读取和写入操作的内存数据库系统 | |
| US10769115B2 (en) | Data handling | |
| US12216622B2 (en) | Supporting multiple fingerprint formats for data file segment | |
| CN112416879B (zh) | 一种基于ntfs文件系统的块级数据去重方法 | |
| US12014070B2 (en) | Method, device, and computer program product for storage management | |
| CN118861100A (zh) | 数据库的大对象读取方法、存储介质及设备 | |
| CN118861127A (zh) | 数据库的大对象排重处理方法、存储介质及设备 | |
| CN118861040A (zh) | 数据库的大对象排重处理方法、存储介质及设备 | |
| CN118861063A (zh) | 数据库的大对象重写方法、存储介质及设备 | |
| CN118861066A (zh) | 数据库的大对象更新方法、存储介质及设备 | |
| CN118861111A (zh) | 数据库的大对象排重处理方法、存储介质及设备 | |
| CN118861064A (zh) | 数据库的大对象删除方法、存储介质及设备 | |
| CN118861039A (zh) | 数据库的大对象存储方法、存储介质及设备 | |
| CN118885485A (zh) | 数据库中临时大对象的存储方法及相关产品 | |
| CN118861068A (zh) | 数据库中大对象的更改方法及相关产品 | |
| CN118861042A (zh) | 具有大对象列的数据表的管理方法与相关产品 | |
| CN118861101A (zh) | 数据库的大对象读取方法与相关产品 | |
| CN118861067A (zh) | 数据库的大对象重写方法与相关产品 | |
| CN119003547A (zh) | 数据库的大对象更新方法、存储介质及设备 | |
| CN118861065A (zh) | 数据库的大对象更新方法与相关产品 | |
| CN118981468A (zh) | 数据库中大对象的分区存储方法与相关产品 |
Legal Events
| Date | Code | Title | Description |
|---|---|---|---|
| PB01 | Publication | ||
| PB01 | Publication | ||
| SE01 | Entry into force of request for substantive examination | ||
| SE01 | Entry into force of request for substantive examination |