#数据库配置调优

数据库安装部署过程中的初始化配置对数据库性能至关重要。在YashanDB中,初始化配置包含如下两项:

  • 参数配置文件:通过在yasdb.ini中配置相关参数,初始化足够的数据库资源,例如内存、会话数、并行数等。
  • 建库语句:通过创建数据库的SQL语句,指定数据库启动后被分配的资源,例如存储空间等。

# 初始化配置参数

YashanDB提供了一系列性能参数,可以满足不同硬件环境、不同业务模型下的性能需求。数据库初始化时,应根据应用需求和环境资源,赋予这些参数合适的初始值;同时,在后续的数据库运行过程中,可能需要对这些参数进行调整,以解决某些被识别到的性能瓶颈。

除了在数据库运行过程中,根据识别到的瓶颈进行参数优化之外,数据库在初始化时,也应该根据应用需求,初始化合适的参数值。

下表列示在部署数据库实例时需要重点关注的配置参数,这些参数的初始化值对数据库性能至关重要:

参数名称 参数描述
VM_BUFFER_SIZE VM用于保存数据运算的中间结果,例如order by,group by。如对其配置过小,将容易导致频繁的VM换入换出(产生IO)。
建议需要根据应用实际需求,配置合理的VM大小。
REDOFILE_IO_MODE REDO文件的IO模式,不同磁盘在不同IO模式下的性能差异可能比较大,设置合理的IO模式,可以充分发挥磁盘性能。
建议一直使用默认值,若出现明显的性能问题,可通过性能测试找到合适的IO模式。
REDO_BUFFER_SIZE REDO缓存区的大小,设置较大的缓存区可以提高REDO刷盘效率和REDO回放效率。
建议将REDO_BUFFER_SIZE配置为64M。
REDO_BUFFER_PARTS REDO缓存区的分区个数,某个会话产生的REDO被哈希分配到唯一的分区,设置合理的分区个数能减少并发冲突。
建议将REDO_BUFFER_PARTS配置为8。
VM_BUFFER_SWAP_TIMES(隐藏参数,默认值1024 VM可交换次数,即可使原先的VM BLOCK扩大的倍数。该值支持设置的最大值为1024,超过最大值会报错。
VM_BUFFER_PARTS(隐藏参数,默认值1 VM设置分区个数,该值支持设置的最大分区数为3,设置大于3不会报错,但是不生效。
SCOL_DATA_BUFFER_SIZE 可供使用了稳态数据缓冲区的对象(如LSC表)使用的稳态数据缓冲区大小,缓冲区调大可提升读取命中率及LSC表的导入性能。建议将Slice元数据和频繁访问小表都缓存在内存。
HEAP/TAC表情况下,建议将该参数配置为默认值。
LSC表情况下,建议将该参数配置为数据库预留内存的50%左右。
DBWR_COUNT Database Writer用于将数据库产生的脏块刷新到磁盘,此参数用于配置Database Writer的数量,一般情况下(尤其是SSD盘),提高Database Writer的数量,可以提升IO的效率。
建议根据实际硬件环境和业务压力,配置合适的Database Writer数量。
DB_BLOCK_SIZE 组织数据的块大小,包括文件中以及Data Buffer中的块大小,YashanDB提供8K,16K,32K三种不同规格的块大小供设置。
小的数据块可以降低高并发下的数据访问冲突,大的数据块可以提升IO效率。因此建议事务处理场景下配置较小的块大小,数仓场景下配置较大的块大小。
需要注意的是,建库指定的块大小不能再被改变,除非重新建库。
DATA_BUFFER_SIZE 数据缓存区的大小,该值对数据库的性能表现至关重要,合理的缓存区配置将有效降低IO的开销。
建议将DATA_BUFFER_SIZE配置为数据库预留内存的80%。
该参数设置过小可能会出现启动或建库失败,最小值近似公式:(UNDO_SEGMENTS * 99 + 1K)* DB_BLOCK_SIZE,UNDO_SEGMENTS和DB_BLOCK_SIZE参考CREATE DATABASE,计算时UNDO_SEGMENTS最小取64(该值还可能和某些隐藏参数有关联)。
COMPRESSION LSC表默认压缩方式,如建表时不指定压缩方式,则使用该配置。该值可设置为UNCOMPRESSED不压缩,或LZ4压缩。
建议使用LZ4压缩,可减少存储空间占用,降低IO开销。
CHECKPOINT_TIMEOUT 检查点时间间隔,表示每过一段时间,执行一次增量检查点。
提高检查点频率能减少REDO追尾风险,减少宕机重启时间,但是会增加磁盘IO。反之,则会增加REDO追尾风险,增加宕机重启时间。
建议该值设置为10到30秒,但如果是持续时间较短的极限性能测试场景,可以设置为较大值,不触发检查点。
CHECKPOINT_INTERVAL 检查点REDO大小阈值,表示当检查点覆盖的REDO(重启回放所需的REDO)的总大小超过该值时,将执行一次增量检查点。
设置较小的阈值可以提高检查点频率和减少REDO追尾风险,减少宕机重启时间。
建议该值设置为REDO文件的平均大小,但如果是持续时间较短的极限性能测试场景,可以设置为较大值,不触发检查点。

# 参数关联性

YashanDB的大部分参数是独立的,但是某些参数之间会有关联性,某些文件的大小也依赖于参数设置。其中:

  • REDO_BUFFER_PARTS与参数REDO_BUFFER_SIZE有关联,配置不合理可能会导致数据库启动报错,详细信息请参考配置参数
  • 双写文件的最小大小,依赖于DBWR_COUNT,DBWR_BUFFER_SIZE和DB_BLOCK_SIZE。当这些参数调整变大后,数据库启动可能报双写文件太小的错误,此时需要resize双写文件。
  • REDO文件的最小大小,依赖于REDO_BUFFER_SIZE,MAX_SESSIONS和DB_BLOCK_SIZE。详细信息请参考ALTER_DATABSE配置参数

# 参数大小

资源相关的参数,不能设置太大,否则会因为无法申请资源而导致数据库启动失败。内存相关的参数的更需要关注,虽然这些参数设置较大对性能有提升,但是系统总内存是有限的,合理分配这些内存才能最大化发挥数据库性能。 其中,DATA_BUFFER_SIZE,SCOL_DATA_BUFFER_SIZE,COLUMNAR_VM_BUFFER_SIZE和VM_BUFFER_SIZE所占内存最多,在不同的业务场景下,这些参数的比重也不一样。此处根据表类型给出一组配置建议:

  1. 如果表类型都是HEAP,建议DATA_BUFFER_SIZE占80%左右,VM_BUFFER_SIZE根据业务类型分配,SCOL_DATA_BUFFER_SIZE和COLUMNAR_VM_BUFFER_SIZE使用默认值。
  2. 如果表类型都是TAC,建议DATA_BUFFER_SIZE占60%左右,COLUMNAR_VM_BUFFER_SIZE占30%左右,VM_BUFFER_SIZE适当分配,SCOL_DATA_BUFFER_SIZE使用默认值。
  3. 如果表类型都是LSC,建议SCOL_DATA_BUFFER_SIZE占50%左右,DATA_BUFFER_SIZE占25%左右,COLUMNAR_VM_BUFFER_SIZE占20%左右,VM_BUFFER_SIZE适当分配。

以上只是建议配置,并不能让所有业务模型都达到性能最优。

# 初始化REDO文件

出于性能考虑,YashanDB基于WAL(Write-ahead logging)机制来保证数据持久化,数据库性能也因此与REDO文件的大小息息相关。通常情况下, REDO文件越大,数据库整体性能越好。当REDO文件较小时,需要频繁的触发检查点机制来释放REDO空间,会对数据库性能造成冲击。

REDO文件是循环复用的,并且旧的REDO文件被复用前,该REDO对应的脏页必须全部刷盘。如果REDO被复用前,对应脏页还没有被Checkpoint刷到磁盘,系统将抛出checkpoint not complete的告警日志,且业务执行会被阻塞,即REDO追尾现象。

当业务量激增,REDO产生的速度超过Checkpoint的速度时,过一段时间后就会发生REDO追尾。通常较大的REDO文件能提供更长的追尾缓冲时间。

REDO文件不宜过小,否则会造成REDO频繁切换。

建议初始创建至少6个REDO文件,每个REDO文件的大小根据磁盘资源设置,范围在100 MB到100 GB的范围,REDO的块大小设置为系统支持的IO块大小。对REDO文件大小设置的一个经验参考是,数据库正常负载下,自动切换REDO文件的时间间隔应该至少为5分钟。

# 初始化表空间

YashanDB存在不同用途的表空间,数据库性能与每种类型的表空间都息息相关。对于内置表空间,如果在建库SQL中不额外指定其信息,系统将创建默认大小的内置表空间,该值一般远小于正常的应用需求。所以用户在创建数据库时,应该根据数据量、并发数、应用场景等不同因素,为所有内置表空间配置合理的初始大小。

# Permanent类型表空间

Permanent表空间用于存储用户数据。在配置表空间中,SYSTEM和SYSAUX表空间一般被用于存储数据库的元数据,对于用户数据建议由单独的用户表空间来存储(使用默认USERS表空间,或者创建新的用户表空间)。

用户应该对数据存储空间有预先规划,存储空间过小或者过大都会带来问题:

  • 表空间太小:实际使用的空间大于表空间容量时,可能导致应用报错。通过打开自动扩展可避免报错,但可能导致应用性能的波动。
  • 表空间太大:空间浪费严重,有可能导致系统资源耗尽的情况。

在规划数据存储空间时,需要考虑以下几个要素:

  • 表空间数量:一般情况下只需要一个表空间即可,但有些场景,例如数据分区,可以选择将数据存储在不同表空间以提升性能和可靠性。
  • 表空间挂载的数据文件数量:YashanDB默认单个数据文件的最大大小为512G,当数据量超过这个大小时,就需要考虑增加多个数据文件。
  • 数据文件的大小和属性:为了避免运行中的自动扩展,应该尽可能通过初始化值满足应用要求的数据文件大小。在配置自动扩展属性时,应当考虑MAXSIZE在规划的容量范围内,避免出现资源耗尽的情况。

需要注意的是,YashanDB在创建数据文件时,采用了空间预占的策略,初始化的时间可能会比较久,建议同时创建多个表空间,以提升初始化效率。

# Undo类型表空间

Undo类型表空间(即内置表空间中的UNDO表空间)用于存储UNDO数据,在回滚、一致性读等场景使用。

与用户数据存储不同,UNDO数据的存储采用循环复用的机制,即超过保留期限(由UNDO_RETENTION参数控制)的UNDO将有可能被覆盖。这要求用户根据实际场景来配置合理的UNDO表空间大小值,如果配置过小,可能导致出现快照过旧的错误;如果配置过大,可能会造成UNDO表空间的空间浪费。

建议结合UNDO_RETENTION参数值进行UNDO表空间的初始化配置:

  • 一般情况下, UNDO_RETENTION越大,UNDO表空间的规划就应该越大。
  • UNDO表空间的初始值可以相对小一些(例如1G),并对其配置合理的扩展属性。
  • 通过参数UNDO_SHRINK_ENABLED和UNDO_SHRINK_INTERVAL打开UNDO的自维护机制,降低用户维护UNDO表空间的难度。

# Temporary类型表空间

Temporary类型表空间用于必要时持久化临时表数据,对其初始大小的配置取决于应用系统中临时表可能被使用的情况。建议初始值不要配置过大,打开自动扩展即可,除非应用系统有明确的临时表需求。

YashanDB中,临时表的存储空间采用预占方式,但只有在BUFFER不足需要换出的时候才会被使用,且在数据库重启之后被重置。因此用户可以考虑如下两方面的调优:

  • Temporary表空间空间不足时,通过RESIZE或者ADD DATAFILE的方式增加容量。
  • Temporary表空间空间过剩时,对其执行SHRINK以释放物理空间。

# Swap类型表空间

Swap类型表空间被用作VM BUFFER的物理交换空间。在SORT,GROUP BY,HASH JOIN等场景中VM BUFFER将被消耗,当VM BUFFER不足时,就需要通过Swap表空间进行换入换出。

用户应该结合VM_BUFFER_SIZE参数值和自身业务状况对Swap表空间大小配置合适的初始值。当无法准确评估时,可以先初始化为一个较小的值,并打开自动扩展。

Swap表空间可能因为某些SQL临时性的被撑大,发现此种情况时,用户可以在空间空闲后通过SHRINK功能释放物理空间。