作者介绍:林锦,腾讯云数据库团队高级工程师,曾任云计算初创公司系统架构师,从事分布式系统研发7年,2017年加入腾讯云,从事NewSQL研发工作,目前主要负责CynosDB for PostgreSQL开发工作。
CynosDB是新一代高性能高可用的企业级分布式云数据库,采用共享存储架构,作为腾讯云NewSQL数据库家族成员之一,由腾讯云数据库产品中心和TEG数据平台部联合打造,满足企业按需分配计算和存储资源,实现弹性调度,动态扩容,节约用户成本,将结合新硬件,新网络,全球分布,自动化等不断演进。本文简要介绍CynosDB for PostgreSQL架构,事务并发机制,缓存管理及数据加载,写数据流程,以及恢复等方面,后续将进一步补充相关信息,本文仅供参考,交流和学习,感谢您阅读!
NewSQL 是一项系统工程,而系统工程是组织管理NewSQL系统规划,研究,设计,研发,测试和使用的科学方法,其综合计算机系统,软件工程,网络工程,项目及产品管理,安全,数据科学,机器学习,运维体系等方方面面,而架构是系统工程的蓝图,供系统在生命周期内的各个阶段(包括研发,管理,实施,运营和运维)提供参考和指导。NewSQL架构与现有系统架构并非完全不同,其中多数技术已存在于传统DBMS,其创新之处在于将这些技术重新梳理,统一整合到一个管理平台中,通过结合当前新硬件,新网络特点,达到高可靠,高可用,高性能,安全,自动化,充分利用资源的目的。
CynosDB 是新一代高性能高可用的企业级分布式云数据库,采用共享存储架构,作为腾讯云NewSQL数据库家族成员之一,由 腾讯云数据库产品中心和TEG数据平台部 联合打造,满足企业 按需分配计算和存储资源,实现弹性调度,动态扩容,节约用户成本,具有多租户,水平扩展存储,融合传统关系数据库、云计算与新硬件,新网络优势,100%兼容PostgreSQL。
[ 图1 CynosDB 全局视图 ]
CynosDB 由两类数据库实例组成:
每个数据库实例可以在1个腾讯云虚拟专用云(VPC) 和 3个专用网络(1个管理专用网+ 2个存储专网) 进行通信:客户应用程序通过 客户VPC 与数据库实例 进行交互,数据库实例 所在节点上的Agent 进程通过 管理专用网络 与 管控平台 进行交互,数据库引擎 通过 存储专用网络 与 存储服务 进行交互,而 存储服务 与 冷备存储系统 通过存储专用网络进行传输,各个专用网络 相互隔离,遵从 1987年,关系数据库设计者C.J.Date在《Distributed Database: A Closer Look》中提出12条规则的 本地自治 + 位置透明和独立性 + 可持续操作 + 硬件独立性 + 网络独立性 等原则。
[ 图2 CynosDB 架构 ]
CynosDB使用 腾讯云数据库运营平台 作为控制面板,由 实例管理器(Instance Manager) 向 资源管理器(Resource Manager) 注册申请一个对象池Pool,然后创建和部署 CynosDB 数据库实例,并在该数据库实例的 VPC 上安装一个代理(Agent)进程,负责监视数据库实例的运行状况,其根据实例运行情况进行故障切换或更换实例。 资源管理器(Resource Manager) 根据Pool注册信息初始化一个 称为 段组 SegmentGroup 的调度单元,根据调度规则选择最佳节点做为该数据库实例的物理存储,调度规则将参考Pool信息,根据 装箱算法 从可用区开始,依次筛选数据中心,机架,物理节点,磁盘容量,以及结合当前整个CynosDB 运行情况(IO + 网络 + 容量),选择最佳节点。 存储管理器(Storage Manager) 负责管控 CynosDB物理存储资源以及备份和恢复数据需要的详细信息,对于长时间运行的操作,如存储节点故障后的数据库恢复或修复(重新复制)等操作,使用 异步机制 通过后端作业进行调度,为保持高可用性,指标采集服务持续监控存储操作的所有关键方面,积极主动,自动化的探测实际的和潜在的问题,如关键性能或可用性指标发现问题就会触发警报而引起关注。存储服务 部署在 访问管理CAM 上,并配置多个存储磁盘(SSD),存储节点之间采用RDMA技术进行数据的高效传送,存储节点维护本地SSD与数据库引擎实例,其他对等存储节点以及备份/恢复服务进行交互,备份/恢复服务把数据库物理日志持续备份到COS平台,并定期增量数据 备份到COS平台,这样可以按时间点进行数据的快速恢复。
CynosDB 特点:
[ 图3 CynosDB 数据模型 ]
说明:
PageHeaderData 字段:
pd_lsn: identifies xlog record for last change to this page.
pd_checksum: page checksum.
pd_flags: flag bits.
pd_lower: offset to start of free space.
pd_upper: offset to end of free space.
pd_special: offset to start of special space.
pd_pagesize_version: size in bytes and page layout version number.
pd_prune_xid: oldest XID among potentially prunable tuples on page.
在1992年在LFS首次出现日志结构存储,通过只写数据页的变更来减少写放大,以REDO日志方式,跟踪事务确认回复最大的LSN,而CynosDB 存储 采用 日志写 + 块读方式 实现 日志结构的存储系统,对于写是日志流,而读操作支持MVCC的块操作。
[ 图4 CynosDB 存储IO ]
CynosDB IO 流:
RDMA/SPDK 主要用于存储 数据块 传输,以及RAFT member 之间数据传输。
在RDBMS中采用并发控制保证数据的一致性和隔离性, 三种并发控制机制:Multi-version Concurrency Control(MVCC), Strict Two-Phase Locking (S2PL), 和 Optimistic Concurrency Control (OCC), PostgreSql 使用 Serializable Snapshot Isolation (SSI) 的 MVCC,新数据项将直接插入相关表页面,在读数据项时,通过应用 可见性检查规则 来选择合适版本的数据项来响应单个事务,使用SSI 进行DML(数据操作语言,例如SELECT,UPDATE,INSERT,DELETE),使用2PL进行DDL(数据定义语言,例如CREATE TABLE等)。
缓存管理器管理共享内存和对象存储之间的数据传输,包括 缓存表(buffer table), 缓存描述符(buffer descriptors), 缓存池(buffer pool) ,所有数据文件的每个页面分配唯一标记,即缓冲标记buffer_tag,buffer_tag包含三个值:RelFileNode,ForkNumber,BlockNumber。 如buffer_tag '(201808,0,9)' 表示第9个块中的页面,其OID和fork号分别为201808和0。参考 buf_internals.h
CynosDB 加载数据页
[ 图5 CynosDB 加载新页 + 淘汰算法]
假设访问的数据页不在缓存中,且当前缓存满,需淘汰页(如是脏页,则需刷新脏页),然后加载新页
[ 图6 CynosDB 写入过程 ]
CynosDB写操作将所有 数据页或索引页 的修改(包括插入,删除或提交操作)作为历史数据SLOG写入持久存储,以应对故障,当事务提交/中止时,立即写到存储系统,以下是写数据 A 到TABLE_A 的过程:
说明:关于 全页写,因后台写进程刷脏页时,由于机械盘故障导致数据页损坏,而且根据XLOG记录无法在损坏的页面上重放来恢复(可通过全量XLOG恢复,但代价极大),故PostgreSQL采用全页写方式来解决此问题,在每个检查点后,每个页面的首次更改时将整个页面作为XLOG记录,这种XLOG记录也称为备份块,CynosDB 对此进行优化,移除 全页写 和 Checkpoint.
传统的数据库都依赖于类似 ARIES 恢复协议来实现故障恢复,而CynosDB 使用状态机复制技术 State machine replication来避免故障恢复, 不需要REDO恢复,这是因为CynosDB 只会将已经提交的更新写入到存储。由于重做日志应用程序与数据库实例分离,交给存储层,在存储层以并行、异步、分布式的方式进行REDO操作,所以数据库可以很快恢复。数据库实例启动后,将与存储服务协同恢复以重建其运行时状态,首先从 资源管理器 获取该数据库实例所拥有的SG(Segment Group),计算出每个Segment的VDL,产生截断范围,消除VDL之后的日志记录(SLog的LSN大于VDL的记录),对该范围内的日志进行存储,产生新的VDL。
事务日志: 在计算机科学数据库领域,事务日志(数据库日志,二进制日志或审计跟踪)是数据库管理系统用于保证ACID属性而执行的历史动作,保存在稳定存储中,记录一系列数据库变更的文件。当发生崩溃或硬件故障时,重启系统后发现数据库处于不一致状态或未正确关闭,则数据库管理系统将检查未提交事务日志并回滚这些事务所做的更改,所有已提交但尚未在数据库物化的事务则重新应用日志,两者都是确保事务的原子性和持久性。在PostgreSQL数据库中 XLOG 或 WAL 日志为 事务日志。
日志序列号LSN(Log Sequence Number): 是日志记录的唯一标识, 以单调递增顺序进行分配,这在 ARIES 恢复算法中很有用。
预写日志记录WAL(Write-ahead logging): 在数据库系统中,对于一个对象的任何更改,首先记录在日志中并保证其写入到稳定存储,然后将对象的更改写入磁盘,是提供原子性和持久性的一系列技术。
PostgreSQL事务ID(txid): 每当事务开始时,事务管理器就会分配一个具有唯一标识符的事务id(txid),txid是一个32位无符号整数,在事务启动后可通过执行内置函数txid_current()查看当前txid。由于实际系统txid空间不足,将txid空间当作一个圆,当达到最大值后,从新开始,循环使用。不会为BEGIN命令分配txid,当执行BEGIN命令后执行第一个命令时,事务管理器会分配tixd,然后启动其事务。
PostgreSQL 元组(Tuples): 由 t_xmin + t_xmax + t_cid + t_ctid + t_xvac + t_infomask2 + t_infomask + t_hoff + t_bitsFLEXIBLE_ARRAY_MEMBER + USER DATA 组成, t_xmin 保存插入此元组时的事务txid, t_xmax保存删除或更新此元组的事务的txid。 如果尚未删除或更新此元组,则t_xmax设置为0,表示无效。t_cid保存命令id(cid),表示从0开始的当前事务执行多少个SQL命令。t_ctid保存指向自身或新元组的元组标识符(tid), 更新此元组时,此元组的t_ctid指向新元组; 否则,t_ctid指向自己。
可见性规则(Visibility check rules): 可见性检查规则是一组使用元组Tuples的t_xmin和t_xmax,clog以及获取事务快照来确定每个元组是可见还是不可见的规则。
提交日志CLOG(Commit Log): 在CLOG中保存事务的状态,CLOG被分配给共享内存,并在整个事务处理过程中使用, 事务的状态包括:IN_PROGRESS, COMMITTED, ABORTED, 和 SUB_COMMITTED.
事务快照(Transaction Snapshot) 事务快照是一个数据集,用于在单个事务特定时间点存储有关所有事务是否处于活动状态的信息。这里的活动事务表示正在进行中或尚未开始,PostgreSql内部将事务快照表示格式定义为“100:100:”, 表示'小于99的txids未激活,并且等于或大于100的txids处于活动状态'。
-- DONE --
更多前沿数据库技术和案例分享,请关注我们的微信号:腾讯云数据库CDB
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。