分配undo回滚段

    每个独立UNDO表空间存在若干个(默认128)个回滚段,而每个回滚段又默认存在1024个UNDO LOG SLOT,分配undo log其实质便是在所有UNDO表空间中找到一个空闲的UNDO LOG SLOT。

    分配回滚段的工作在函数trx_assign_rseg_durable进行,分配策略是采用round-robin方式。

    ‌分配成功时,递增rseg->trx_ref_count,保证rseg的表空间不会被truncate。

    ‌临时表操作不记redo log,最终调用get_next_noredo_rseg函数进行分配;其他情况调用get_next_redo_rseg。

    分配undo log

    从回滚段缓存中分配

    ‌使用cache是为了提升undo log的分配效率。一个undo log在使用完成变得不再有效后便会被释放,一旦满足某些条件,它会被加入到回滚段的undo cache链表,insert 和update undo log有自己独立的链表。

    从cache分配就很简单了,只需要从相应类型的缓存链表中取出第一项,然后初始化这个被复用的undo log即可。这里的逻辑比较简单,就不再赘述了。感兴趣的读者请自行研究。

    如果undo log类型是update,这时候还要创建一个新的undo log header,而不能复用之前undo log。这是因为:这个被缓存的update undo log可能还在history list中尚未被purge。因而,我们只能在原来的undo page中创建一个新的undo log header,这就导致了每个update undo log page上可能会存在多个undo log,与我之前想象的有所不同。

    如果无法从缓存中分配undo log,那也只能退化成来实际分配了,在函数trx_undo_create中执行:

    ‌我们在前面的章节“UNDO LOG物理格式”中说过,创建undo log的关键是分配undo segment。它是个独立的段,每个undo segment包含1个header page(第1个undo page)和若干个记录undo日志的undo page。

    ‌第1个undo page中存储的是元信息: 首先存储的是undo page的元信息,位于TRX_UNDO_PAGE_HDR到TRX_UNDO_SEG_HDR之间。

    ‌因此,如果理解了undo log的物理格式,上面的过程就非常简单了,这里不作过多描述。‌

    UNDO LOG空间不足时如何处理