Module 08

Transactions, journals, locks & recovery

Every change is written to a log before it is written to the data. That log is how the database survives a crash — and it is also the entire source of truth for software that keeps a copy of this data somewhere else. Everything in this module is load-bearing for Module 10.

~50 min1 simulator10-question checkpoint
What this module is really about

The change log, and why it is the most important file on the machine as far as you are concerned.

The database writes a description of every change to that log before it writes the change itself. That is what makes crash recovery possible. It is also what makes replication possible, because the same log is what a copying tool reads.

So the single most consequential fact in this course lives here: if a change never reaches the log, no copy of this database will ever know about it — and there are legitimate ways for that to happen.

New words on this page, one line each
journal
The change log. A diary of every alteration, written before the alteration itself.
write-ahead logging
The rule that the diary entry is safely on disk before the data is touched.
before-image / after-image
A copy of a record as it was, and as it became. One is used to undo, the other to redo and to build your copy.
checkpoint
A marker meaning “everything up to here is safely saved”.
archive
Older log files moved off to tape or another dataset. Kept for a fixed time, then reused.
warm start
Automatic recovery after a crash: unfinished work undone, finished work kept. No operator action.
rollforward
Recovery after losing a disk: restore an old copy, then replay the log forward.
cold start
Restarting without reading the log at all. Fast, and it can leave data the log no longer explains.
deadlock
Two programs each holding what the other is waiting for. The database spots it and cancels one.

Write the diary first, then move the card

Picture it

Before the clerk moves a card, they write in the day book what the card said and what it is about to say. Only then do they move it.

If the lights go out halfway through, the day book always contains enough to work out what happened and put it right — either finish the move or undo it. That is the whole trick, and every durable database does some version of it.

The rule is the same one every durable database follows: the log record describing a change is hardened before the data page containing that change is written. If the system dies at any instant, the journal always contains enough to reconstruct or undo whatever state the data pages are in.

IDMS journals hold record images. A change to an occurrence produces a before-image and an after-image of that occurrence, tagged with enough identification to know exactly which occurrence it was.

The journal record types you will see named. Exact codes and additional types vary by release.
TypeWritten whenContains
BGINA run unit starts updatingRun-unit identity, program, time
BFORBefore a record is changed or erasedThe prior image of the occurrence — used to undo
AFTRAfter a record is stored or changedThe new image — used to redo
CKPTA COMMIT is issuedA durable point for this run unit
ENDJThe run unit finishesNormal completion marker
Why images rather than operations matters A journal of operations would say "increase salary by 4%". A journal of images says "this occurrence was X, and is now Y". The second is far friendlier to change data capture: you can construct a complete target row from the after-image alone, and you can compute exactly which columns changed by comparing before and after. You do not have to replay application logic.

How the log fills up, and what happens to the old ones

The part that becomes your problem

There is a fixed set of log files, used in rotation. When one fills, it is copied off and eventually reused.

Recovery only needs those copies for a day or two, so that is usually how long they are kept. But your copying software reads the same files. If it is offline for longer than the retention period, the changes it missed no longer exist anywhere, and the only way back is to copy the whole database again from scratch.

This is why retention is a project dependency you negotiate in writing, not an operational detail you inherit.

A CV has several disk journal files, declared in the DMCL, used in rotation. When one fills, IDMS switches to the next and the full one is offloaded by the archive journal process to tape or to a dataset. If every journal is full and none has been archived, the CV cannot continue — updates stop.

J1JRNLfull · archiving J2JRNLactive · writing J3JRNLempty Archive journaltape or dataset · retained N days Consumers rollforward recovery · CDC capture
Recovery and replication read the same stream. Retention sized only for recovery is the single most common cause of an unrecoverable replication gap.

The four ways things get put right

Four scenarios, one line each

Rollback — a program changed its mind. Undo its work.

Warm start — the whole database process crashed. On restart, undo anything that was half-done and keep everything that was finished. Automatic.

Rollforward — a disk was lost. Restore last night’s backup and replay the log forward over it.

Cold start — restart without reading the log at all. Fast, and it can leave the data in a state the log does not explain. If you hear that one happened, check your copy against the source.

ScenarioWhat failedWhat IDMS doesJournal direction
ROLLBACKThe application decided to abandon its workApplies before-images in reverse to the last checkpointBackwards, undo
Warm startThe CV abendedAutomatically backs out every in-flight run unit on restart; committed work standsBackwards, undo
RollforwardMedia failure — an area is lost or corruptRestore the last image copy, then apply after-images from archived journals forward to the failure pointForwards, redo
Cold startSomething has gone badly wrongRestarts without processing the journals — abandoning in-flight recovery informationNeither
A cold start is a replication incident A cold start leaves the database in a state that the journal stream does not fully explain: in-flight work may be partly applied and no undo was performed. Any replica built from that journal stream is now potentially divergent in ways no reconciliation can attribute. Get cold starts on your incident notification list, and treat one as a trigger for a comparison run.

Lab — read a journal stream and recover from it

Locking, and why it is about program structure

If you know row locks in PostgreSQL

Familiar mechanism, unfamiliar lifetime. Locks here are held for as long as the program’s whole session with the database, not for the duration of a statement.

So a batch job that reads a million records without saving along the way is holding a million locks. The fix is the same as everywhere: commit periodically. The difference is that here you must do it deliberately, and there is a special form of commit that saves your work without losing your place in the file.

IDMS locks at two levels, and both are visible to you.

Area locks

Taken by READY, held for the run unit's life, and determined entirely by the usage mode (Module 05). EXCLUSIVE UPDATE shuts everyone else out of the area; RETRIEVAL shuts nobody out.

Record locks

Taken implicitly on the records a run unit touches — shared for retrieval, exclusive for update — and explicitly by KEEP and KEEP EXCLUSIVE. Held until COMMIT or FINISH.

Because locks live for the run unit's lifetime rather than a statement's, IDMS lock duration is a property of application structure. A batch program that reads a million records without committing accumulates a million locks and blocks anything that touches them. The standard remedy is periodic COMMIT ALL — commit the work, release the locks, keep the currency.

Deadlock

Two run units, each holding what the other wants. IDMS detects the cycle, selects a victim, and returns a status in the 3000 family to it; the victim's work is rolled back and it is expected to retry.

the classic deadlock and its fix
*> Run unit A                    *> Run unit B
   OBTAIN CALC DEPARTMENT '2000'    OBTAIN CALC DEPARTMENT '3200'
   KEEP EXCLUSIVE CURRENT           KEEP EXCLUSIVE CURRENT
   ...                              ...
   OBTAIN CALC DEPARTMENT '3200'    OBTAIN CALC DEPARTMENT '2000'
   KEEP EXCLUSIVE CURRENT   <--- waits   KEEP EXCLUSIVE CURRENT  <--- waits

*> Fix: agree a global lock ordering. Every program that needs
*> several departments takes them in ascending DEPT-ID order.
*> Deadlock becomes impossible, not merely rare.

The other levers: shorten transactions, take the strongest lock you will need first rather than upgrading a shared lock to exclusive later, and avoid holding locks across terminal I/O in pseudo-conversational applications.

Tuning, in priority order

  1. Buffer pool size. Every page found in memory is an I/O that did not happen. This is the largest single lever and the cheapest to pull.
  2. Physical clustering. VIA placement (Module 03) decides how many pages a set walk touches. Fixing clustering is a reload; the payoff is permanent.
  3. Access path choice. An application doing a sweep where a CALC would do is a code fix, not a database fix.
  4. Commit frequency. Too rare: lock contention and enormous rollback exposure. Too frequent: journal write overhead and, for replication, a change stream full of tiny transactions.
  5. Journal configuration. Buffer size and file size determine how often you pay a switch, and how much log is at risk.
  6. Page size and reserve. Fewer, larger pages mean fewer I/Os for clustered access and more contention per page.

Where the numbers in a performance argument come from

the statistics you will be quoted in a performance discussion
DCMT DISPLAY STATISTICS SYSTEM     *> task rates, waits, storage high-water marks
DCMT DISPLAY BUFFER                *> pages, reads, writes, hit ratio per pool
DCMT DISPLAY AREA  ...             *> lock mode, in-use count, status
DCMT DISPLAY JOURNAL               *> which journal is active, archive state
DCMT DISPLAY LOCKS                 *> current holders and waiters

*> run-unit level statistics are also available to the program itself
    ACCEPT STATISTICS INTO WS-STATS-BLOCK.

ACCEPT STATISTICS lets a program read its own I/O and lock counters — useful when you are trying to prove that a particular extract is or is not the thing causing pain.

What this means for replication

  • The journal is your change stream. Everything you can replicate is something the journal records; everything the journal omits is invisible. Local-mode jobs without journalling, and utility operations that bypass normal logging, are therefore replication blind spots. Enumerate them.
  • Transaction boundaries come from CKPT and ENDJ. Applying changes in commit order, not arrival order, is what makes the target transactionally consistent rather than merely eventually similar.
  • Before-images are a gift. They let you compute the changed-column set exactly, detect conflicting concurrent updates, and reconstruct a deleted row for an audit target.
  • Journal retention is a hard dependency. Write it into the runbook: minimum retention, who to notify before a journal reconfiguration, and what the recovery procedure is if capture falls behind retention.
  • Rollbacks are normal traffic. Your pipeline must not apply changes from a run unit that later rolls back. This is why capture buffers by transaction and applies on commit, and why a single enormous uncommitted transaction can stall the whole pipeline.
  • Get the incident feed. Cold starts, rollforwards, area restores and reorganisations all change what the journal means. You want to hear about them from operations, not from a reconciliation report three days later.
Exercise 8.1 — Design the operational agreement

Write the section of the runbook covering source-side operations. It should state, concretely:

  1. Minimum archive journal retention in hours, and the calculation that justifies it (maximum tolerable capture outage plus a safety factor).
  2. Which events require notification to the replication team, with lead time: journal reconfiguration, cold start, area restore, unload/reload, schema change, DMCL change.
  3. The agreed procedure when capture latency exceeds a threshold — who is called, what is throttled, when a full refresh is declared.
  4. How a full refresh is performed and how long it takes, measured, not estimated.
  5. The external run unit budget allocated to replication and validation, and who to ask to raise it.

Every one of these is cheap to agree before go-live and expensive to negotiate during an incident.

Checkpoint