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 May 9, 1988 1:34:57 pm PDT
DIRECTORY
Basics,
YggCoordinator,
YggEnvironment,
YggInternal;
YggLog: CEDAR DEFINITIONS =
BEGIN
Comparison: TYPE = Basics.Comparison;
logDeviceCharacteristics: YggEnvironment.DeviceCharacteristics;
wordsPerPage: CARD; -- words in a Log page
RecordType: TYPE = YggInternal.LogRecordType;
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.
RecordID: TYPE = YggInternal.LogRecordID;
Uniquely identifies a record within a log. This is a 64 bit address space and allows for many, many years of log writing.
nullRecordID: RecordID = YggInternal.nullLogRecordID;
No log record is identified by this value.
firstRecordID: RecordID = YggInternal.firstRecordID;
for all r, Compare[firstRecordID, r] # greater
lastRecordID: RecordID = YggInternal.lastRecordID;
for all r, Compare[lastRecordID, r] # less
LogRecordPhaseType: TYPE = YggInternal.LogRecordPhaseType;
Identifies during which phase of recovery the record is needed.
Block: TYPE = RECORD [
base: LONG POINTER,
length: CARD,
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: YggInternal.TransHandle,
outcome: TransState];
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.
TransState: TYPE = YggInternal.TransState;
{committed, aborted, ready}
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: YggInternal.TransHandle, logRecordPhaseType: LogRecordPhaseType,
recordType: RecordType, recordData: Block, force: BOOLFALSE]
RETURNS [thisRecord, followingRecord: RecordID];
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).
CoordinatorWrite: PROC [
trans: YggCoordinator.Handle, recordType: RecordType,
recordData: Block, force: BOOLFALSE]
RETURNS [thisRecord, followingRecord: RecordID];
! WriteFailed (online log is full - server should restart).
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.
CHANGE LOG
Created by MBrown on 2-Dec-81
Changed by MBrown on 16-Dec-81 15:06:20
Initialize takes a File.Capability, not the name of a server.
Changed by MBrown on 1-Feb-82 15:10:32
Define interface that is decoupled from handles defined in other parts of Alpine.
Change from stream to stateless style reading. Use 48 bit log record ids throughout.
Changed by MBrown on 2-Feb-82 11:09:06
Add workerComplete to RecordType enumeration.
Changed by MBrown on June 23, 1982 4:16 pm
Use AlpineEnvironment.FileID, not File.Capability; introduce Error and LogFailure.
Changed by MBrown on September 14, 1982 12:34 pm
Move "Initialization and recovery" section to LogBasic.
Changed by MBrown on September 15, 1982 8:39 pm
Added RegisterRecoveryProc, merged various forms of invalidRecordID, eliminated Release
(still in LogBasic).
Changed by MBrown on October 2, 1982 8:25 pm
Moved Format and Recover to LogControl. next ← NIL in Log.Block.
Changed by MBrown on October 3, 1982 10:42 pm
Error -> LogFull (all other errors are really caller programming errors).
recordExhausted: BOOL -> status: ReadProcStatus.
Changed by MBrown on October 7, 1982 5:09 pm
ReadForRecovery introduced, and the readProc parm to RecoveryProc dropped.
Changed by MBrown on October 11, 1982 3:21 pm
Added largestRecordID.
Changed by MBrown on November 3, 1982 11:59 am
Changed trans arg to Write from TransID to TransHandle; added CoordinatorWrite.
Changed by MBrown on January 30, 1984 10:10:13 am PST
Changed Environment -> Basics for Cedar 5.0.
Hauser, March 8, 1985 10:41:10 am PST
Nodified, added copyright.