实时事务调度
实时事务调度并非易事。数据库必须保证逻辑一致性,同时安排事务以满足其截止期限,并尽量减少错过截止期限的事务数量。我们提供两种主要的调度策略:
高优先级最早截止期限优先(EDF)算法:事务首先按优先级排序,然后在相同优先级内按截止期限排序。相应的事务管理器基于 MURSIW。
优先级继承(PI)算法:事务管理器(PI-TM)依赖于实时操作系统(RTOS)的调度,并通过特定使用操作系统同步原语提供必要的提示。创建数据库时分配固定数量的同步原语作为互斥锁。事务开始时,线程获取一个或多个互斥锁(只读事务随机选择一个;读写事务获取所有互斥锁,防止死锁),并在事务结束时释放它们。操作系统调度程序可以识别持有关键互斥锁的线程,并在需要时应用“优先级继承”,即临时提高低优先级线程的优先级,使其更快完成并释放互斥锁(例如,在 Linux 和 FreeRTOS™ 中)。更多解释见“EDF 与 PI-TM”。
同步原语的数量由 mco_db_params_t.max_pi_readers 设置,定义了可并行运行的只读事务的最大数量。默认值为 1,意味着 PI-TM 行为类似于 EXCL(mcotexcl)。建议将 max_pi_readers 设置为不超过 CPU 核心数。如果启动了多个只读事务,其中 max_pi_readers 个事务将运行,其余事务将等待,直到至少有一个正在运行的事务完成。PI-TM(mcotmpi)支持的操作系统包括 Linux、LynxOS-178®、FreeRTOS、embOS、INTEGRITY™ 和 VxWorks™。
事务执行由事务管理器控制,确保正确的序列化(读写事务按顺序执行,只读事务在没有读写事务时并行执行)。优先级规则如下:
- 高优先级读写事务会抢占所有低优先级只读事务(先回滚),除非有更高优先级的只读事务正在运行。此时,读写事务根据其优先级和截止时间排队。
- 如果新事务的截止时间早于当前事务的剩余时间,高优先级只读或读写事务会抢占低优先级读写事务(先回滚)。否则,不会抢占,以避免两个事务都回滚。
SmartEDB/rt 事务管理器在多个验证检查点测试事务的运行时间,确保不超出设定的截止期限。如果事务用完分配的时间片,则被标记为“事务中断”状态(MCO_E_INTERRUPTED),控制权返回给应用程序。应用程序应回滚事务,事务管理器确保数据库恢复到一致状态,并在应用程序响应时保证回滚在截止期限内完成。因此,事务可能错过截止期限但不会导致内部不一致。
EDF与PI-TM
在包含高优先级线程(H_DB)、低优先级线程(L_DB)和不与数据库交互的中优先级线程(M)的情况下,PI-TM 具有显著优势。
考虑以下场景:L_DB 启动事务后,M 线程因优先级更高而抢占 L_DB,将其暂停。随后 H_DB 到达,但由于 L_DB 正在执行事务,H_DB 无法立即启动新事务。在 EDF 调度下,H_DB 必须等待 L_DB 完成事务。而在 PI-TM 中,操作系统会在 H_DB 到达时临时提升 L_DB 的优先级,使其抢占 M 并完成事务,从而为 H_DB 让出路径。
对于 CPU 密集型事务的 PI-TM,应考虑以下要点:
- 初始分配的同步原语数量应等于 CPU 核心数。允许的只读事务数量不应超过可同时运行的核心数,否则会增加每个事务的执行时间。
- 分配的同步原语越多,启动读写事务越困难,因为它可能需要等待所有竞争的只读事务释放其原语。因此,PI-TM 更适用于具有 1 至 4 个 CPU 内核的硬件配置。
“先发制人”模式
当设置以下选项时:
db_params.mode_mask |= MCO_DB_PREEMPTIVE;
具有更高优先级(在 MCO_TRANS_PRIORITY 意义上)的事务将抢占正在运行的低优先级事务,并立即终止它们,同时返回 MCO_E_INTERRUPTED 错误。
此选项既适用于 EDF 事务管理器,也适用于 PI 事务管理器。