Oninit Logo
The Down System Specialists
+1-913-732-8892
+44-2081-337529
Partnerships Contact

Oninit® Forensic Tools — Examples: removing a page

A worked run-through of the offline single-page removal operation. For the flag set + edit-case enumeration, see the Subcommands section of the ondebug CLI page.

Worked example

A test table test_enc in database testdb, sitting in encrypted dbspace encryptdbs (dbsnum 4, chunk_id 4). The table holds two rows; both live on a single data page. The exercise orphans that data page from the partition by editing the partition's extent map, then confirms the engine restarts cleanly and the table reads back as empty.

Step 1 — confirm current state

While the engine is still running, capture the row baseline. This is both the verification anchor for Step 5 and a sanity check that the table we're about to operate on is actually the one the operator means.

$ echo "select * from test_enc;" | dbaccess testdb
Database selected.

c1  1
c2  Informix is pure dead Brill

c1  2
c2  Informix runs on scotch

2 row(s) retrieved.
Database closed.

Step 2 — look up the partition page + extent

The operator needs two page indices: the owning partition page (--partpage) and the data page to remove (--target). Both come from oncheck -pT — it works against an offline engine, so the lookup can be done after Step 3's quiesce if preferred.

$ oncheck -pT testdb:test_enc
TBLspace Report for testdb:informix.test_enc

    Physical Address               4:5
    …
    Number of pages used           2
    Number of data pages           1
    Number of rows                 2
    Partition partnum              4194306
    …

    Extents
         Logical Page     Physical Page        Size Physical Pages
                    0              4:53           8          8

Physical Address 4:5 = chunk_id 4, page 5 — the partition page (--partpage 5 -C 4). The single extent starts at 4:53 and is 8 pages long (pages 53–60). The single data page in this extent is page 54 (per Number of data pages = 1); that's our --target 54.

Step 3 — quiesce the engine + take a chunk image

$ onmode -ky
$ cp /home/informix/data/encryptdbs /tmp/encryptdbs.image
$ chmod 600 /tmp/encryptdbs.image

The engine has to be stopped first. Editing a chunk file while the engine has it open invites torn writes — in-flight engine writes can race the offline edit, and the buffer cache will otherwise overwrite the offline edit at the next checkpoint. The standard recipe is to take a copy with the engine down, work against the copy, and put the edited copy back in place before restarting.

Step 4 — dry-run inspect the planned edit

ondebug rm-page performs the edit. Dry-run is the default (no --apply); the target page is first rendered to stderr so the operator sees exactly what content is being orphaned, then the planned edit is printed.

$ ondebug rm-page --partpage 5 --target 54 -C 4 \
          /tmp/encryptdbs.image
=== ondebug rm-page: unloading target page 54 before removal ===
addr             stamp    chksum nslots flag type         frptr frcnt next     prev
4:54             11442017455575   2      1    DATA         232   1804  0        0

	slot ptr   len   flg
	1    24    104   0
	2    128   104   0

slot   1:
    0:  0  0  0  1 49 6e 66 6f 72 6d 69 78 20 69 73 20   ....Informix is
   16: 70 75 72 65 20 64 65 61 64 20 42 72 69 6c 6c 20   pure dead Brill
   …
slot   2:
    0:  0  0  0  2 49 6e 66 6f 72 6d 69 78 20 72 75 6e   ....Informix run
   16: 73 20 6f 6e 20 73 63 6f 74 63 68 20 20 20 20 20   s on scotch
   …

ondebug rm-page: partition page 5 (partnum 0x00400002) in chunk 4
  target page 54: flag=1 nslots=2 rows-removed=2
  case (d): split extent 0: {start=53 count=8}
                   → {start=53 count=1} + {start=55 count=6}
  descriptor: npused 2→1, npdata 1→0, nrows 2→0
  chksum: 0x5537 (recomputed)
  dry-run: no write performed (pass --apply --backup to commit)

The unload shows both test rows verbatim, addressable as row R, col C within each slot — the operator confirms this is the right page and the right content before any write happens. The planned-edit block then enumerates the four-case classification (here case d, interior split), the new extent map, the new descriptor counters, and the recomputed chksum.

The unload can be redirected to a file with --unload-to <path> for archival.

Step 5 — apply the edit with a backup

$ ondebug rm-page --partpage 5 --target 54 -C 4 \
          --apply --backup \
          /tmp/encryptdbs.image
… (unload block + planned-edit block as in Step 4) …
  backup: original partition page → /tmp/encryptdbs.image.rm-page-5.20260519-131127
  applied: partition page 5 rewritten

The timestamped .rm-page-… sidecar is the rollback image — a 2 KB file containing the original ciphertext of the partition page. Keep it until the engine is confirmed running. --apply without --backup is rejected; there is no engine-side transactional undo for offline edits.

Step 6 — restore, restart, verify

$ cp /tmp/encryptdbs.image /home/informix/data/encryptdbs
$ oninit -vw
$ onstat -
IBM Informix Dynamic Server Version 14.10.FC13W3 -- On-Line -- Up 00:00:12 -- 32768 Kbytes

$ echo "select count(*) from test_enc;" | dbaccess testdb
Database selected.

(count(*))  0

1 row(s) retrieved.
Database closed.

On-Line on the onstat - status line confirms the engine reached normal operating state on the edited chunk. select count(*) on test_enc then returns 0 rows — the engine read the edited partition page on startup, the extent map no longer claims page 54, and the two rows that lived there are no longer reachable through the table. The row bytes themselves are still on disk at chunk 4 page 54 (the operation only edits the partition page, never the data page), but the engine no longer follows any pointer to them.

If onstat - reports anything other than On-Line (Initialization, Recovery, Quiescent, or no response at all), or if the table query returns an error, do not declare success — capture online.log for diagnostics, stop the engine if it did come up, and roll back from the Step 5 backup before retrying.

Step 7 — roll back to the pre-edit state

The Step 5 sidecar is the rollback path. Splicing it back into the chunk file at the partition page's offset (page 5 × page_size = byte 10240) returns the partition page to its byte-for-byte original state; the engine restarts to the pre-edit row count.

$ onmode -ky
$ dd if=/tmp/encryptdbs.image.rm-page-5.20260519-131127 \
     of=/home/informix/data/encryptdbs \
     bs=2048 seek=5 conv=notrunc
1+0 records in
1+0 records out
$ oninit -vw
$ onstat -
IBM Informix Dynamic Server Version 14.10.FC13W3 -- On-Line -- Up 00:00:08 -- 32768 Kbytes

$ echo "select * from test_enc;" | dbaccess testdb
… (two rows, identical to Step 1 baseline) …

Both rows back, identical to the Step 1 baseline. The data page was never touched by the edit (the operation only amends the partition page's extent map), so its contents are intact and the engine reads them as if the removal never happened. The rollback is precise so long as no checkpoint has run on the edited state — once an engine-side checkpoint persists the post-edit view, the sidecar restores the partition-page bytes but later engine-side writes may have drifted other pages forward; in that window a forensic re-capture is preferred over a straight dd.

To discuss how Oninit ® can assist please call on +1-913-732-8892 or alternatively just send an email specifying your requirements.


You get all this for free.. think about what you get if you pay us