Prev: memory-management Next: record-management
One of the major features relational databases support is transactions.
The transaction API in SimpleDB looks like the following:
struct Transaction {
: FileMgr,
fm: LogMgr,
lm: BufferMgr,
bm}
trait Transactions {
fn pin(&self, blk: BlockId);
fn unpin(&self, blk: BlockId);
fn get_int(&self, blk: BlockId, offset: i32) -> i32;
fn get_str(&self, blk: BlockId, offset: i32) -> String;
fn set_int(&self, blk: BlockId, offset: i32, val: i32, ok_to_log: bool);
fn set_string(&self, blk: BlockId, offset: i32, val: String, ok_to_log: bool);
fn available_buffs(&self) -> i32;
fn size(&self, filename: String) -> i32;
fn append(&self, filename: String) -> Block;
fn block_size(&self) -> i32;
}
The Recovery Manager is the portion of the database engine that reads and processes the log.
To be able to roll back a transaction, the recovery manager has to log information about the transaction’s activities.
There are four kinds of log records:
Rollback allows a transaction to be undone.
The general algorithm looks like this:
As well, the log is used for recovery. Any uncompleted transactions are rolled back, and all committed transactions have their modifications written to disk.
The undo stage might look like this:
The redo stage might look like this:
The Simpledb recovery manager looks like the following:
struct RecoveryMgr {
: Transaction,
tx: i32,
txnum: LogMgr,
lm: BufferMgr,
bm}
trait RecoveryManagement {
fn commit(&mut self);
fn rollback(&mut self);
fn recover(&mut self);
fn set_int(buff: Buffer, offset: i32, val: i32);
fn set_string(buff: Buffer, offset: i32, val: String);
}
Each log record implements an undo method, its transaction number, a way to write itself to a log, and deserialize itself.
As well, there is a lock manager that is used to implement transactions.
Prev: memory-management Next: record-management