本申请涉及数据库技术领域,具体涉及数据库访问方法和装置。
背景技术:
在传统数据库中,为了适应于传统的持久性介质(如硬盘(harddiskdrive,hdd)、固态硬盘(solidstatedrive,ssd)等),在数据库的存取过程中,需要以固定粒度为单位对介质进行读写,所述固定粒度例如为页、扇区等,但对数据库中的一条记录的修改可能只占用所述固定粒度中的几个字节。以存储在ssd中的数据库为例,在对数据库中的一条记录进行修改时,即使只修改若干字节,由于ssd以页为单位读写数据,从而需要读写整个页面来进行该修改,带来较大的读写放大。同时,在对数据库进行存取的过程中,还需要将数据写入日志文件、内存缓冲池中,存在写放大和内存资源占用,耗费了大量的内存、计算资源、存储资源,也带来了较高的请求处理延时。因此,需要一种更有效的数据库访问方法。
技术实现要素:
本申请实施例旨在提供一种更有效的适用于当前的字节级持久性介质的数据库访问方案,以解决现有技术中的不足。
为实现上述目的,本申请一个方面提供一种由数据库服务器执行的数据表的访问方法,所述方法包括:接收记录行插入请求,所述记录行插入请求中包括所述记录行的数据;在数据库服务器中存入所述记录行的数据;在所述数据库服务器中包括的映射表的与所述记录行对应的行中记录所述记录行的数据存储地址,所述映射表包括与数据表每个记录行对应的各行。在该方法中,通过服务器中持久性介质中存入记录行数据,并在映射表中记录该记录行数据的存储地址,从而不需要对数据进行多次复制,节省了资源,并且,该方法可字节级存取记录行数据,不存在额外的读写放大,提供了数据库访问速度。
在一种实施方式中,所述在数据库服务器中存入所述记录行的数据包括:生成一条日志,在所述日志中记录所述记录行的数据;在数据库服务器中的日志文件中存入所述日志。本发明通过以变长日志作为记录行数据的存储单元,通过映射表跟踪记录行数据在日志文件中的存储位置信息,从而实现日志即数据。
在一种实施方式中,所述方法还包括:在生成一条日志之后,为所述日志分配一个序列号,所述序列号用于标识所述日志为当前最新产生的一条日志。本发明通过以日志生成的时间顺序对日志进行排列,从而在映射表失效的情况中,还可以通过依次读取日志来恢复数据库。
在一种实施方式中,所述映射表被存储于所述数据库服务器的内存中,其中,在所述映射表的与所述记录行对应的行中记录所述日志的存储地址和所述日志的序列号。通过在内存中存储映射表,节省了介质的存储空间,在数据库发生故障时,可通过介质中预先基于故障前的映射表生成的恢复文件来恢复内存中的映射表。
在一种实施方式中,所述映射表被存储于所述数据库服务器的持久性介质中,其中,在所述映射表的与所述记录行对应的行中记录所述日志的存储地址。
在一种实施方式中,所述方法还包括:接收记录行修改请求,所述记录行修改请求中包括对所述记录行的修改信息;从所述映射表的与所述记录行对应的行中读取修改前数据的存储地址;基于所述存储地址读取所述修改前数据;生成与记录行修改请求对应的一条日志,在所述日志中记录与所述记录行的修改后数据相关的信息,其中,所述与所述记录行的修改后数据相关的信息基于所述修改前数据的存储地址、所述修改前数据和所述修改信息获取;在数据库服务器中的日志文件中存入所述与记录行修改请求对应的日志;在所述映射表的与所述记录行对应的行中记录所述与记录行修改请求对应的日志的存储地址。
在一种实施方式中,所述方法还包括:接收记录行读取请求;从所述映射表中与所述记录行对应的行中读取最新的地址;基于所述地址读取所述记录行的数据;以及返回所述记录行的数据。
在一种实施方式中,所述方法包括:接收记录行删除请求;生成一条与所述记录行删除请求对应的日志,所述日志中与所述记录行对应的数据为空数据;在数据库服务器中的日志文件中存入与所述记录行删除请求对应的日志;在映射表中与所述记录行对应的行中标记对所述记录行的删除。
本发明另一方面提供一种部署于数据库服务器中的数据表的访问装置,所述装置包括:接收单元,用于接收记录行插入请求,所述记录行插入请求中包括所述记录行的数据;存入单元,用于在数据库服务器中存入所述记录行的数据;记录单元,用于在所述数据库服务器中包括的映射表的与所述记录行对应的行中记录所述记录行的数据存储地址,所述映射表包括与数据表每个记录行对应的各行。
在一种实施方式中,所述存入单元包括:生成子单元,用于生成一条日志,在所述日志中记录所述记录行的数据;存入子单元,用于在数据库服务器中的日志文件中存入所述日志。
在一种实施方式中,所述存入单元还包括:分配子单元,用于在生成一条日志之后,为所述日志分配一个序列号,所述序列号用于标识所述日志为当前最新产生的一条日志。
在一种实施方式中,所述映射表被存储于所述数据库服务器的内存中,其中,所述记录单元还用于在所述映射表的与所述记录行对应的行中记录所述日志的存储地址和所述日志的序列号。
在一种实施方式中,所述映射表被存储于所述数据库服务器的持久性介质中,其中,所述记录单元还用于在所述映射表的与所述记录行对应的行中记录所述日志的存储地址。
在一种实施方式中,所述装置还包括修改模块,所述修改模块包括:接收单元,用于接收记录行修改请求,所述记录行修改请求中包括对所述记录行的修改信息;第一读取单元,用于从所述映射表的与所述记录行对应的行读取修改前数据的存储地址;第二读取单元,用于基于所述存储地址读取所述修改前数据;生成单元,用于生成与记录行修改请求对应的一条日志,在所述日志中记录与所述记录行的修改后数据相关的信息,其中,所述与所述记录行的修改后数据相关的信息基于所述修改前数据的存储地址、所述修改前数据和所述修改信息获取;存入单元,用于在数据库服务器中的日志文件中存入所述与记录行修改请求对应的日志;记录单元,用于在所述映射表的与所述记录行对应的行中记录所述与记录行修改请求对应的日志的存储地址。
在一种实施方式中,所述装置还包括读取模块,所述读取模块包括:接收单元,用于接收记录行读取请求;第一读取单元,用于从所述映射表中与所述记录行对应的行中读取最新的地址;第二读取单元,用于基于所述地址读取所述记录行的数据;以及返回单元,用于返回所述记录行的数据。
在一种实施方式中,所述装置还包括删除模块,所述删除模块包括:接收单元,用于接收记录行删除请求;生成单元,用于生成一条与所述记录行删除请求对应的日志,所述日志中与所述记录行对应的数据为空数据;存入单元,用于在数据库服务器中的日志文件中存入与所述记录行删除请求对应的日志;标记单元,用于在映射表中与所述记录行对应的行中标记对所述记录行的删除。
本发明另一方面提供一种计算机可读存储介质,其特征在于,其上存储有计算机程序,当所述计算机程序在计算机中执行时,令计算机执行上述任一项方法。
本发明另一方面提供一种计算设备,包括存储器和处理器,其特征在于,所述存储器中存储有可执行代码,所述处理器执行所述可执行代码时,实现上述任一项方法。
附图说明
通过结合附图描述本申请实施例,可以使得本申请实施例更加清楚:
图1示意示出根据本申请实施例的数据库系统应用场景;
图2示意示出根据本申请实施例的数据库服务器100的架构图;
图3示出根据本申请实施例的一种在数据表1中插入记录行1的方法流程图;
图4示意示出了向数据表1中插入记录行1的时序图;
图5示出了在向数据表1中插入记录行1的过程中服务器介质中的数据变化示意图;
图6示意示出了根据本申请实施例的事务日志中包括的内容;
图7示出根据本申请实施例的一种在数据表中1修改记录行1的方法;
图8示意示出了向数据表1中修改记录行1的时序图;
图9示出了在向数据表1中插入记录行1的过程中服务器介质中的数据变化示意图;
图10示出根据本申请实施例的一种在数据表1中读取记录行1的方法流程图;
图11示意示出了从数据表1中读取记录行1的时序图;
图12示出根据本申请实施例的一种在数据表1中删除记录行1的方法流程图;
图13示出在从数据表删除记录行的过程中服务器介质中的数据变化示意图;
图14示出根据本发明另一实施例的一种在数据表1中插入记录行1的方法流程图;
图15示出在向数据表1中插入记录行1的过程中服务器中的数据变化示意图;
图16示出根据本发明另一实施例的一种在数据表中修改记录行的方法流程图;
图17示出在数据表中修改记录行的过程中服务器中的数据变化示意图;
图18示出根据本发明另一实施例的一种在数据表中读取记录行的方法流程图;
图19示出根据本发明另一实施例的一种在数据表中删除记录行的方法流程图;
图20示出在数据表中删除记录行的过程中服务器中的数据变化示意图;
图21示出根据本申请实施例的一种部署于数据库服务器中的数据表的访问装置2100;
图22示出根据本申请实施例的修改模块214;
图23示出根据本申请实施例的读取模块215;
图24示出根据本申请实施例的删除模块216。
具体实施方式
下面将结合附图,对本申请实施例中的技术方案进行描述。
图1示意示出根据本申请实施例的数据库系统应用场景。如图1中所示,数据库用户可以通过数据库客户端(connectors)200连接到本发明中的数据库服务器100。数据库服务器100中包括处理器11、内存12和持久性介质13。其中,处理器11处理来自用户的请求,并持久化保存数据到持久性介质(storagedevice)13中。处理器11可以部署为单个服务线程(或进程),也可以是多个线程,它们使用共享或独立的存储空间(例如日志文件、映射表等)。处理器11负责数据表的空间管理、数据组织、记录存取、数据缓存等功能。它接收到数据表访问请求后,对请求语句进行解释、优化等工作,并执行数据表记录的插入、删除、更新、查询等操作,并存储记录行数据到持久性介质13上。
图2示意示出根据本申请实施例的数据库服务器100的架构图。如图2中所示,所述服务器100中包括处理器11,基于所述处理器可设置后台线程池,线程池中的线程为数据库系统中处理用户请求的执行载体,所述线程也可以为进程等执行体。所述数据库服务器100中还包括内存12和持久性介质13。所述持久性介质13优选为字节级持久性存储介质,如存储级内存(storageclassmemory,scm),但也可以为hdd,sdd等。
在所述持久性介质13中存储有至少一个日志文件(write-aheadlogging,wal)。在图2中虽然仅示出一个wal文件(wal1),实际中可包括多个wal文件。所述wal文件中包括多个日志,该日志为数据库中的变长数据存储单元,用于保存数据库的记录行数据及对该记录行的操作。
数据库服务器将与数据表访问请求对应的事务日志以追加写的方式存储到日志文件中,每个事务日志包括多个操作日志,每个操作日志用于描述该请求中的对一个记录行的操作。每个事务日志被按照时间顺序分配序列号(lsn号),单个日志文件中的事务日志按照lsn号有序存储。每个日志文件具有唯一的标识(walid),该文件标识也按照文件的产生时间递增,用于恢复数据和维护数据库各记录版本间的关系。为了便于空间的回收或者多个线程的同时访问,一个数据库系统通常包含多个日志文件,日志文件的最大容量可在系统启动时设置。每个数据表可以独享自己的日志文件,也可以与其它表共享日志文件。
在所述持久性介质13中,还包括与多个数据表分别对应的多个映射表,图中示出的其中一个映射表1包括例如n行,该n行中的每行与相应的数据表中的一个记录行相对应,并且在每行中记录了与该记录行对应的至少一个日志各自的存储地址。在需要读取该映射表时,例如可通过内存映射的方式,将介质中的映射表映射为内存中的虚拟地址,从而可从内存虚拟地址读取该映射表。在本申请实施例中,仅以一个数据表为例进行说明。
其中,图2所示映射表仅为本发明一个实施例的情况,在本发明另一个实施例中,可在内存12中包括与多个数据表分别对应的多个映射表,而不需要在介质中存储映射表。
图2中示意示出映射表与日志文件之间的对应关系。如图2中所示,映射表包括多行,每行具有行id,每个操作日志与数据表的一个记录行相对应,因此,也与映射表中的一行相对应。例如,lsn=10的操作日志是对映射表1中第0行对应的记录行的操作,因此,该操作日志与映射表1中的第0行相对应,从而,在映射表的第0行中记录该lsn=10的日志在介质中的存储地址,地址1,该地址1例如为(wal1:0x10),其中wal1为该日志文件的文件标识,0x10为该日志在该wal1中的存储地址。lsn=60的日志也是对映射表中第0行对应的记录行的操作,类似地,在映射表1的第0行中记录该日志的存储地址(地址5)。lsn=65的日志是对映射表中第3行对应的记录行的操作,类似地,在映射表1的第3行中记录该日志的存储地址(地址6)。
另外,在所述持久性介质13中还包括索引1,该索引1中记录了每条记录行对应的映射表行。
通过在映射表中建立映射表行id与用于记录数据库记录行数据的各个日志的存储地址之间的映射关系,来实现对数据表记录行数据的高效存取与更新跟踪。当每次向数据表插入一条新的记录行时,系统会为该记录行分配映射表中的唯一的行id,向日志文件中写入相应的操作日志,并且在该行id对应的映射表行中记录该操作日志的存储地址。对于对数据表中一条记录行的修改、删除等,系统则会向日志文件中写入相应的操作日志,并且在该条记录行对应的映射表行中按照时间先后顺序记录该日志的存储地址。当从该数据表读取一条记录行时,则从索引1读取该记录行对应的行id,从映射表的相应行中读取最新的地址,从而从该地址读取该记录行的当前内容。
下文中将详细描述根据本申请实施例的数据表访问过程。
图3示出根据本申请实施例的一种在数据表1中插入记录行1的方法流程图,图4示意示出了向数据表1中插入记录行1的时序图。图5示出了在向数据表1中插入记录行1的过程中服务器介质中的数据变化示意图。下文将结合图3~图5进行对该方法的描述。所述方法包括以下步骤。
步骤s302,接收用户的插入请求,所述插入请求用于请求向数据表1中插入记录行1,并且所述插入请求中包括该记录行1的数据。
如图5中所示,假设介质中的映射表1与数据表1相对应,并且数据表1的记录行通过图中的wal1文件中的日志进行记录。在图5中,假设在执行该方法之前,在持久性介质中的wal1文件中写到0x10的偏移位置,并且映射表1中的第0行为空行,即为未使用的行。
参考图4,当用户通过其客户端200向数据库服务器100发送插入数据表1的记录行1的插入请求时,从而数据库服务器100中的处理器11从客户端200接收到该插入请求。该插入请求中例如包括数据表1的表id,和与插入操作对应的指示符,从而指示向数据表1中插入数据。从而将由处理器11执行图3所示的各个步骤。
该记录行1例如可以在数据表1中以行的形式示出,或者以列的形式示出,其表示数据表中的一个对象,包括该对象各个字段的字段值。本发明中虽然以数据表中的记录行进行示例表述,可以理解,在根据本申请实施例的方案中,数据库中的数据记录不限于为记录行,而可以为一列记录、一个键值对记录等等,在此不作限定。例如,在数据记录为记录行1的情况中,该记录行1的数据例如包括对象的预定多个字段各自的字段值,其中该行数据与一个键唯一对应,所述键由所述多个字段中至少一个字段各自的字段值构成。假设,记录行1例如包括小明的各个字段的字段值,所述字段例如包括身份标识、年龄、性别、职业等等,其中,该记录行1的键例如设定为小明的身份标识。
步骤s304,为记录行1分配映射表1中的当前未使用的第0行。
如图4中所示,该步骤例如由处理器11基于服务器内存进行。在服务器内存中通常缓存有记录行与映射表中的行的对应关系。
由于如参考图2所述,映射表1与数据表1相对应,因此,在接收到上述向数据表1中插入记录行1的请求之后,可将映射表1中未使用的一行(即未分配给其它记录行的)一行分配给该记录行1。例如,假设图1中的映射表1中的第0行当前未使用(即当前还不包括图5中的映射表1中的第0行中的内容),则处理器11可基于内存中的缓存的所述对应关系确定第0行当前未使用,并将第0行分配给该记录行1。
步骤s306,在持久性介质中记录记录行1与第0行的对应关系。
在进行上述分配之后,在一种实施方式中,可在持久性介质中维护的与该数据表1对应的索引1中记录:记录行1与第0行相对应。具体是,例如,对于上述与小明对应的记录行1,可在索引1中记录:“小明id:第0行行id”,其中小明id例如为小明身份证号。
在一种实施方式中,可在所述映射表的第0行中记录所述对应关系。
所述行id可包括第0行所在映射表的编号信息以及该行在映射表内的编号,例如,该行id可以包括8个字节,其中,高位的四字节表示映射表的编号,低位的四字节表示该行在映射表内的编号,例如,该行id可以通过十六进制数0x100000000表示,其中高位四字节中的1表示映射表1,低位四字节中的00000000表示在映射表1中的第0行。
可以理解,所述行id不限于通过上述方式表示,例如,该行id可以仅仅包括该行在映射表内的编号,即0x0,从而,在需要示出该行所在映射表的编号的场景中,可以“0x1,0x0”来表示该行,即映射表1中的第0行,在不需要示出该行所在映射表编号的场景中,则可以以“0x0”表示该行。
在持久性介质中记录上述对应关系之后,可在内存中记录所述对应关系,以加快数据存取速度。在一种实施方式中,可在内存中存入与索引1相同的表。
步骤s308,在持久性介质中写入操作日志1,所述操作日志1中记录了所述记录行1的数据。
如图4中所示,该步骤例如由处理器11相对于持久性介质13的日志文件wal1中进行,即在wal1中写入操作日志1。可以理解,在本申请实施例中,不限于以在日志文件中写入操作日志的形式来记录数据表的数据,例如,可将数据写入持久性介质的预定地址段中等等。
在一种实施方式中,例如在图5中的wal1中的偏移位置0x10处写入与插入请求对应的事务日志1,该事务日志1中包括操作日志1。处理器11在接收到上述插入请求之后,在内存中生成事务日志1,并为该事务日志分配日志序列号lsn,该日志序列号lsn与接收插入请求的时间相对应,表示该事务日志为当前最新产生的一条日志。图6示意示出了根据本申请实施例的事务日志中包括的内容。如图6中所示,事务日志1包括事务日志头和多个操作日志,每个操作日志分别包括操作日志头和数据。在本申请实施例中,事务日志与一个用户请求相对应,通常,一个用户请求涉及到多个数据库操作,例如,一个用户请求可以是用小明的数据代替小红的数据,从而,该用户请求包括,插入小明的数据,删除小红的数据,即包括对数据库的两个操作,因此,该两个操作被包括在该同一个事务日志中,以表示其与同一个用户请求相关。在特定情况中,当用户请求包括的操作过多的情况中,可与该用户请求对应地写入多条事务日志,但是每条事务日志的lsn号都是相同的lsn号。其中,事务日志的日志头中包括事务的lsn号、记录数(即包含的操作日志数量)。在同一个日志文件中,事务日志按照lsn号递增保存。并且事务日志在事务提交时持久化写入到日志文件中。
事务日志中的操作日志用于描述对一个记录行的操作,例如在数据库中插入小明的一行数据的操作。如图6中所示,操作日志中包括操作日志头和数据区。其中,操作日志头中可保存行id、操作码、数据长度等信息,通常还包括数据校验信息,如数据哈希值等。所述行id为上述分配给该记录行的映射表中的行id。所述操作码例如分别与插入操作、更新操作、删除操作等相对应,以用于指示操作类型。所述数据区中保存了与相应的记录行相关的内容。例如在该数据插入的场景中,与该数据插入对应的操作日志1的日志头中可保存:与该记录行对应的行id、与数据插入对应的操作码(例如,“insert”)、该记录行的长度等,在数据区中保存该需要插入的记录行的数据,例如上述小明身份id和小明的特征数据。
可以理解,上述对操作日志的描述仅是示例性的而不是限制性的。例如,在操作日志中可以不保存行id,或者,在操作日志中不保存操作码和数据长度信息,等等。
在一种实施方式中,可以将一个请求相关的多个操作日志分别写入到持久性介质中,而不需要如上文所述以一个事务日志整体写入介质中。在该情况中,为了保持与一个请求相关的各个操作日志的时间一致性,可使得各个操作日志的lsn号都为分配给该请求的lsn号。从而,在该情况中,可例如在图6中的wal1中的偏移位置0x10处直接写入操作日志1。该操作日志1中也可以包括日志头和数据区。该日志头中保存了分配给所述插入请求的lsn号,另外,该日志头中还可以与上述类似地,包括行id、操作码等信息。
步骤s310,获取操作日志1在所述持久性介质中的地址1。
如图6中所示,通过在wal1中写入事务日志1,从而写入操作日志1。在该情况中,事务日志头、操作日志头具有预定长度,从而将该事务日志1在wal1中的存储地址(即起始偏移位置0x10)加上事务日志1的日志头长度、操作日志0的日志头的长度、操作日志0中日志头中保存的数据长度,从而可获取该操作日志1在wal1中的存储地址(起始偏移位置),例如0x15,从而可获取操作日志1在持久性介质中的存储地址作为地址1:wal1,0x15。也就是说,在该实施例中,操作日志1在持久性介质中的存储地址是通过日志文件id和该文件中的偏移地址来表示,可以理解,在不通过日志文件记录日志的情况中,可以以其它形式表示操作日志在持久性介质中的存储地址,在此不作限定。
例如,如上文所述,在wal1中例如0x10处直接写入所述操作日志1,从而,可直接获取该操作日志1在持久性介质中的存储地址作为地址1:wal1,0x10。
在该实施例中,在映射表中记录的地址为操作日志的地址,当需要读取记录行的数据时,通过映射表中的地址找到相应的操作日志,从而通过读取操作日志而读取到其中包括的记录行的数据。可以理解,本发明不限于此,在一种实施方式中,映射表1中的地址1例如为所述操作日志1中的记录行数据的存储地址。在如上文所述获取操作日志1的存储地址之后,基于操作日志1中的日志头的大小,可计算出操作日志1中的记录行数据的存储地址,作为地址1。
步骤s312,在映射表1的第0行中记录所述地址1。
如图5中所示,在图中映射表行第0行中,以框示出的“地址1”即为通过该步骤在第0行中记录的地址信息。在进行该记录之后,也对该行进行了标记,即,该行已经被分配给了数据表1的相应记录行。
图7示出根据本申请实施例的一种在数据表中1修改记录行1的方法,图8示意示出了向数据表1中修改记录行1的时序图。图9示出了在向数据表1中插入记录行1的过程中服务器介质中的数据变化示意图。下文将结合图7~图9进行对该方法的描述。所述方法包括以下步骤。
步骤s702,接收用户的修改请求,所述修改请求用于请求对数据表1中的记录行1进行修改,并且,所述修改请求中包括针对记录行1的修改信息。
参考图8,当用户希望将数据表1中小明的职业从教师修改为律师,该用户通过其客户端200向数据库服务器发送修改请求。该修改请求中例如通过包括数据表1的表id和与修改操作对应的指示符,来指示向数据表1中修改记录行。另外,该修改请求中还包括与记录行1对应的键,例如小明的身份证号,以及修改内容,例如,职业:律师。从而,数据库服务器中的处理器11接收该修改请求,并执行图7所示的各个步骤。
步骤s704,基于服务器中的记录确定记录行1与映射表1中的第0行相对应。
如上文中所述,服务器在内存和持久性介质中都记录了记录行1与映射表1第0行的对应关系,通常,可从内存中直接获取该对应关系,从而确定记录行1与第0行对应。在内存中未记录该对应关系的情况中,当在映射表1中记录了各行对应的键的情况中,可通过映射表1确定,记录行1与第0行相对应。当仅在例如图2中的索引1中记录了所述对应关系的情况中,可通过读取所述索引1而确定所述对应关系。
步骤s706,从第0行中读取最新的地址1。
假设在开始执行该方法时,映射表1如图5中的映射表1所示,从而,在图5中,在映射表1的第0行的最新地址即为地址1。
步骤s708,基于地址1读取操作日志1中的记录行1的修改前数据。
如上文所述,地址1即为操作日志1的存储地址,可基于地址1读取操作日志1,从而顺序读取到该操作日志1中包括的记录行1的记录行数据。这里,可从持久性介质中的地址1直接读取操作日志1。或者,在基于内存映射的方式进行数据读取时,当内存中缓存了所述操作日志1时,可以基于地址1与内存中的地址的映射关系,从内存中的缓存中读取所述操作日志1,当内存中尚未缓存所述操作日志1时,可基于内存映射的机制通过地址1进行对操作日志1的读取。其中,基于地址1从内存缓存中读取操作日志1的记录行数据的方法不限于内存映射的方法,而可以为其它地址对应方法,在此不作限定。
在一种实施方式中,在地址1为操作日志1中的记录行数据的存储地址的情况中,可基于地址1直接读取操作日志1中的记录行数据。
步骤s710,在所述持久性介质中写入操作日志5,所述操作日志5中记录了与记录行1的修改后数据相关的信息,所述信息基于所述修改信息、所述地址1、和所述修改前数据获取。
与上文类似地,处理器在接收到修改请求后,在内存中生成操作日志5,并在操作日志5中记录与记录行1的修改后数据相关的信息。在持久性介质中写入操作日志5的方式可参考上文中写入操作日志1的方式,在此不再赘述。在一种实施方式中,操作日志5中的与记录行1的修改后数据相关的信息包括:地址1,修改后数据相对于修改前数据的差异数据。例如,在所述记录行是结构化的数据的情况中,即,包括多个字段的字段值,并且该修改为对其中一个字段进行修改,则差异数据可以为所述修改信息本身。在所述记录行不是结构化数据的情况中,可基于修改信息和修改前数据获取修改后数据,并通过增量压缩等算法提取修改后数据相对于修改前数据的差异数据。通过在操作日志5中记录地址1和差异数据,从而在需要通过操作日志5读取记录行的数据时,可首先从地址1读取到修改前数据,并记录修改前数据和差异数据恢复出修改后数据来。在一种实施方式中,在操作日志5中直接记录记录行1的修改后数据,该修改后数据基于所述修改前数据和修改信息获取。
步骤s712,获取操作日志5在所述持久性介质中的地址5。
该步骤可参考上文中对步骤s310的描述,在此不再赘述。
步骤s714,在映射表1的第0行中依据时间顺序记录地址5。
图9中示意示出了在映射表1的第0行中对地址5的记录。在第0行中,以链表的形式在地址0之后记录地址5,该链表显示出这两个记录的地址的时间先后顺序。
图10示出根据本申请实施例的一种在数据表1中读取记录行1的方法流程图。图11示意示出了从数据表1中读取记录行1的时序图。下文将结合图10和图11进行对该方法的描述。所述方法包括以下步骤。
步骤s1002,接收用户的读取请求,所述读取请求用于请求读取数据表1中的记录行1。
例如,用户希望读取小明的记录行数据,从而通过其客户端200向数据库服务器发送读取请求,该读取请求例如包括数据表1的表id和与读取操作对应的指示符,以指示读取数据表1中的记录行,另外,该读取请求中还包括与记录行1对应的键(例如小明的身份id),以指示读取记录行1。从而数据库服务器中的处理器11接收到该读取请求,并执行图9中的各个步骤。
步骤s1004,基于服务器中的记录确定记录行1与映射表1中的第0行相对应。
步骤s1006,从映射表的第0行读取最新的地址5。
假设执行该方法时,映射表1如图9中所示,映射表1第0行的最新地址为地址5,从而可读取该地址5。
步骤s1008,基于地址5读取操作日志5,以获取记录行1的当前数据。
如上文所述,在一种实施方式中,操作日志5中存储有地址1和差异数据,在基于地址5读取操作日志5之后,可从地址1读取记录行1的修改前数据,并基于修改前数据和差异数据恢复出记录行1的当前数据。
在一种实施方式中,操作日志5中记录有记录行1的当前数据,从而,通过读取操作日志5可读取记录行1的当前数据。
步骤s1010,返回记录行1的当前数据。
图12示出根据本申请实施例的一种在数据表中删除记录行的方法流程图。图13示出在从数据表删除记录行的过程中服务器介质中的数据变化示意图。下文将结合图12和图13进行对该方法的描述。所述方法包括:
步骤s1202,接收用户的用于请求删除数据表1中的记录行1的删除请求。
例如,记录行1如上文所述为小明的数据,其与映射表1中的第0行对应,该删除请求包括数据表1的表id、与删除操作对应的指示符和记录行1的键,以指示删除数据表1中的记录行1,该键例如为小明的身份证号。
步骤s1204,基于所述服务器中的记录确定记录行1与映射表1中第0行相对应。
步骤s1206,在持久性介质中写入操作日志7,所述操作日志7中的与记录行1对应的数据区为空。通过该步骤,在操作日志7中记录了对记录行1的删除。
步骤s1208,在映射表中第0行中标记删除记录行。例如,删除该第0行中记录的地址。通过该步骤,在映射表中标记了第0行对应的记录行被删除,即第0行可分配给其它记录行。如图13中所示,在进行步骤步骤s1206和步骤s1208之后,日志文件中增加了操作日志7,而映射表1中的第0行从图9中所示变为了空行。
步骤s1210,在服务器中删除记录行1与映射表1中第0行的对应关系。通过在对应关系中删除记录行1与第0行的对应关系,从而表示第0行为空行,可分配给其它记录行。
在该实施例中,由于在持久性介质中存储日志文件和映射表,因此,即使数据库服务器出现故障,在服务器重启之后,直接通过读取映射表即可读取到数据表中的记录行的数据,而不需要重启后的数据库恢复过程。其中,在重启之后,可通过内存映射的方式对映射表和日志文件进行读取。即,通过系统调用函数mmap()将介质中的映射表和日志文件的地址映射到虚拟内存地址空间,从而可通过读取虚拟内存地址而读取到介质中的映射表和日志文件,用内存读写代替了i/o读写,通过内存与介质之间的地址映射直接交互,实现了两个存储空间的高效交互。如果映射表信息失效,则可以通过按顺序回放事务日志(或操作日志)来重建映射表。
图14示出根据本发明另一个实施例的一种在数据表1中插入记录行1的方法流程图,图15示出在向数据表1中插入记录行1的过程中服务器中的数据变化示意图。所述方法包括以下步骤。
步骤s1402,接收用户的插入请求,所述插入请求用于请求向数据表1中插入记录行1,并且所述插入请求中包括该记录行1的数据。
当用户通过其设备向数据库服务器发送插入记录行1的请求时,从而数据库服务器从用户设备接收到该插入请求。该插入请求中例如包括数据表1的表id,和与插入操作对应的指示符,从而指示向数据表1中插入数据。该记录行1例如可以在数据表1中以行的形式示出,或者以列的形式示出,其表示数据表中的一个对象,包括该对象各个字段的字段值。本发明中虽然以数据表中的记录行进行示例表述,可以理解,在根据本申请实施例的方案中,数据库中的数据记录不限于为记录行,而可以为一列记录、一个键值对记录等等,在此不作限定。例如,在数据记录为记录行1的情况中,该记录行1的数据例如包括对象的预定多个字段各自的字段值,其中该行数据与一个键唯一对应,所述键由所述多个字段中至少一个字段各自的字段值构成。假设,记录行1例如包括小明的各个字段的字段值,所述字段例如包括身份标识、年龄、性别、职业等等,其中,该记录行1的键例如设定为小明的身份标识。
步骤s1404,生成与所述插入请求对应的操作日志1,为所述操作日志1分配日志序列号(logsequencenumber,lsn)lsn1,所述lsn1与时间相关联。
在接收到该插入请求之后,在内存中构建操作日志1,并按照时间顺序对该插入请求分配lsn号作为该操作日志1的lsn号,该lsn号从而体现了时间的先后顺序。例如,lsn号可按照各个请求的时间先后顺序从0开始递增,对该插入请求分配的lsn1例如为lsn1=10。
步骤s1406,为记录行1分配内存中的映射表1中的当前未使用的第0行。
如图15所示,在该实施例中,在服务器内存中维护有与数据表1对应的映射表1。在接收到上述向数据表1中插入记录行1的请求之后,可将映射表1中未使用的一行(即未分配给其它记录行的)一行分配给该记录行1。例如,假设图1中的映射表1中的第0行当前未使用(即当前还不包括映射表1中的第0行中的内容),则可将当前未使用的第0行分配给该记录行1。
步骤s1408,在持久性介质中记录记录行1与所述映射表1中第0行的对应关系。
在进行上述分配之后,可在持久性介质中维护的与该数据表1对应的索引1中记录:记录行1与第0行相对应。具体是,例如,对于上述与小明对应的记录行1,可在索引1中记录:“小明id:第0行行id”,其中小明id例如为小明身份证号。
所述行id可包括第0行所在映射表的编号信息以及该行在映射表内的编号,例如,该行id可以包括8个字节,其中,高位的四字节表示映射表的编号,低位的四字节表示该行在映射表内的编号,例如,该行id可以通过十六进制数0x100000000表示,其中高位四字节中的1表示映射表1,低位四字节中的00000000表示在映射表1中的第0行。
可以理解,所述行id不限于通过上述方式表示,例如,该行id可以仅仅包括该行在映射表内的编号,即0x0,从而,在需要示出该行所在映射表的编号的场景中,可以用“0x1,0x0”来表示该行,即映射表1中的第0行,在不需要示出该行所在映射表编号的场景中,则可以以“0x0”表示该行。
在持久性介质中记录上述对应关系之后,可在内存中记录所述对应关系,以加快数据存取速度。在一种实施方式中,可在内存中存入与索引1相同的表。在一种实施方式中,可在所述映射表的第0行中记录所述对应关系。
步骤s1410,在所述持久性介质中写入操作日志1,所述操作日志1中记录了所述记录行1的当前数据和所述映射表第0行的行id。
该操作日志1的写入形式可参考上文中对步骤s308的描述。在该操作日志1中需要包括所述映射表第0行的行id,以用于在服务器故障时恢复内存中的映射表。如图15中所示,例如在wal1中的例如0x10处写入操作日志1。
步骤s1412,获取所述操作日志1在所述持久性介质中的地址1。
如上文所示,通过在wal1中写入事务日志1,从而写入操作日志1。在该情况中,事务日志头、操作日志头具有预定长度,从而将该事务日志1在wal1中的存储地址(即起始偏移位置0x10)加上事务日志1的日志头长度、操作日志0的日志头的长度、操作日志0中日志头中保存的数据长度,从而可获取该操作日志1在wal1中的存储地址(起始偏移位置),例如0x15,从而可获取操作日志1在持久性介质中的存储地址作为地址1:wal1,0x15。也就是说,在该实施例中,操作日志1在持久性介质中的存储地址是通过日志文件id和该文件中的偏移地址来表示,可以理解,在不通过日志文件记录日志的情况中,可以以其它形式表示操作日志在持久性介质中的存储地址,在此不作限定。
例如,如上文所述,在wal1中例如0x10处直接写入所述操作日志1,从而,可直接获取该操作日志1在持久性介质中的存储地址作为地址1:wal1,0x10。
在该实施例中,在映射表中记录的地址为操作日志的地址,当需要读取记录行的数据时,通过映射表中的地址找到相应的操作日志,从而通过读取操作日志而读取到其中包括的记录行的数据。可以理解,本发明不限于此,在一种实施方式中,映射表1中的地址1例如为所述操作日志1中的记录行数据的存储地址。在如上文所述获取操作日志1的存储地址之后,基于操作日志1中的日志头的大小,可计算出操作日志1中的记录行数据的存储地址,作为地址1。
步骤s1414,在映射表1中记录与操作日志1中的记录行数据对应的节点描述1,节点描述1中包括tmin=10和地址1。
如图1中所示,在图中以实线框示出的映射表1第0行中,示出节点描述1,该节点描述1与操作日志1中的记录行数据相对应,该节点描述1包括操作日志1中记录行数据的生效序列号tmin=10,和地址1,其中,所述生效序列号即为操作日志1的序列号,表示该操作日志1中的记录行数据开始生效的时间。“地址1”即为通过上述步骤获取的操作日志1的存储地址,或者为操作日志1中的记录行数据的存储地址。在一种实施方式中,可在节点描述1中包括操作日志1中记录行数据的失效序列号:tmax=max,失效序列号可表示该操作日志1的记录行数据被删除从而失效的时间,这里,由于在该插入操作之后尚未出现对记录行1的修改,因此,将tmax表示为max,以表示该操作日志1中的记录行数据当前是有效的。这样,对于数据表的每个记录行都可以通过所述映射表和所述wal表示,所以只需要通过所述映射表和所述wal文件中的日志即可表示一个数据表,而不需要在scm中再另外存储一份数据表。
图16示出根据本申请实施例的一种在数据表中修改记录行的方法流程图,图17示出在数据表中修改记录行的过程中服务器中的数据变化示意图。所述方法包括以下步骤。
步骤s1602,接收用户的修改请求,所述修改请求用于请求对数据表1中的记录行1进行修改,并且,所述修改请求中包括针对所述记录行1的修改信息。
当用户希望将数据表1中小明的职业从教师修改为律师,该用户通过其设备向数据库服务器发送修改请求。该修改请求中例如通过包括数据表1的表id和与修改操作对应的指示符,来指示向数据表1中修改记录行。另外,该修改请求中还包括与记录行1对应的键,例如小明的身份证号,以及修改内容,例如,职业:律师。
步骤s1604,生成与该修改请求对应的操作日志5,并为该操作日志5分配lsn号,lsn2。该步骤可参考上文中对步骤s1404的描述,在此不再赘述,其中,例如,lsn2=60。
步骤s1606,基于所述服务器中的记录确定记录行1与内存中的映射表1中的第0行相对应。
如上文中所述,服务器在内存和持久性介质中都记录了记录行1与映射表1第0行的对应关系,通常,可从内存中直接获取该对应关系,从而确定记录行1与第0行对应。当在映射表1中记录了各行对应的键的情况中,可通过映射表1直接确定,记录行1与第一0行相对应。当仅在例如图1中的索引1中记录了所述对应关系的情况中,可通过读取所述索引1而确定所述对应关系。
步骤s1608,从映射表1的第0行中读取最新的节点描述1,以读取其中包括的地址1。
假设当前的映射表1如图15中的映射表1所示,由于第0行中当前最新的节点描述为节点描述1,即与上述操作日志1中的记录行数据对应的节点描述,从而,从该节点描述1可读取操作日志1或其中的记录行数据的存储地址,即地址1。
步骤s1610,基于地址1读取操作日志1中的记录行1的修改前数据。
如上文所述,地址1即为操作日志1的存储地址,可基于地址1读取操作日志1,从而顺序读取到该操作日志1中包括的记录行1的记录行数据。这里,可从持久性介质中的地址1直接读取操作日志1。或者,在基于内存映射的方式进行数据读取时,当内存中缓存了所述操作日志1时,可以基于地址1与内存中的地址的映射关系,从内存中的缓存中读取所述操作日志1,当内存中尚未缓存所述操作日志1时,可基于内存映射的机制通过地址1进行对操作日志1的读取。其中,基于地址1从内存缓存中读取操作日志1的记录行数据的方法不限于内存映射的方法,而可以为其它地址对应方法,在此不作限定。
在一种实施方式中,在地址1为操作日志1中的记录行数据的存储地址的情况中,可基于地址1直接读取操作日志1中的记录行数据。
步骤s1612,在操作日志5中记录了与记录行1的修改后数据相关的信息和所述第0行的行id,其中,所述信息基于所述修改信息、地址1和修改前数据获取,并在所述持久性介质中写入操作日志5。
所述与记录行1的修改后数据相关的信息可参考上文中对步骤s710的详细描述,在此不再赘述。
步骤s1614,获取操作日志5在持久性介质中的地址5,该步骤可参考上文中对步骤s1410的描述。
步骤s1616,在所述映射表1的第0行中依据时间顺序记录与操作日志5中的记录行数据对应的节点描述5,所述节点描述5中包括tmin=60和地址5。
如图17中所示,在该映射表1中的第0行中,添加与操作日志5对应的节点描述5,该节点描述5包括:tmin=60,tmax=max,以及地址5;同时,在该步骤中,还修改第0行中在节点描述5之前的节点描述1中的tmax,即将节点描述1中的tmax修改为节点描述5对应的操作日志5的lsn号,即tmax=60,表示节点描述1对应的记录行数据在lsn=60时被修改,也即在lsn=60时失效。第0行中的与同一记录行对应的多个节点描述可以通过如图1所示的链表表示,该链表显示出了该多个节点描述对应的多个操作日志的时间先后顺序。
图18示出根据本申请实施例的一种在数据表中读取记录行的方法流程图,所述方法包括以下步骤。
步骤s1802,接收用户的用于请求读取数据表1中的记录行1的读取请求。例如,用户希望读取小明的记录行数据,从而通过其设备向服务器发送读取请求,该读取请求例如包括数据表1的表id和与读取操作对应的指示符,以指示读取数据表1中的记录行,另外,该读取请求中还包括与记录行1对应的键(例如小明的身份id),以指示读取记录行1。
步骤s1804,基于服务器中的记录确定记录行1与内存中的映射表1中第0行相对应。数据库服务器在从用户设备接收到该读取请求之后,同样地,可基于内存(或索引1)中的键与映射表行id的对应关系,确定小明身份证号与映射表1中的第0行相对应。
步骤s1806,从映射表1的第0行中读取最新的节点描述5,以读取其中包括的地址5。假设内存中当前的映射表1如图17中所示,其中,最新的节点描述为节点描述5,从而从第0行中读取到最新的节点描述5。
步骤s1808,基于地址5读取操作日志5中的记录行数据作为记录行1的当前数据。如上文所述,地址5为图17中的操作日志5或其中的记录行数据在持久性介质中的存储地址,从而可基于地址5读取操作日志5中的记录行数据,由于,操作日志5对应的节点描述是第0行中最新的节点描述,这就表示,操作日志5为记录行1的最新数据,即为记录行1的当前数据。其中,基于地址5读取操作日志5中的记录行数据的具体方式可参考上文中对步骤s410的描述,在此不再赘述。
步骤s1710,向用户设备返回记录行1的当前数据。
图19示出根据本申请实施例的一种在数据表中删除记录行的方法流程图,图20示出在数据表中删除记录行的过程中服务器中的数据变化示意图。所述方法包括以下步骤。
步骤s1902,接收用户的用于请求删除数据表1中的记录行1的删除请求。该删除请求包括数据表1的表id、与删除操作对应的指示符和记录行1的键,以指示删除数据表1中的记录行1。
步骤s1904,生成与所述删除请求对应的操作日志7,为操作日志7分配lsn3,例如lsn3=70。
步骤s1906,基于所述服务器中的记录确定记录行1与映射表1中第0行相对应。
步骤s1908,在所述操作日志7中记录与记录行1数据对应的空数据、和第0行的行id,并在所述持久性介质中写入操作日志7。
步骤s1910,将第0行中的最新的节点描述5的tmax修改为lsn3,从而在映射表1中第0行中标记该行对应的记录行1被删除。如图20中所示。
步骤s1912,在服务器中删除记录行1与映射表1中第0行的对应关系。
在对映射表1中第0行进行上述标记之后,在该第0行中将不增加新的节点描述。由于在服务器中删除了记录行1与映射表1第0行的对应关系,从而第0行成为未使用的行,从而在插入其它记录行时,有可能将第0行分配给其它记录行,从而,该第0行中已有的节点描述将被删除,以用于记录与其它记录行对应的节点描述。
在该实施例中,由于通过内存中的映射表和持久性介质中的日志文件表示数据表,所以在服务器出现故障之后,只要恢复内存中的与数据表对应的映射表,即可恢复数据表。
在本发明中,取代了传统的日志、缓存页、数据文件的存储方式,以变长日志作为记录行数据的基本存储单元,通过映射表跟踪记录行数据在日志文件中的存储位置信息,从而实现日志即数据,节省了内存资源和多份数据间的转换、拷贝带来的资源占用。同时,在本发明中可字节级存取数据库的记录,不存在额外的数据读写放大,从而提高了数据库访问速度。
图21示出根据本申请实施例的一种部署于数据库服务器中的数据表的访问装置2100,所述装置2100包括:
接收单元211,用于接收记录行插入请求,所述记录行插入请求中包括所述记录行的数据;
存入单元212,用于在数据库服务器中存入所述记录行的数据;
记录单元213,用于在所述数据库服务器中包括的映射表的与所述记录行对应的行中记录所述记录行的数据存储地址,所述映射表包括与数据表每个记录行对应的各行。
在一种实施方式中,所述存入单元212包括:生成子单元2121,用于生成一条日志,在所述日志中记录所述记录行的数据;存入子单元2122,用于在数据库服务器中的日志文件中存入所述日志。
在一种实施方式中,所述存入单元还包括:分配子单元2123,用于在生成一条日志之后,为所述日志分配一个序列号,所述序列号用于标识所述日志为当前最新产生的一条日志。
在一种实施方式中,所述映射表被存储于所述数据库服务器的内存中,其中,所述记录单元213还用于在所述映射表的与所述记录行对应的行中记录所述日志的存储地址和所述日志的序列号。
在一种实施方式中,所述映射表被存储于所述数据库服务器的持久性介质中,其中,所述记录单元213还用于在所述映射表的与所述记录行对应的行中记录所述日志的存储地址。
在一种实施方式中,所述装置还包括修改模块214,图22示出根据本申请实施例的修改模块214,所述修改模块214包括:
接收单元2141,用于接收记录行修改请求,所述记录行修改请求中包括对所述记录行的修改信息;
第一读取单元2142,用于从所述映射表的与所述记录行对应的行读取修改前数据的存储地址;
第二读取单元2143,用于基于所述存储地址读取所述修改前数据;
生成单元2144,用于生成与记录行修改请求对应的一条日志,在所述日志中记录与所述记录行的修改后数据相关的信息,其中,所述与所述记录行的修改后数据相关的信息基于所述修改前数据的存储地址、所述修改前数据和所述修改信息获取;
存入单元2145,用于在数据库服务器中的日志文件中存入所述与记录行修改请求对应的日志;
记录单元2146,用于在所述映射表的与所述记录行对应的行中记录所述与记录行修改请求对应的日志的存储地址。
在一种实施方式中,所述装置还包括读取模块215,图23示出根据本申请实施例的读取模块215,所述读取模块215包括:
接收单元2151,用于接收记录行读取请求;
第一读取单元2152,用于从所述映射表中与所述记录行对应的行中读取最新的地址;
第二读取单元2153,用于基于所述地址读取所述记录行的数据;以及
返回单元2154,用于返回所述记录行的数据。
在一种实施方式中,所述装置还包括删除模块216,图24示出根据本申请实施例的删除模块216,所述删除模块216包括:
接收单元2161,用于接收记录行删除请求;
生成单元2162,用于生成一条与所述记录行删除请求对应的日志,所述日志中与所述记录行对应的数据为空数据;
存入单元2163,用于在数据库服务器中的日志文件中存入与所述记录行删除请求对应的日志;
标记单元2164,用于在映射表中与所述记录行对应的行中标记对所述记录行的删除。
需要理解,本文中的“第一”,“第二”等描述,仅仅为了描述的简单而对相似概念进行区分,并不具有其他限定作用。
本领域普通技术人员应该还可以进一步意识到,结合本文中所公开的实施例描述的各示例的单元及算法步骤,能够以电子硬件、计算机软件或者二者的结合来实现,为了清楚地说明硬件和软件的可互换性,在上述说明中已经按照功能一般性地描述了各示例的组成及步骤。这些功能究竟以硬件还是软件方式来执行,取决于技术方案的特定应用和设计约束条件。专业技术人员可以对每个特定的应用来使用不同方法来实现所描述的功能,但是这种实现不应认为超出本发明的范围。
本领域普通技术人员可以理解实现上述实施例方法中的全部或部分步骤是可以通过程序来指令处理器完成,所述的程序可以存储于计算机可读存储介质中,所述存储介质是非短暂性(英文:non-transitory)介质,例如随机存取存储器,只读存储器,快闪存储器,硬盘,固态硬盘,磁带(英文:magnetictape),软盘(英文:floppydisk),光盘(英文:opticaldisc)及其任意组合。
以上所述,仅为本发明较佳的具体实施方式,但本发明的保护范围并不局限于此,任何熟悉本技术领域的技术人员在本发明揭露的技术范围内,可轻易想到的变化或替换,都应涵盖在本发明的保护范围之内。因此,本发明的保护范围应该以权利要求的保护范围为准。