接上篇内容
插入性能优化
YashanDB行式存储主要从提供并发度、批量化处理以及减少日志产生三方面对事务处理过程中的插入性能进行了优化:
1
提高并发度
单线程插入的速度是有限的,在资源充足的场景下,我们希望通过增加线程来提高导入数据的速度。由于数据块不能同时写入,如果两个线程要在同一个数据块上插入数据,就会产生等待。因此我们希望多个线程插入数据的时候,尽量离散到不同的数据块上。
YashanDB采用ASSM(Auto Segment Space Management)管理数据块的空闲度,插入数据通过ASSM随机查找一个可用的数据块,ASSM会将不同的Session、不同的实例尽量随机到不同的数据块上,降低块冲突,提高并发度。
2
批量插入
如果插入数据时,选择一条一条插入会产生多次重复工作,每插入一条数据,就要写一次数据块、一条Redo、一条Undo, 因此我们将多行数据合并,一次写入数据块,同时合并Redo、 Undo,减少写操作的次数,Redo、Undo合并也可以减少Redo/Undo的头信息占用的空间。
3
Nologging
进行DML的时候,记录Redo是为了数据库宕机后重启可以恢复数据,记录Undo是为了保证DML并发的数据一致性。在导入数据的过程中,记录Redo、Undo会花费大量的时间。
考虑数据迁移的场景,用户创建表之后,会导入大量的数据,这个过程中,对于正在导入的表一般不会有其他的业务诉求,且表数据的完整性、正确性都能保证,也不会考虑导入出错需要回滚的场景。
基于上述应用场景,我们实现了一种简单高效的Nologging导入,在导入的过程中,不记录Redo、 Undo,限制导入过程中除了Insert之外的DML、DDL。执行完Nologging导入,将表设置成Logging,执行全量检查点,保证数据块都已将全部刷到磁盘。
行存储结构
YashanDB的单行长度远大于单个数据块的大小,因此需要将单行存储在不同的数据块上。同时在update操作时,原始的行有可能会变长,导致当前数据块没有足够的存储空间,需要分配分配新的空间。YashanDB针对宽行设计了行链接、行迁移机制:
1
行迁移
当行数据经过Update变大,有可能行所在数据块的空闲空间不足,需要将行数据迁移到另一个数据块,原位置保留一个行头。
图4 行迁移机制
2
行链接
当行长度超过单个数据块的最大容量时会将行切分成多个分片,存储在不同的数据块上。
图5 行链接机制
行的每个分片可以单独修改,分片在行数据发生变化后,也可以自动收缩,这样在操作宽行时可以按需访问,有效保证了宽行数据的访问处理性能。
总结
YashanDB采用了细粒度并发控制、免锁事务优化等先进技术,进行了高效的行式存储设计,能够实现快速查询、数据一致性以及高效的数据访问,这对于数据库系统的性能和可靠性具有极其重要的意义。未来YashanDB将从数据压缩、数据分层存储、行列混合计算等方面优化行式存储能力,进一步提升数据库事务处理能力以及混合负载能力,降低数据存储成本,提高数据处理性能。