本申请涉及计算机领域,尤其涉及一种用于预写式日志归档的方法及设备。
背景技术:
在主备模式的数据库系统中,备库设备通过tcp(transmissioncontrolprotocol,传输控制协议)流从主库设备同步数据,来保证备库设备设和主库设备间数据的一致。例如,目前业界大部分基于postgresql的数据库产品均是基于上述方式来来同步数据。
在高并发的数据库写入操作,会让主库设备在短时间产生大量预写式日志(writeaheadlog,wal),当主库设备写完一个预写式日志后对其进行标记,表示该预写式日志已经写完可以对其进行归档操作。在常规的配置下,主库设备会自动对被标记的预写式日志进行归档,使其能够在需要时被重用,为新的预写式日志清理出空间。在此过程中,备库设备不断从主库设备获取预写式日志,并对这些预写式日志进行应用,使得备库设备的数据能够与主库设备同步。
但是,考虑到备库设备的处理延迟(例如主库设备和备库设备之间的网络带宽较低或者备库设备应用预写式日志修改数据的速度较慢),那么预写式日志就有可能在还未被备库设备拉取之前被主库设备重用,造成该预写式日志丢失,使得备库设备拉取不到想要的预写式日志,导致备库设备的数据同步中断。在这种情况下,要修复主备之间的数据不一致,需要重搭备库设备。而这是一个代价较高的操作,需要全量拉取主库设备的所有数据,这不仅会降低主库设备的性能,而且对于保存有大数据量的数据库拉取的时间会很长,若在此期间主库设备宕机,将会造成基于该数据库的业务不可用的风险。
申请内容
本申请的一个目的是提供一种用于预写式日志归档的方法及设备,用以解决预写式日志在未被备库设备拉取之前被主库设备重用,造成主备之间的同步中断的问题。
为实现上述目的,本申请提供了一种用于预写式日志归档的方法,该方法包括:
获取备库设备最后拉取的预写式日志的序号,并将所述序号作为归档序号;
将序号小于等于所述归档序号的预写式日志文件进行归档处理。
基于本申请的另一方面,还提供了一种用于预写式日志归档的主库设备,该主库设备包括:
标记装置,用于获取备库设备最后拉取的预写式日志的序号,并将所述序号作为归档序号;
归档装置,用于将序号小于等于所述归档序号的预写式日志文件进行归档处理。
此外,本申请还提供了一种用于预写式日志归档的主库设备,包括:
处理器;
以及被安排成存储计算机可执行指令的存储器,所述可执行指令在被执行时使所述处理器:获取备库设备最后拉取的预写式日志的序号,并将所述序号作为归档序号;以及将序号小于等于所述归档序号的预写式日志文件进行归档处理。
与现有技术相比,本申请实现了主库设备根据获取到的备库设备最后拉取的预写式日志的序号,主动对主库设备中的预写式日志进行归档,仅对备库设备已经拉取的预写式日志之前的预写式日志进行归档,可以避免未同步到备库设备预写式日志的被重用,导致主备之间的日志同步中断。
在业务高峰时无需通过修改预写式日志空间配置的方式增加用于存放预写式日志的本地存储空间,避免存储资源的浪费,并且在业务高峰时来不及归档的预写式日志可以留待业务低峰时及时进行归档,避免重启数据库实例,从而对正常业务造成影响。
附图说明
通过阅读参照以下附图所作的对非限制性实施例所作的详细描述,本申请的其它特征、目的和优点将会变得更明显:
图1为本申请实施例中涉及的一主一备构架的数据库系统的示意图;
图2为本申请实施例提供的一种用于预写式日志归档的方法的流程图;
图3为本申请实施例中涉及的一主多备构架的数据库系统的示意图;
图4(a)为在对预写式日志进行重用前的预写式日志存储情况的示意图;
图4(b)为在对预写式日志进行重用后的预写式日志存储情况的示意图;
图5为本申请实施例提供的一种用于预写式日志归档的设备的结构示意图;
附图中相同或相似的附图标记代表相同或相似的部件。
具体实施方式
下面结合附图对本申请作进一步详细描述。
在本申请一个典型的配置中,终端、服务网络的设备和可信方均包括一个或多个处理器(cpu)、输入/输出接口、网络接口和内存。
内存可能包括计算机可读介质中的非永久性存储器,随机存取存储器(ram)和/或非易失性内存等形式,如只读存储器(rom)或闪存(flashram)。内存是计算机可读介质的示例。
计算机可读介质包括永久性和非永久性、可移动和非可移动媒体可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的模块或其他数据。计算机的存储介质的例子包括,但不限于相变内存(pram)、静态随机存取存储器(sram)、动态随机存取存储器(dram)、其他类型的随机存取存储器(ram)、只读存储器(rom)、电可擦除可编程只读存储器(eeprom)、快闪记忆体或其他内存技术、只读光盘只读存储器(cd-rom)、数字多功能光盘(dvd)或其他光学存储、磁盒式磁带,磁带磁盘存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。按照本文中的界定,计算机可读介质不包括非暂存电脑可读媒体(transitorymedia),如调制的数据信号和载波。
图1示出了一数据库系统,以一主一备的构架为例,该数据库系统中包括一台主库设备110和一台备库设备120,两者通过网络相互连接,其中,所述主库设备在进行写入操作时,会产生相应的预写式日志。在现有技术中一般采用自动归档的方式,当数据库系统的主库设备写完一个预写式日志后,会在相应的目录里产生一个与该预写式日志对应的标记文件,用于对预写式日志进行标记,表示该预写式日志已经写入完成,可以进行归档。
以postgresql数据库为例,主库设备会在pg_xlog/archive_status目录中产生与预写式日志对应的ready文件。该ready文件产生后,按照常规的配置,主库设备就会自动对对应的预写式日志进行归档,通常是将预写式日志存放至数据库系统的相应目录中,并在完成后将ready文件重命名为done文件,由此完成预写式日志的归档,被done文件标记的预写式日志文件会在达到空间上限时被重用。由于在业务高峰时,会并发大量的写入操作,短时间内会生成大量的预写式日志,如果某一预写式日志在重用的时候还未被备库设备拉取,那么备库设备与主库设备的数据同步就会中断。为避免未同步到备库设备的预写式日志的被重用,导致主备之间的同步中断,本申请实施例了一种用于预写式日志归档的方法,该方法适用于主备构架的数据库系统中的主库设备端,具体包括以下步骤:
步骤s201,获取备库设备最后拉取的预写式日志的序号,并将所述序号作为归档序号。
其中,所述预写式日志的序号用于表示预写式日志的生成顺序,主库设备的预写式日志的生成顺序与该预写式日志记录的数据操作对应,由于备库设备需要根据拉取的预写式日志同步数据,因此备库设备在拉取主库设备的预写式日志时,会根据该预写式日志的生成顺序来进行拉取,例如主库设备中的预写式日志的序号为001~009,备库设备会按照顺序由001的预写式日志开始拉取,直至拉取最后生成的009的预写式日志。若当前备库设备已经拉取了001~004的预写式日志,那么备库设备最后拉取的预写式日志的序号即为004,归档序号即为004。
步骤s202,将序号小于等于所述归档序号的预写式日志文件进行归档处理。
接上例,由于归档序号为004,表示备库设备已经拉取了001~004的预写式日志,此时即使主库设备中的001~004的预写式日志被重用也不会影响到主库设备和备库设备之间的数据同步。由此,可以将序号小于等于所述归档序号的预写式日志文件进行归档处理,使其能够在需要时被重用,为新的预写式日志清理出空间。
本实施例的技术方案中,主库设备根据获取到的备库设备最后拉取的预写式日志的序号,主动对主库设备中的预写式日志进行归档,仅对备库设备已经拉取的预写式日志之前的预写式日志进行归档,可以避免未同步到备库设备预写式日志的被重用,导致主备之间的日志同步中断。
目前常用的方式为:在主库设备中预留足够的空间来存放更多的预写式日志,这样重用预写式日志的时间就会被延长,使得备库设备有足够的时间在预写式日志被重用之前将其拉取,因此只要保证预留的空间足够大,就可以保证主备之间的同步不会中断。但是,在实际应用中很难预估预留多大的空间足够支撑业务高峰所产生日志,如果预留的空间过多,在并非业务高峰的其它大部分时间这些预留的空间会造成存储资源的浪费,不利于降低成本。此外,由于调整用于存放预写式日志的空间需要在修改相关配置后重启数据库实例,因此若采用动态调整的方式在业务高峰时增加预留空间,在非业务高峰时减少预留空间,无法避免对正常业务的影响。
本申请实施例中的方案在业务高峰时无需通过修改预写式日志空间配置的方式增加用于存放预写式日志的本地存储空间,避免存储资源的浪费,并且在业务高峰时来不及归档的预写式日志可以留待业务低峰时及时进行归档,避免重启数据库实例,从而对正常业务造成影响。
在此,本领域技术人员应当理解,所述数据库系统中的主库设备110和备库设备120可以包括但不限于用户设备、网络设备或用户设备与网络设备通过网络相集成所构成的设备。所述用户设备包括但不限于个人计算机、触控终端等实现;所述网络设备包括但不限于如网络主机、单个网络服务器、多个网络服务器集或基于云计算的计算机集合等实现。在此,云由基于云计算(cloudcomputing)的大量主机或网络服务器构成,其中,云计算是分布式计算的一种,由一群松散耦合的计算机集组成的一个虚拟计算机。
根据实际的应用需求,该数据库系统也可以是一主多备的构架,包含多个备库设备120,其中任意一个备库设备与主库设备之间的交互方式,与本例中一主一备的构架类似。在一主多备的构架下,所述步骤s201,具体包括:获取多个备库设备最后拉取的预写式日志的序号,并将其中最小的所述序号作为归档序号。
图3示出了一种一主多备构架的数据库系统,包括三个备库设备120a、120b和120c,主库设备110在当分别获取这三个备库设备最后拉取的预写式日志的序号,由于主库设备与这三个备库设备之间的网络状况以及三个备库设备自身的处理能力不同,备库设备120a最后拉取的预写式日志的序号为004,备库设备120b最后拉取的预写式日志的序号为006,备库设备120c最后拉取的预写式日志的序号为003。为了保证备库设备120c的数据同步不中断,主库设备只能对001~003的预写式日志进行归档,而不对004及其之后的预写式日志进行归档,避免因004及其之后的预写式日志被重用,导致备库设备120c无法顺利进行数据同步。
进一步地,在本实施例中可以通过获取备库设备中拉取的预写式日志的文件名方式来获取备库设备最后拉取的预写式日志的序号,以postgresql数据库为例,可以在主库设备中执行如下语句:selectclient_addr,pg_xlogfile_name(sent_location)frompg_stat_replication,由此获取到与该主库设备连接的每个备库设备中拉取的预写式日志的文件名,在postgresql数据库该文件名即表示备库设备最后拉取的预写式日志的序号。由此,所述步骤s201中获取备库设备最后拉取的预写式日志的序号,具体包括:获取备库设备中拉取的预写式日志的文件名,根据所述文件名确定所述备库设备最后拉取的预写式日志的序号。
进一步地,步骤s202中归档处理的具体过程可以采用以下方式:将序号小于等于所述归档序号的预写式日志拷贝至预设位置,并将其对应的状态标记为已归档状态。
其中,所述预设位置是指区别于数据库系统内部的指定目录的存储位置,可以是外部系统的存储位置,例如将预写式日志拷贝至oss(objectstorageservice,对象存储服务)平台,由此不仅可以节约数据库系统本身的存储资源,也可以使得本方案在增加预写式日志的存储空间时,无需通过修改数据库系统的配置文件,可以在业务高峰时自动增加主库设备上未归档的预写式日志的空间,而无需重启数据库实例,对正常的业务造成影响。
而每条预写式日志相应的状态标记可以采用在特定目录中与预写式日志对应的文件的形式,例如参考postgresql数据库,采用在pg_xlog/archive_status目录中的ready文件作为表示未归档的标记文件,done文件作为表示已归档的标记文件。因此,将预写式日志对应的状态标记为已归档状态时,可以是将预写式日志对应的表示未归档的标记文件修改为表示已归档的标记文件,例如将ready文件重命名为done文件。
由于大部分数据库系统的主库设备的归档策略均是采用自动归档的策略。以postgresql数据库为例,通过在配置文件postgresql.conf中将archive_mode参数置为on打开其归档功能,并且配置archive_command参数,每当主库设备写完一个预写式日志,在其pg_xlog/archive_status目录中生成一个对应的ready文件后,会自动对对应的预写式日志进行归档,将其ready文件重命名为done文件。
因此,在对现有的数据库系统进行改进以实现本申请实施例提供的归档方法时,需要在获取备库设备最后拉取的预写式日志的序号之前,配置控制参数,停止对任意预写式日志进行自动归档处理。仍以postgresql数据库为例,通过在配置文件postgresql.conf中将archive_mode参数置为on打开其归档功能,但是不设置archive_command参数,使得主库设备在写完预写式日志后会产生ready文件,但是不会自动对对应的预写式日志进行归档,将其ready文件重命名为done文件。
进一步地,所述用于预写式日志归档的方法还包括:在所述将序号小于等于所述归档序号的预写式日志进行归档处理之后,重用已完成归档处理的预写式日志。
以一主一备的数据库系统为例,若主库设备当前已经写完的预写式日志的序号为001~020,备库设备最后来去的预写式日志的序号为010,由此确定的归档序号即为010。在实际应用中,在对001~010的预写式日志进行归档之后,会在用于存放预写式日志的空间满时,对这些已经归档的预写式日志进行重用,以清理出存储空间。例如,当主库设备写完020的预写式日志时,其空间已满,为了不影响新的预写式日志的生成,主库设备会按照顺序对已经归档的预写式日志进行重用(按照001至010的顺序),在生成新的预写式日志时直接使用已经归档的预写式日志的空间。例如,清理001的预写式日志的内容以生成021的预写式日志,在对001的预写式日志进行重用的前后的预写式日志的存储情况如图4(a)和图4(b)所示。
基于本申请的另一方面,本申请实施例了还提供了一种如图5所示的用于预写式日志归档的主库设备,该主库设备适用于图1所示的主备构架的数据库系统,包括标记装置510和归档装置520。
具体地,所述标记装置510用于获取备库设备最后拉取的预写式日志的序号,并将所述序号作为归档序号。其中,所述预写式日志的序号用于表示预写式日志的生成顺序,主库设备的预写式日志的生成顺序与该预写式日志记录的数据操作对应,由于备库设备需要根据拉取的预写式日志同步数据,因此备库设备在拉取主库设备的预写式日志时,会根据该预写式日志的生成顺序来进行拉取,例如主库设备中的预写式日志的序号为001~009,备库设备会按照顺序由001的预写式日志开始拉取,直至拉取最后生成的009的预写式日志。若当前备库设备已经拉取了001~004的预写式日志,那么备库设备最后拉取的预写式日志的序号即为004,归档序号即为004。
所述归档装置520用于将序号小于等于所述归档序号的预写式日志文件进行归档处理。接上例,由于归档序号为004,表示备库设备已经拉取了001~004的预写式日志,此时即使主库设备中的001~004的预写式日志被重用也不会影响到主库设备和备库设备之间的数据同步。由此,可以将序号小于等于所述归档序号的预写式日志文件进行归档处理,使其能够在需要时被重用,为新的预写式日志清理出空间。
本实施例的技术方案实现了主库设备根据获取到的备库设备最后拉取的预写式日志的序号,主动对主库设备中的预写式日志进行归档,仅对备库设备已经拉取的预写式日志之前的预写式日志进行归档,可以避免未同步到备库设备预写式日志的被重用,导致主备之间的日志同步中断。
目前常用的方式为:在主库设备中预留足够的空间来存放更多的预写式日志,这样重用预写式日志的时间就会被延长,使得备库设备有足够的时间在预写式日志被重用之前将其拉取,因此只要保证预留的空间足够大,就可以保证主备之间的同步不会中断。但是,在实际应用中很难预估预留多大的空间足够支撑业务高峰所产生日志,如果预留的空间过多,在并非业务高峰的其它大部分时间这些预留的空间会造成存储资源的浪费,不利于降低成本。此外,由于调整用于存放预写式日志的空间需要在修改相关配置后重启数据库实例,因此若采用动态调整的方式在业务高峰时增加预留空间,在非业务高峰时减少预留空间,无法避免对正常业务的影响。
本申请实施例中的方案在业务高峰时通过传统的修改预写式日志空间配置的方式增加用于存放预写式日志的本地存储空间,避免存储资源的浪费,并且在业务高峰时来不及归档的预写式日志可以留待业务低峰时及时进行归档,避免重启数据库实例,从而对正常业务造成影响。
在此,本领域技术人员应当理解,所述数据库系统中的主库设备110和备库设备120可以包括但不限于用户设备、网络设备或用户设备与网络设备通过网络相集成所构成的设备。所述用户设备包括但不限于个人计算机、触控终端等实现;所述网络设备包括但不限于如网络主机、单个网络服务器、多个网络服务器集或基于云计算的计算机集合等实现。在此,云由基于云计算(cloudcomputing)的大量主机或网络服务器构成,其中,云计算是分布式计算的一种,由一群松散耦合的计算机集组成的一个虚拟计算机。
根据实际的应用需求,该数据库系统也可以是一主多备的构架,包含多个备库设备120,其中任意一个备库设备与主库设备之间的交互方式,与本例中一主一备的构架类似。在一主多备的构架下,所述标记装置510具体用于获取多个备库设备最后拉取的预写式日志的序号,并将其中最小的所述序号作为归档序号。
图3示出了一种一主多备构架的数据库系统,包括三个备库设备120a、120b和120c,主库设备110在当分别获取这三个备库设备最后拉取的预写式日志的序号,由于主库设备与这三个备库设备之间的网络状况以及三个备库设备自身的处理能力不同,备库设备120a最后拉取的预写式日志的序号为004,备库设备120b最后拉取的预写式日志的序号为006,备库设备120c最后拉取的预写式日志的序号为003。为了保证备库设备120c的数据同步不中断,主库设备只能对001~003的预写式日志进行归档,而不对004及其之后的预写式日志进行归档,避免因004及其之后的预写式日志被重用,导致备库设备120c无法顺利进行数据同步。
进一步地,在本实施例中可以通过获取备库设备中拉取的预写式日志的文件名方式来获取备库设备最后拉取的预写式日志的序号,以postgresql数据库为例,可以在主库设备中执行如下语句:selectclient_addr,pg_xlogfile_name(sent_location)frompg_stat_replication,由此获取到与该主库设备连接的每个备库设备中拉取的预写式日志的文件名,在postgresql数据库该文件名即表示备库设备最后拉取的预写式日志的序号。由此,所述标记装置510在获取备库设备最后拉取的预写式日志的序号时,具体用于获取备库设备中拉取的预写式日志的文件名,根据所述文件名确定所述备库设备最后拉取的预写式日志的序号。
进一步地,所述标记装置520进行归档处理的具体过程可以采用以下方式:将序号小于等于所述归档序号的预写式日志拷贝至预设位置,并将其对应的状态标记为已归档状态。
其中,所述预设位置是指区别于数据库系统内部的指定目录的存储位置,可以是外部系统的存储位置,例如将预写式日志拷贝至oss(objectstorageservice,对象存储服务)平台,由此不仅可以节约数据库系统本身的存储资源,也可以使得本方案在增加预写式日志的存储空间时,无需通过修改数据库系统的配置文件,可以在业务高峰时自动增加主库设备上未归档的预写式日志的空间,而无需重启数据库实例,对正常的业务造成影响。。
而每条预写式日志相应的状态标记可以采用在特定目录中与预写式日志对应的文件的形式,例如参考postgresql数据库,采用在pg_xlog/archive_status目录中的ready文件作为表示未归档的标记文件,done文件作为表示已归档的标记文件。因此,将预写式日志对应的状态标记为已归档状态时,可以是将预写式日志对应的表示未归档的标记文件修改为表示已归档的标记文件,例如将ready文件重命名为done文件。
由于大部分数据库系统的主库设备的归档策略均是采用自动归档的策略。以postgresql数据库为例,通过在配置文件postgresql.conf中将archive_mode参数置为on打开其归档功能,并且配置archive_command参数,每当主库设备写完一个预写式日志,在其pg_xlog/archive_status目录中生成一个对应的ready文件后,会自动对对应的预写式日志进行归档,将其ready文件重命名为done文件。
因此,本申请实施例提供了一种优选的用于预写式日志归档的主库设备,除图5所示的标记装置和归档装置之外,还包括配置装置。该配置装置,用于在获取备库设备最后拉取的预写式日志的序号之前,配置控制参数,停止对任意预写式日志进行自动归档处理。仍以postgresql数据库为例,通过在配置文件postgresql.conf中将archive_mode参数置为on打开其归档功能,但是不设置archive_command参数,使得主库设备在写完预写式日志后会产生ready文件,但是不会自动对对应的预写式日志进行归档,将其ready文件重命名为done文件。
进一步地,所述用于预写式日志归档的主库设备还包括一重用装置,该重用装置用于在所述将序号小于等于所述归档序号的预写式日志进行归档处理之后,重用已完成归档处理的预写式日志。
以一主一备的数据库系统为例,若主库设备当前已经写完的预写式日志的序号为001~020,备库设备最后来去的预写式日志的序号为010,由此确定的归档序号即为010。在实际应用中,在对001~010的预写式日志进行归档之后,可以在用于存放预写式日志的空间满时,对这些已经归档的预写式日志进行重用,以清理出存储空间。例如,当主库设备写完020的预写式日志时,其空间已满,为了不影响新的预写式日志的生成,主库设备会按照顺序对已经归档的预写式日志进行重用(按照001至010的顺序),在生成新的预写式日志时直接使用已经归档的预写式日志的空间。例如,清理001的预写式日志的内容以生成021的预写式日志。
此外,本申请实施例还提供了另一种用于预写式日志归档的主库设备,包括:
处理器;
以及被安排成存储计算机可执行指令的存储器,所述可执行指令在被执行时使所述处理器:获取备库设备最后拉取的预写式日志的序号,并将所述序号作为归档序号;以及将序号小于等于所述归档序号的预写式日志文件进行归档处理。
综上所述,本方案中主库设备根据获取到的备库设备最后拉取的预写式日志的序号,主动对主库设备中的预写式日志进行归档,仅对备库设备已经拉取的预写式日志之前的预写式日志进行归档,可以避免未同步到备库设备预写式日志的被重用,导致主备之间的日志同步中断。由于业务的处理总会有业务高峰和业务低峰,在业务高峰时不及归档的预写式日志可以留待业务低峰时及时进行归档,因此无需通过传统的修改预写式日志空间配置的方式在主库设备增加用于应对业务高峰时短时间内大量产生的预写式日志的本地存储空间,从而避免重启数据库实例,从而对正常业务造成影响。
需要注意的是,本申请可在软件和/或软件与硬件的组合体中被实施,例如,可采用专用集成电路(asic)、通用目的计算机或任何其他类似硬件设备来实现。在一个实施例中,本申请的软件程序可以通过处理器执行以实现上文所述步骤或功能。同样地,本申请的软件程序(包括相关的数据结构)可以被存储到计算机可读记录介质中,例如,ram存储器,磁或光驱动器或软磁盘及类似设备。另外,本申请的一些步骤或功能可采用硬件来实现,例如,作为与处理器配合从而执行各个步骤或功能的电路。
另外,本申请的一部分可被应用为计算机程序产品,例如计算机程序指令,当其被计算机执行时,通过该计算机的操作,可以调用或提供根据本申请的方法和/或技术方案。而调用本申请的方法的程序指令,可能被存储在固定的或可移动的记录介质中,和/或通过广播或其他信号承载媒体中的数据流而被传输,和/或被存储在根据所述程序指令运行的计算机设备的工作存储器中。在此,根据本申请的一个实施例包括一个装置,该装置包括用于存储计算机程序指令的存储器和用于执行程序指令的处理器,其中,当该计算机程序指令被该处理器执行时,触发该装置运行基于前述根据本申请的多个实施例的方法和/或技术方案。
对于本领域技术人员而言,显然本申请不限于上述示范性实施例的细节,而且在不背离本申请的精神或基本特征的情况下,能够以其他的具体形式实现本申请。因此,无论从哪一点来看,均应将实施例看作是示范性的,而且是非限制性的,本申请的范围由所附权利要求而不是上述说明限定,因此旨在将落在权利要求的等同要件的含义和范围内的所有变化涵括在本申请内。不应将权利要求中的任何附图标记视为限制所涉及的权利要求。此外,显然“包括”一词不排除其他单元或步骤,单数不排除复数。装置权利要求中陈述的多个单元或装置也可以由一个单元或装置通过软件或者硬件来实现。第一,第二等词语用来表示名称,而并不表示任何特定的顺序。