YggLog.mesa
Copyright Ó 1985, 1987, 1988 by Xerox Corporation. All rights reserved.
Based on AlpineLog.mesa
Last edited by
MBrown on January 30, 1984 10:10:04 am PST
Taft on 16-Feb-82 18:29:44
Hauser, March 8, 1985 10:41:36 am PST
Carl Hauser, October 4, 1985 2:13:27 pm PDT
Bob Hagmann June 13, 1989 1:44:31 pm PDT
DIRECTORY
Basics,
ConstArith,
Camelot,
YggEnvironment;
YggLog: CEDAR DEFINITIONS =
BEGIN
Comparison: TYPE = Basics.Comparison;
logDeviceCharacteristics: YggEnvironment.DeviceCharacteristics;
wordsPerPage: CARD; -- machine dependent words in a Log page
RecordType: TYPE = MACHINE DEPENDENT {
A tag of type RecordType is associated with each log record as it is written. This is used to identify the recovery procedure responsible for the record.
Include lots of spares so that new LogRecordTypes can be introduced without invalidating existing log files. If you change these, keep the corresponding subranges (below) up-to-date.
--ControlRecord-- noop (0), checkpointBegin(2), checkpointComplete (5), startTrans (10), commitTrans (15), abortTrans (19),
--FileRecord-- writeBytes (100),
--Reserved-- reserved (200), (LAST[INTEGER]) }; -- s/b LAST[CARDINAL] but for compiler bug
RecordID: TYPE = ConstArith.Const;
Uniquely identifies a record within a log. This is a 64 bit address space and allows for many, many years of log writing. Units of machine dependent words.
nullRecordID: RecordID = [zero, 0, 0];
No log record is identified by this value.
firstRecordID: RecordID = [zero, 0, 0];
for all r, Compare[firstRecordID, r] # greater
lastRecordID: RecordID = [positive, LAST[CARD], LAST[CARD]];
for all r, Compare[lastRecordID, r] # less
LogRecordPhaseType: TYPE = {
 Identifies during which phase of recovery the record is needed.
analysis, -- only needed in analysis phase (e.g., transaction commit)
redo, -- only needed in redo phase (e.g., writePages)
undo, -- only needed in undo phase
redoUndo, -- needed in both redo and undo phases
other -- other records (e. g., checkpointBegin)
};
Block: TYPE = RECORD [
base: LONG POINTER,
length: CARD, -- in 32 bit words
rest: BlockPtr ← NIL ];
BlockPtr: TYPE = LONG POINTER TO Block;
nullBlock: Block = [base: NIL, length: 0, rest: NIL];
Essentially a list of descriptor for array of 32-bit words. Used both for gather writing (e.g. system puts a header onto each log record) and for scatter reading (e.g. pages that are written contiguously in the log may be buffered in discontiguous virtual memory.)
RecoveryProc: TYPE = PROC [
record: RecordID, type: RecordType, trans: YggEnvironment.TransID,
outcome: YggEnvironment.Outcome];
A recovery proc should call ReadForRecovery, not Read, to access the log
record whose ID is passed to it. Attempting to read any other log record
with ReadForRecovery will result in an error.
RegisterRecoveryProc: PROC [recordType: RecordType, recoveryProc: RecoveryProc];
Any program that writes log records of a particular type is responsible for recovery
of those records. As part of its PROGRAM proc (called by STARTing the module),
the program should call RegisterRecoveryProc once for each type of record it
writes. It is an error to call RegisterRecoveryProc after the update pass of recovery
begins.
ReadForRecovery: ReadProc;
Should be called only from a RecoveryProc, as explained above.
See below for definition of type ReadProc.
Note: Perform recovery before calling any of the procedures below.
Log writing
Write: PROC [trans: YggEnvironment.TransID, logRecordPhaseType: LogRecordPhaseType,
recordType: RecordType, optr: Camelot.optrT, recordData: Block, force: BOOLFALSE, writeID: BOOLFALSE]
RETURNS [thisRecord, followingRecord: RecordID, thisWordNumber: YggEnvironment.WordNumber];
Write the data block in the log. When this returns, the data from the block has been copied, so the block may be modified. If done with force, the block has been stably written to the log before this procedure returns. If trans is NIL, then there is no transaction associated with the record (e. g., a checkpoint record has no transaction associated with it).
WriteFailed: ERROR;
Force: PROC [followingRecord: RecordID];
Force all records prior to (not including) followingRecord to be recorded stably in the online log.
Log reading
ReadProc: TYPE = PROC [thisRecord: RecordID, wordsToSkip: CARDINAL ← 0, to: Block]
RETURNS [status: ReadProcStatus, wordsRead: CARDINAL];
ReadProcStatus: TYPE = {normal, destinationFull, sourceExhausted};
normal means destinationFull and sourceExhausted (normal termination for reading
a fixed-length log record).
Read: ReadProc;
Extracts all or part of the contents of a log record whose type and transaction are
known, placing it in "to". Should be called during normal operation of the server
to carry out intentions.
END.