3.2.1 达梦数据库体系架构
3.2.1.1 DM物理存储结构
数据库是磁盘上存放的数据的集合,一般包括数据文件、日志文件、控制文件及临时数据文件等。实例一般由一组正在运行的数据库后台进程/线程及一个大型的共享内存组成。简单来说,实例就是操作数据库的一种手段,是用来访问数据库的内存结构及后台进程的集合。DM8体系结构如图3-1所示。
1.配置文件
配置文件是数据库用来设置功能选项的一些文本文件的集合,达梦数据库的配置文件主要以ini为扩展名,用来存储功能选项的配置值。配置文件存放在数据文件的目录下。
图3-1 DM8体系结构
例如查看数据库DAMENG的所有ini配置文件:
以下为几个主要的配置文件。
(1)dm.ini:DM实例的配置参数。在创建DM实例时自动生成。
(2)dmmal.ini:MAL系统的配置文件。在配置DM高可用解决方案时需要用到该配置文件。
(3)dmarch.ini:归档配置文件。启用数据库归档后,在该文件中配置归档的相关属性,如归档类型、归档路径、归档可使用的空间大小等。
2.控制文件
控制文件记录了数据库必要的初始信息,每个DM实例都有一个二进制的控制文件,默认其和数据文件存放在同一个目录下,扩展名为ctl。例如:
数据库必要的初始信息主要包含以下内容:
(1)数据库名称;
(2)数据库服务器模式;
(3)OGUID唯一标识;
(4)数据库服务器版本;
(5)数据文件版本;
(6)数据库的启动次数;
(7)数据库最近一次启动时间;
(8)表空间信息;
(9)控制文件校验码,在每次修改控制文件后生成,保证控制文件的合法性,防止文件损坏及手工修改。
第一次初始化新数据库时,会在控制文件同级目录的CTL_BAK目录下对原始的dm.ctl执行一次备份。在修改控制文件时,例如添加数据文件,也会执行一次备份。备份的路径和备份保留数由dm.ini参数文件中的CTL_BAK_PATH和CTL BAK_NUM参数决定。例如:
3.备份文件
备份文件是数据库备份恢复过程中使用的文件,扩展名为bak。在执行SQL备份或者DMRMAN(DM recovery manager)备份时会生成备份文件。备份文件记录备份的名称、数据库、备份类型和备份时间等信息。备份文件是数据库备份恢复操作的基础,也可以通过备份恢复的方式进行数据迁移。
4.数据文件
数据文件对应磁盘上的一个物理文件,是存储真实数据的地方,一个表空间至少包含一个数据文件,数据文件扩展名为DBF。表空间中数据文件的总数不能超过256。
数据文件可以配置成自增,每次自增的范围是0到2048 MB。数据文件的大小范围是4096×页大小到2147483647×页大小。例如:
5.重做日志文件
重做(REDO)日志文件记录了在数据库中添加、删除、修改对象,或者改变数据的过程。这些操作执行的结果按照特定的格式写入当前的重做日志文件中。重做日志文件以log为扩展名。每个数据库实例至少有两个重做日志文件,默认重做日志名称是数据库名加编号,两个重做日志文件循环使用。例如:
重做日志文件是循环使用的,当重做日志文件被写满后,数据库会根据检查点覆盖之前的内容。重做日志文件主要用于数据库的备份与恢复。在异常情况下,例如服务器异常断电,数据库缓冲区中的数据页没有及时写入数据文件中。在下次启动DM实例时,通过重做日志文件中的数据,可以将实例恢复到发生意外前的状态。
6.归档日志文件
归档日志文件是REDO日志文件的备份,REDO日志文件记录数据库实例DDL(data definition language)和数据更新操作。为了保证数据库备份恢复操作,需要启动归档模式,并且将REDO日志文件中的数据复制到归档日志文件中。归档日志文件以归档时间命名,扩展名也是log。
归档日志文件的保存目录由dmarch.ini中的ARCH_DEST参数控制。例如:
3.2.1.2 DM逻辑存储结构
数据库存储在服务器的磁盘上,实例则存储在服务器的内存中。通过运行DM实例,可以操作DM中的数据,实例仅在启动后存在。图3-2所示为表空间、数据文件、段、簇、页的关系。
图3-2 表空间、数据文件、段、簇、页的关系
可以看出,在DM8中存储的层次结构如下:
(1)数据库由一个或多个表空间组成;
(2)每个表空间由一个或多个数据文件组成;
(3)每个数据文件由一个或多个簇组成;
(4)段是簇的上级逻辑单元,一个段可以跨多个数据文件;
(5)簇由磁盘上连续的页组成,一个簇总是在一个数据文件中;
(6)页是数据库中最小的分配单元,也是数据库中使用的最小的I/O单元。
1.表空间
数据库中的所有对象在逻辑上都存放在表空间中,而在物理上都存储在所属表空间对应的数据文件中。创建数据库时会自动创建5个表空间:SYSTEM表空间、ROLL表空间、MAIN表空间、TEMP表空间和HMAIN表空间。
(1)SYSTEM(系统)表空间存放了有关数据库的字典信息,用户不能在SYSTEM表空间创建表和索引。
(2)ROLL(回滚)表空间存储事务操作修改之前的值,从而保证数据的读一致性。该表空间由数据库自动维护。
(3)MAIN表空间是默认的用户表空间。创建用户时如果没有指定默认表空间,则使用MAIN表空间为默认的表空间。
(4)TEMP表空间为临时表空间。当SQL语句需要磁盘空间来完成某个操作时,会从TEMP表空间分配临时段。该表空间由数据库自动维护。
(5)HMAIN表空间是HUGE表空间(huge tablespace,HTS)。创建HUGE表时,如果没有指定HTS,则默认使用HMAIN表空间来存储。我们可以通过v $ tablespace视图查看与表空间相关的信息:
如果是HTS,则需要查询v $ huge_tablespace视图:
2.记录
达梦数据库表中的每一行数据就是一条记录。除了HUGE表,数据库中其他的表都是以记录的形式将数据存储在数据页中的。
数据页中除了存储记录的数据以外,还包含存储页头控制信息的相关空间,而记录又不能跨数据页存储,因此记录的长度受到数据页大小的限制。在达梦数据库中,每条记录的总长度不能超过页面大小的一半(如果超过,可以通过为表设置启用超长列的特性来支持)。
3.页
数据页(page)又称为数据块,是达梦数据库中最小的数据存储单元。达梦数据库中页大小可以设置为4 KB、8 KB(默认值)、16 KB、32 KB。在创建数据库时指定其大小,数据库建好后,页大小不能修改。
数据页包含4个部分:页头控制信息、数据、空闲空间、行偏移数组。
页头控制信息包含页类型、页地址等信息。页中部存储记录的数据,页尾部专门留出部分空间来存放行偏移数组。行偏移数组用于标识页上的空间占用情况,以便管理数据页自身的空间。
正常情况下,用户不用干预数据库对页的管理。但在创建表或索引时也可以指定该对象的存储属性:FILLFACTOR。该存储属性控制存储数据时,每个数据页和索引页的充满程度的取值范围为0到100。默认值为0,等价于100,表示全满填充。
填充比例决定了页内的可用空间,当填充比例较低时,页内有更多的可用空间,可以避免在增加列或者更新列时因空间不足而导致的页分裂,即一部分保留在当前数据页中,另一部分存入一个新页中。
使用FILLFACTOR时要平衡性能和空间,设置较低的FILLFACTOR可以避免频繁的页分裂,减少I/O操作,从而提升性能,但是需要更多的空间来存储数据。
4.簇
簇(extent)由同一个数据文件中16或32个连续的数据页组成。其大小在创建数据库时指定,默认为16。例如数据文件大小为32 MB,页大小为8 KB,则共有32 MB/(8 KB×16)=256个簇,每个簇的大小为8 KB×16=128 KB。簇的大小也只能在创建数据库时指定,之后不能修改。
5.段
段(segment)由表空间中的一组簇组成,这些簇可以来自不同的数据文件,而簇只能由同一个数据文件中连续的16或者32个数据页组成。因为簇的数量是根据对象的数据量来分配的,所以段中的簇不一定是连续的。
3.2.1.3 DM内存结构
数据库实例由内存结构和一系列的线程组成,内存结构主要包括内存池、缓冲区、排序区、哈希区等。
1.内存池
DM的内存池包括共享内存池和运行时内存池。我们可以通过V $ MEM_POOL视图查看所有内存池的状态和使用情况:
1)共享内存池
在实例运行期间,需要经常申请或释放小片内存,而向操作系统申请或释放内存需要发出系统调用,此时可能会引起线程切换,降低系统运行效率。因此,实例在启动时会从操作系统中申请一大片内存,即内存池。当实例在运行中需要内存时,实例可在共享内存池内进行内存的申请或者释放。
共享内存池可以在实例的配置文件(dm.ini)中配置:
MEMORY_POOL参数指定的是共享内存池大小,64位系统的取值范围是64 MB到67108864 MB。当实例运行时,如果需要的内存大于共享内存池的配置值,则共享内存池会自动扩展,每次扩展的大小由MEMORY_EXTENT_SIZE参数决定。该参数的有效范围是1 MB到10240 MB。
MEMORY_TARGET参数控制的是共享内存池可使用的最大值,该值的取值范围在32位平台是0到2000 MB,在64位平台是0到67108864 MB,0表示不限制。
2)运行时内存池
除了共享内存池以外,实例的一些功能模块在运行时还会使用自己的运行时内存池。这些运行时内存池是从操作系统中申请一片内存作为本功能模块的内存池来使用的,如会话内存池、虚拟机内存池等。
2.缓冲区
1)数据缓冲区
数据缓冲区保存的是数据页,包括用户更改的数据页和查询时从磁盘读取的数据页。该区域的大小对实例性能影响较大,设定过小,会导致缓冲页命中率低,磁盘I/O频繁;设定过大,会导致内存资源的浪费。
实例在启动时,根据配置文件中参数指定的数据缓冲区大小,向操作系统申请一片连续的内存并将其按数据页大小进行格式化,最后置入“自由”链中。
数据缓冲区有三条链来管理被缓冲的数据页:
(1)“自由”链,用于存放目前未被使用的内存数据页;
(2)“LRU”链,用于存放已被使用的内存数据页(包括未被修改的和已被修改的);
(3)“脏”链,用于存放已被修改的内存数据页。
“LRU”链对系统当前使用的页按其最近是否被使用的顺序进行了排序。这样,当数据缓冲区中的“自由”链被用完时,从“LRU”链中淘汰部分最近未被使用的数据页,能够较大程度地保证被淘汰的数据页在最近不会被用到,从而减少物理I/O操作。
通过查询V $ BUFFERPOOL视图,我们可以看出,DM实例的内存数据缓冲区有5种类型:NORMAL、KEEP、FAST、RECYCLE和ROLL。V $ BUFFERPOOL视图如下:
在创建表空间或修改表空间时,可以指定表空间属于NORMAL或KEEP缓冲区。
(1)NORMAL缓冲区主要存储实例正在处理的数据页,在没有特别指定缓冲区的情况下,默认缓冲区为NORMAL。
(2)KEEP缓冲区用来存储很少淘汰或几乎不淘汰的数据页。
(3)RECYCLE缓冲区供临时表空间使用。
(4)ROLL缓冲区供回滚表空间使用。
(5)FAST缓冲区根据FAST_POOL_PAGES参数指定的大小由系统自动管理。
用户不能指定使用RECYCLE、ROLL、FAST缓冲区的表或表空间。
在dm.ini配置文件中,由对应的参数来控制这些缓冲区的大小:
参数的相关说明如下。
(1)BUFFER:系统缓冲区大小,有效值为8 MB到1048576 MB。该值推荐设置为可用物理内存的60%~80%。
(2)BUFFER_POOLS:设置BUFFER的分区数,每个BUFFER分区的大小为BUFFER/BUFFER_POOLS。该参数的有效值范围是1到512。
(3)FAST_POOL_PAGES:快速缓冲区页数,有效值范围是0到99999。FAST_POOL_PAGES的值最多不能超过BUFFER总页数的一半,如果超过,系统会自动将其调整为BUFFER总页数的一半。
(4)KEEP:KEEP缓冲区大小,有效值范围是8 MB到1048576 MB。
(5)RECYCLE:RECYCLE缓冲区大小,有效值范围是8 MB到1048576 MB。
(6)RECYCLE_POOLS:RECYCLE缓冲区分区数,每个RECYCLE分区的大小为RECYCLE/RECYCLE_POOLS。该参数的有效值范围是1到512。
注意:以上参数都是静态参数,修改这些值需要重启实例,因此要提前规划好,以免影响业务。
2)日志缓冲区
日志缓冲区用于存放重做日志的内存缓冲区。为了避免直接的磁盘I/O对实例性能的影响,实例在运行过程中产生的日志并不会立即被写入磁盘,而是和数据页一样,先将其放置到日志缓冲区中。
将日志缓冲区与数据缓冲区分开主要基于以下原因:
(1)重做日志的格式与数据页的格式不一样,无法进行统一管理;
(2)重做日志具有连续写的特点;
(3)在逻辑上,写重做日志比写数据页的I/O优先级更高。
在dm.ini配置文件中相关的参数如下:
RLOG_BUF_SIZE参数控制的是单个日志缓冲区大小。日志缓冲区所占用的内存是从共享内存池中申请的,单位为日志页数量,且大小必须为2的N次方,最小值为1,最大值为20480。
RLOG_POOL_SIZE参数控制的是最大日志缓冲区大小,有效值范围是1 MB到1024 MB。
3)字典缓冲区
字典缓冲区主要存储一些数据字典信息,如模式信息、表信息、列信息、触发器信息等。每个事务操作都会涉及数据字典信息,访问数据字典信息的效率直接影响到相应的操作效率,如执行查询时需要获取表的信息、列的信息等,从字典缓冲区中读取这些信息的效率要高于磁盘I/O读取的效率。
DM实例在启动时会将部分数据字典信息加载到字典缓冲区中,并采用LRU算法对字典信息进行控制。可以修改配置文件中的DICT_BUF_SIZE参数来控制字典缓冲区的大小,该参数是静态参数,默认值为5 MB。该缓冲区从内存池中申请。
4)SQL缓冲区
SQL缓冲区提供执行SQL语句过程中所需要的内存(以内存池中申请),包括计划、SQL语句和结果集缓存。当重复执行相同SQL语句时,可以直接使用SQL缓冲区保存的这些语句和对应的执行计划,从而提高SQL语句执行效率。
可以通过设置CACHE_POOL_SIZE参数来控制SQL缓冲区大小,该参数也是静态参数,在64位平台的有效值范围为1 MB到67108864 MB。
3.排序区
排序区提供数据排序所需要的内存空间。在SQL语句需要排序时,所使用的内存就是排序区提供的。在每次排序过程中,都先申请内存,排序结束后再释放内存。
在dm.ini配置文件中以下参数与排序区有关:
SORT_BUF_SIZE参数控制的是排序区的大小。该参数为动态参数,有效值范围为1 MB到2048 MB。由于其值是由系统内部排序算法和排序数据结构决定的,建议使用默认值2 MB。
4.哈希区
达梦数据库提供了为哈希连接而设定的缓冲区,但该缓冲区是虚拟缓冲区,这是因为在系统中没有真正创建特定属于哈希区的内存,而是在进行哈希连接时,对排序的数据量进行了计算。如果计算出的数据量大小超过了哈希区的大小,则使用DM8创新的外存哈希方式;如果没有超过哈希区的大小,实际上使用的还是VPOOL内存池。
dm.ini配置文件中与哈希区有关的参数如下:
HJ_BUF_SIZE参数控制的是单个哈希连接操作符的数据总缓存大小。该参数为动态参数,有效值范围为2 MB到100000 MB。由于其值的大小可能会限制哈希连接的效率,因此建议保持默认值,或设置为更大的值。