Skip to content

Commit 6e79728

Browse files
committed
add
1 parent cd65943 commit 6e79728

File tree

2 files changed

+11
-2
lines changed

2 files changed

+11
-2
lines changed

aries_10.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@ System R 使用的影子页技术并不需要page_LSN来决定哪些需要undo
2727
如果记录9是一个提交记录,那么在undo遍历的时候,记录2就会被undo,并且在redo遍历时,记录4,5会被redo。因此在undo遍历和redo遍历中会涉及相同的事务。接来看一下,在SystemR中为何undo遍历要在redo遍历之前执行,考虑到下面的场景:若某个删除了一条记录,该记录的ID可以被重用,并被相同的事务用来插入新记录。在这一的情况下,一条记录可能会在部分回滚时被删掉,这会在undo遍历中处理。然后该记录ID可能会在事务的其他地方被重用,这会在redo遍历中处理。为了针对系统崩溃前的原始操作顺序进行历史重演,那么undo必须在redo之前执行。
2828
如果9不是‘提交’或者‘准备’记录,那么该事务就认为是个失效事务,在undo遍历的时候,记录2,1都会被undo。在redo遍历的时候,就没有记录需要redo了。
2929
由于System R不会写CLR ,一个事务的undo操作被其他事务的正常流程或者undo流程所打散了,所以具体的undo方式就不知道了。在恢复时对于页的处理会和正常流程有很大不同(比如:历史重演也无法保证)。System R中没有索引变更日志记录也造就了这一点(参见脚注8)。这可能会导致一些空间分配上的问题,比如在正常流程的时候没有分裂,但是在重启时,redo或undo过程中会触发分裂(参见5.4节)。不生成CLR同样会阻止redo的日志信息被物理执行(比如:对于某个对象的操作会被日志记录--而不是记录这个操作之后的镜像)。考虑如下的一个例子:在最近一次checkpoint之后有块数据值为0。然后事务T1加1,T2加2,T1回滚,T2提交。如果T1,T2都记录数据镜像来redo以及其操作来undo。那么就会导致数据不一致问题,因为在恢复后,该值为3而不是2。在这种情况下,System R对事务T1的undo是通过不redo它的操作来完成的。当然,System R并不支持高级锁模型,来使得2个事务可以同时修改相同的对象。使用逻辑dumb从而允许redo物理信息,可以高效的执行redo恢复。这并不意味着面向字节的日志需要依赖是否使用了弹性存储管理(参见10.3节)。记录逻辑undo信息就能支持高并发的undo(参见【59,62】)。ARIES都支持这些。
30-
WAL系统是通过在回滚时使用CLR来解决这一问题。所以当恢复是,数据的状态通常是“marching”前进的,即使一些原始操作以及被回滚了。【52】中提出的一个不同的方案,被LSN标识的数据将会在回滚时被“pushed”回去。这种方案只能在页级(或更粗颗粒度)锁下工作。输出CLR的最直接的后果是,如果事务要回滚了,那么一些原始操作会被重复undo,更糟的是,补偿动作也会重复undo。如图4所描绘的:事务在系统崩溃前开始回滚。那么在恢复时,之前写的CLR被undo了,已经被undo的non-CLR又被undo了一遍。ARIES会避免这种情况,当然仍然会输出CLR。不undo CLR有利于死锁管理,并且可以早点释放带undo对象上的锁(参加22项,12节和6.4节)。CLR的其他优点会在下一节和【69】中讨论。有一些我们已经在第8节中讨论了。
30+
WAL系统是通过在回滚时使用CLR来解决这一问题。所以当恢复是,数据的状态通常是“marching”前进的,即使一些原始操作以及被回滚了。【52】中提出的一个不同的方案,被LSN标识的数据将会在回滚时被“pushed”回去。这种方案只能在页级(或更粗颗粒度)锁下工作。输出CLR的最直接的后果是,如果事务要回滚了,那么一些原始操作会被重复undo,更糟的是,补偿动作也会重复undo。如图4所描绘的:事务在系统崩溃前开始回滚。那么在恢复时,之前写的CLR被undo了,已经被undo的non-CLR又被undo了一遍。ARIES会避免这种情况,当然仍然会输出CLR。不undo CLR有利于死锁管理,并且可以早点释放待undo对象上的锁(参加22项,12节和6.4节)。CLR的其他优点会在下一节和【69】中讨论。有一些我们已经在第8节中讨论了。
3131
不幸的是,像【92】中提到的恢复方法并不支持部分回滚。我们认为这是这类方法的一大缺陷。
32-
32+
**10.3 Space Management空间管理**
33+
本小节的目标是指出空间管理中一些问题:当使用比页级低颗粒度锁时,以及如果高效的支持变长数据存储。
34+
使用弹性存储来执行纪录锁时需要处理的一个问题是:需要确保一个事务在对某个数据进行删除或更新时造成的空间释放,在该事务提交前不会被其他事务使用。该问题在【76】中有详细讨论。在此我们并不讨论空间预留问题。对此感兴趣的读者可以参考【50】。对于索引更新,特别是并发增加,我们并不希望一个事务提交之前,其他事务都没法使用。在这种情况下,undo是使用逻辑undo的处理方式,在【62】中有详细描述。
35+
由于弹性存储管理是其目标,若使用物理(比如面向字节的)锁并且将数据都记录在一个页中,正如一些系统所做的(参见【6,76,81】),这是不能接受的。也就是说我们不想使用记录的第一个字节作为该记录的锁名字。我们也不希望用一些特殊字节来标识待修改的页。日志和锁必须在页中合理执行。记录锁的名字会使用一些类似(page#,slot#),slot#标识该页的位置,这会指向记录的真实位置。日志记录描述了该数据记录是如何变更的。结果就是垃圾回收器会搜集该页上未使用的空间,并且在页中移动数据时,不需要加锁或者记录日志。这使得我们可以高效的移动变长数据记录,可以在页中随意移动记录。在类似IMS系统中,需要经常运行工具来处理存储碎片。这对用户来说,降低了数据可用性。
36+
图19展示了一种场景:无需跟踪特定表的状态(比如,在持久化存储的页中存储LSN),并且尝试从日志的一个较早的时刻执行redo直到有问题的地方,这里使用了弹性存储管理。假设,图19中的更新都是对于同一个页,同一个事物,它像插入一个200字节的数据到该页上,但是只有100字节的剩余空间。这显示了需要对页状态的准确跟踪,并使用LSN来避免尝试redo已经执行到该页上的操作。
37+
通常,每个文件会包含一些有关系的记录,使用少量的页,这些页被称之为空闲空间目录页(FSIP)。在DB2中称之为SMP。每个FSIP描述了很多数据或索引页的空间信息。在插入记录的时候,通常会基于从聚集索引获取的信息,聚集索引记录了相同key(或者相近有关key)的不同记录的位置,对于插入新记录,会向一个或多个FSIP请求空闲空间。FSIP只有一个模糊信息(比如:至少该页的25%是满的,至少50%是满的等等。)。这样就能确保不是每次空间释放或者申请都会导致该页的信息修改。为了避免在redo和undo对FSIP恢复做特殊处理,并且提供恢复独立性,对于FSIP的更新也必须记录日志。
38+
事务T1可能会导致数据也从23%满到27%满,因此就会更新FSIP从0%满到25%满。接着T2可能导致空间变为35%慢,这并不需要更新FSIP。现在如果T1回滚了,那么空间变为31%满,同样不会更新FSIP。如果T1将FSIP的变更日志作为redo/undo记录,那么T1的回滚就会导致FSIP变为0%满,考虑到当前数据页的实际情况,这就不正确了。该场景表明了对于FSIP的变更只能记录redo-only日志,并且对空闲空间目录的变更只能做逻辑undo。也就是说,在做数据页更新的时候,系统要判断该操作是否会影响空闲页信息的变更,如果确实影响了,那么就需要更新FSIP,并且输出描述该变更的CLR。我们很容易构造一个例子:事务在正常流程时对FSIP不更新,但是在回滚的时候需要对其更新。我们同样可以构造一个例子:在正常流程中的更新并不是回滚时完全相反的操作。
39+
**10.4 Multiple LSNs多重LSN**
40+
如果每个页只有一个LSN会有问题:当我们想支持记录锁是,可能需要跟踪每个对象的状态,这样就要给每个对象分配独立的LSN了。接下来我们会解释这不是一个好方案。
41+
DB2已经支持低于页级别的锁了。这在索引上会使用,如果用户要求DB2将索引的页节点从2个分割成16个最小页时,就需要对这个最小页加锁【10,12】。DB2对这些页恢复时,在redo遍历时不会redo失效会话的操作,如下面所示。除了对页节点使用LSN,DB2通过每个最小页上的LSN来跟踪其状态。当最小页更新是,相应记录的LSN会存在最小页的LSN域中。页的LSN被设置成这群最小页中的最大LSN值。在undo的时候,是使用迷你页的LSN,而不是页LSN来和日志记录比较,去判断改记录是否需要在该迷你页上undo。这种技术,除了会导致使用更多的空间来存储LSN,也会是的空间碎片化(并且会浪费)来存储Key。更进一步,它并不能很方便的对记录和key加锁,尤其当需要高效的支持变长数据对象时。对删除的对象维护LSN也是最费力的。我们希望每个页只有一个单独的状态变量(LSN),即使对迷你页加锁,然后进行恢复,特别是介质恢复,也能高效执行。在重启恢复时,在失效事务回滚之前,使用ARIES中简单的历史重演技术足够满足需求了。由于DB2将页分割成固定个数的迷你页,不需要特别的考虑空间预留问题。像【61】中建议的支持低颗粒度锁的方案,不支持变长数据存储(那篇论文中使用了atom)

img/fig19.png

14.2 KB
Loading

0 commit comments

Comments
 (0)