##### #### ##### # # # # #####
# # # # # # # # ## ## # #
# # # # # # # # ## # # #
##### # ### # # # # # # #####
# # # # # # # # # #
# #### ##### #### # # #
This is a brief (for me) explanation of a fairly simple program: pgdump.
The purpose of this program is to print a dump of a page in an Informix
OnLine system. As it happens, it CAN dump part of ANY file but it
assumes it is an OnLine page and the predictably unpredictable results
will occur.
Usage:
The pgdump command requires a few basic parameters, like the name of
the device, the page offset (starting from 0) where to start dumping
pages, the number of pages to dump, y'know, the usual stuff. Should
you forget the parameters (easy to do when there are lots of 'em), try
the -h option:
$ pgdump -h
Usage:
pgdump -h # This help page
pgdump -d<device-path> # Required
[-s<page-size>] # Page size in K (Def: 2)
[-p<n>] # Page Number; Default 0
[-n<pages>] # Number of pages to dump
[-f<format>] # Format of the dump:
Combination of:
x Hex dump - 4 byte columns (Default)
s Hex dump of Slots, where applicable
For example, suppose I run onstat -d and determine that the rootdbs is
on device /dev/rdisk1 at offset 0 (let's keep it simple). The following
command will print a neat 80-column dump of the configuration reserved
page:
pgdump -d /dev/rdisk1 -p 1 -n 1
This produces a dump that looks like this on my system:
Device: </dev/chunk1>; Page <0001/0x0001>; OnLine Page ID: <1/1>
-----------------------------------------------------------------
0000/0000||00100001 16B7B2B0 004B1000 049C0234 |~~~~~~~~~K~~~~~4|
0016/0010||00000000 00000000 524F4F54 4E414D45 |~~~~~~~~ROOTNAME|
0032/0020||20726F6F 74646273 00524F4F 54504154 | rootdbs~ROOTPAT|
0048/0030||48202F64 65762F63 68756E6B 3100524F |H /dev/chunk1~RO|
0064/0040||4F544F46 46534554 20300052 4F4F5453 |OTOFFSET 0~ROOTS|
0080/0050||495A4520 33313230 3030004D 4952524F |IZE 312000~MIRRO|
0096/0060||52203100 4D495252 4F525041 54482000 |R 1~MIRRORPATH ~|
0112/0070||4D495252 4F524F46 46534554 20300050 |MIRROROFFSET 0~P|
0128/0080||48595344 42532070 68797369 6C6F6700 |HYSDBS physilog~|
0144/0090||50485953 46494C45 20383030 30004C4F |PHYSFILE 8000~LO|
0160/00A0||4746494C 45532036 004C4F47 53495A45 |GFILES 6~LOGSIZE|
0176/00B0||20383030 3030004D 53475041 5448202F | 80000~MSGPATH /|
0192/00C0||7573722F 696E666F 726D6978 2F6F6E6C |usr/informix/onl|
0208/00D0||696E652E 6C6F6700 434F4E53 4F4C4520 |ine.log~CONSOLE |
0224/00E0||2F757372 2F696E66 6F726D69 782F6D65 |/usr/informix/me|
0240/00F0||73736167 652E6C6F 67005441 50454445 |ssage.log~TAPEDE|
0256/0100||56202F75 73722F69 6E666F72 6D69782F |V /usr/informix/|
0272/0110||61726368 2E676172 70616300 54415045 |arch.garpac~TAPE|
0288/0120||424C4B20 31303234 00544150 4553495A |BLK 1024~TAPESIZ|
0304/0130||45203130 30303030 30004C54 41504544 |E 1000000~LTAPED|
0320/0140||4556202F 6465762F 6E756C6C 004C5441 |EV /dev/null~LTA|
0336/0150||5045424C 4B203130 3234004C 54415045 |PEBLK 1024~LTAPE|
0352/0160||53495A45 20343039 36303030 00444253 |SIZE 4096000~DBS|
0368/0170||45525645 524E414D 45206870 67617200 |ERVERNAME hpgar~|
0384/0180||53455256 45524E55 4D203000 44454144 |SERVERNUM 0~DEAD|
0400/0190||4C4F434B 5F54494D 454F5554 20363000 |LOCK_TIMEOUT 60~|
--- SNIP ---
OK, what does that all mean?
The first column in each line, with the nnnn/nnnn numbers, is the offset
within the page, of that line. It is displayed first in decimal, then
in hex.
The next 4 columns are bytes in order of their addresses. I have no
intention of worrying about the byte order in 32 and 16-bit integers.
That is not the purpose of the pgdump utility.
The next broad column is, obviously, the same bytes in printable
format. Of course, unprintables have been replaced with the tilde (~)
character.
One more comment about parameter convention: The same command could
have been typed as:
$ pgdump -d/dev/rdisk1 -p1 -n1
i.e. No blanks between an option and its value. (getopts() just hppens
to work that way.)
Now this dump is not much easier to read than your run-of-the-mill dump
(though I have yet to get something this readable from the UNIX od
command). The problem is separating rows. For this we have another
option. Note that I omitted the -f option from the sample command.
Let's try the same command with this variation:
$ pgdump -d /dev/chunk1 -n 1 -p 1 -fs
Here I specified slot formatting, producing the following:
Event ID: <16B7B2B0>; Slots: <075>;
Page type:<1000/PG_RSRVD/OnLine reserved Page>
Total free bytes: <0564>; Free area begins at: <0x049C>
Slot 001 at offset: <0018/0024>; Length: <0011; 0017>
0000/0000||524F4F54 4E414D45 20726F6F 74646273 |ROOTNAME rootdbs|
0016/0010||00 |~ |
Slot 002 at offset: <0029/0041>; Length: <0015; 0021>
0000/0000||524F4F54 50415448 202F6465 762F6368 |ROOTPATH /dev/ch|
0016/0010||756E6B31 00 |unk1~ |
Slot 003 at offset: <003E/0062>; Length: <000D; 0013>
0000/0000||524F4F54 4F464653 45542030 00 |ROOTOFFSET 0~ |
Slot 004 at offset: <004B/0075>; Length: <0010; 0016>
0000/0000||524F4F54 53495A45 20333132 30303000 |ROOTSIZE 312000~|
0016/0010||4D |M |
Slot 005 at offset: <005B/0091>; Length: <0009; 0009>
0000/0000||4D495252 4F522031 00 |MIRROR 1~ |
Slot 006 at offset: <0064/0100>; Length: <000C; 0012>
0000/0000||4D495252 4F525041 54482000 |MIRRORPATH ~ |
Slot 007 at offset: <0070/0112>; Length: <000F; 0015>
0000/0000||4D495252 4F524F46 46534554 203000 |MIRROROFFSET 0~ |
Slot 008 at offset: <007F/0127>; Length: <0011; 0017>
0000/0000||50485953 44425320 70687973 696C6F67 |PHYSDBS physilog|
0016/0010||00 |~ |
Slot 009 at offset: <0090/0144>; Length: <000E; 0014>
0000/0000||50485953 46494C45 20383030 3000 |PHYSFILE 8000~ |
Slot 010 at offset: <009E/0158>; Length: <000B; 0011>
0000/0000||4C4F4746 494C4553 203600 |LOGFILES 6~ |
Slot 011 at offset: <00A9/0169>; Length: <000E; 0014>
0000/0000||4C4F4753 495A4520 38303030 3000 |LOGSIZE 80000~ |
Slot 012 at offset: <00B7/0183>; Length: <0021; 0033>
0000/0000||4D534750 41544820 2F757372 2F696E66 |MSGPATH /usr/inf|
0016/0010||6F726D69 782F6F6E 6C696E65 2E6C6F67 |ormix/online.log|
0032/0020||00 |~ |
Slot 013 at offset: <00D8/0216>; Length: <0022; 0034>
0000/0000||434F4E53 4F4C4520 2F757372 2F696E66 |CONSOLE /usr/inf|
0016/0010||6F726D69 782F6D65 73736167 652E6C6F |ormix/message.lo|
0032/0020||6700 |g~ |
--- SNIP ---
Now we're getting somewhere! If you can locate a corrupted index page
(the online.log will give you its page address) by some other means,
you can dump that page and examine the index entries. Of course, that
means you are (or have been) an Informix propeller-head but you can
really dazzle the tech support guy with the detailed information and
get escalated to advanced support real quick!
Another note about the parameters: Supposing I run the same command as
the first but with one slight variation:
$ pgdump -d /dev/chunk1 -n 1 -p 1 -fX
Note the capital X in the format option. This will give you the basic
same dump as the first example (where I omitted the format option).
However, this will be in wide format for your 132-character printer.
The slot dump can also specify -fS (instead of -fs) to get a wide
format slot dump.
You can get both dumps in one output, page by page, by specifying -fxs
or -fXS. No matter what order you specify the format, you will always
get the hex dump of each page before the slot dump for that page.
Note that the syntax allows you to specify -fXs but, due to a minor
flaw, mixing formats produces ugly results in the slot dump. Hey, you
wouldn't want to mix them anyway, wooould you? ;-)
Note that the default assumed page size is 2K. You can override this
on the command line with the -s option, e.g. -s4 for a 4-K page size.
Limitations:
- You must be user informix (or root) in order to run this program.
The file permissions on the devices would prevent any other user
from getting into the disk devices this way.
- pgdump is not (yet) smart enough to dump a whole blob page. It is
smart enough to refuse to produce a slot dump if given a blob page
to dump.
Other limitations will be discussed in the file TO-DO.
Installation:
If you are reading this, you have obviously untarred the installation
file already. The "make" command is all you need to run. So far, the
entire utility fits in a single C file.
pgdump was developed on an HP-UX with an old ANSI-C compiler. Perhaps
on your system the -D option is not needed, or you can use gcc
compiler, which will probably make life easier in any case.
If you do not happen to have an ANSI-C compiler, you will need to
modify the Makefile and change the options to the cc command.
====EOF====