构建 OLTP 核心:API 契约、分页大小与自适应调优
新一代 OLTP 数据库开发者采用 Rust 中的 trait 接口,构建了严格的隔离层架构。每层都有明确的 API 契约,按表空间可配置分页大小,配置由资源经纪器管理,无需手动调优。诊断功能通过 USDT 和 eBPF 集成。
分页大小与表空间配置
数据分页大小针对纯 OLTP 场景为 4-8 KB,HTAP 场景在 NVMe 上为 16-32 KB。每个表空间是一个独立文件,创建后分页大小固定。默认值为 16 KB。PageId 为复合结构:[tablespace_id:16][page_index:48]。BufferPool 根据大小将请求路由到子缓存。
文件开头的超级块独立存储表空间元数据,与分页大小无关。挂载时检查配置,不匹配则拒绝启动,避免性能退化。
架构层与 API 契约
核心分为四层:
- 适配层 (async tokio):终止 TLS,解析网络协议。
#[async_trait]
pub trait NetworkAdapter {
async fn handle_connection(&self, stream: Box<dyn ConnectionStream>) -> Result<(), NetworkError>;
}
- 兼容层:解析 SQL 为 AST,模拟 pg_catalog,转换为 LogicalPlan,拒绝不支持特性(错误码 0A000)。
pub trait CompatLayer {
fn translate_query(&self, ast: SqlAst) -> Result<LogicalPlan, CompatError>;
}
- 核心引擎 (sync):优化器、执行器、事务管理器。在 spawn_blocking 池中运行。
pub trait ExecutionEngine {
fn execute_plan(&self, plan: LogicalPlan, session: &Session) -> Result<ResultSet, ExecutionError>;
}
- 存储管理器:PageProvider 和 TransactionLogSink 的门面。核心请求页面和 UNDO 记录。
pub trait StorageManager {
fn pin_page(&self, page_id: PageId, mode: LockMode) -> Result<PageGuard, StorageError>;
fn append_undo(&self, txn_id: TxnId, record: UndoRecord) -> Result<UndoPtr, StorageError>;
}
层间边界防止细节泄露:锁指标排除异步等待。
自适应调优与资源经纪器
约 60 个参数分为预算、护栏和覆盖。操作符设置高层限制:
[resources]
memory_budget = "16GB"
cpu_budget = "auto"
io_iops = 5000
顾问(MemoryAdvisor、IoAdvisor、CpuAdvisor)每秒重新分配资源:
- CpuAdvisor:DOP 和线程池 vs 限流。
- MemoryAdvisor:负载下 BufferPool vs work_mem。
- IoAdvisor:事务优先级,云端突发感知。
防护机制
- 迟滞:5 秒窗口,5% 步进,避免振荡。
- 硬底线:BufferPool/UNDO 最低 128 MB。
- 平滑过渡:新分配应用新限制。
- 专家覆盖优先于自动调优。
后台 UNDO 日志清理取代 VACUUM。运行时变更无需重启。
诊断:USDT 探针与 eBPF
诊断机制内置二进制中。USDT 探针用于运行时分析,eBPF 用于零开销追踪。
关键要点:
- 按表空间分页大小,启动时检查。
- 层间严格 trait 契约防泄露。
- 资源经纪器:预算 → 带护栏自动调优。
- 核心集成 eBPF/USDT 诊断。
- 摒弃手动调优,转向自适应机制。
— Editorial Team
暂无评论。