On Thu, 2013-06-13 at 20:09 -0400, Tom Lane wrote:
> What I propose we do about this is reduce backend/storage/page/checksum.c
> to something like
>
> #include "postgres.h"
> #include "storage/checksum.h"
> #include "storage/checksum_impl.h"
Attached a new diff for pg_filedump that makes use of the above change.
I'm not sure what the resolution of Alvaro's concern was, so I left the
flag reporting the same as the previous patch.
Regards,
Jeff Davis
Common subdirectories: pg_filedump-9.2.0/.deps and pg_filedump-9.3.0j/.deps
diff -Nc pg_filedump-9.2.0/Makefile pg_filedump-9.3.0j/Makefile
*** pg_filedump-9.2.0/Makefile 2012-03-12 09:02:44.000000000 -0700
--- pg_filedump-9.3.0j/Makefile 2013-06-18 09:14:42.442220848 -0700
***************
*** 1,7 ****
# View README.pg_filedump first
# note this must match version macros in pg_filedump.h
! FD_VERSION=9.2.0
CC=gcc
CFLAGS=-g -O -Wall -Wmissing-prototypes -Wmissing-declarations
--- 1,7 ----
# View README.pg_filedump first
# note this must match version macros in pg_filedump.h
! FD_VERSION=9.3.0
CC=gcc
CFLAGS=-g -O -Wall -Wmissing-prototypes -Wmissing-declarations
diff -Nc pg_filedump-9.2.0/pg_filedump.c pg_filedump-9.3.0j/pg_filedump.c
*** pg_filedump-9.2.0/pg_filedump.c 2012-03-12 08:58:31.000000000 -0700
--- pg_filedump-9.3.0j/pg_filedump.c 2013-06-18 09:25:42.438208300 -0700
***************
*** 26,31 ****
--- 26,37 ----
#include "utils/pg_crc_tables.h"
+ // checksum_impl.h uses Assert, which doesn't work outside the server
+ #undef Assert
+ #define Assert(X)
+
+ #include "storage/checksum_impl.h"
+
// Global variables for ease of use mostly
static FILE *fp = NULL; // File to dump or format
static char *fileName = NULL; // File name for display
***************
*** 40,51 ****
static void DisplayOptions (unsigned int validOptions);
static unsigned int ConsumeOptions (int numOptions, char **options);
static int GetOptionValue (char *optionString);
! static void FormatBlock ();
static unsigned int GetBlockSize ();
static unsigned int GetSpecialSectionType (Page page);
static bool IsBtreeMetaPage(Page page);
static void CreateDumpFileHeader (int numOptions, char **options);
! static int FormatHeader (Page page);
static void FormatItemBlock (Page page);
static void FormatItem (unsigned int numBytes, unsigned int startIndex,
unsigned int formatAs);
--- 46,57 ----
static void DisplayOptions (unsigned int validOptions);
static unsigned int ConsumeOptions (int numOptions, char **options);
static int GetOptionValue (char *optionString);
! static void FormatBlock (BlockNumber blkno);
static unsigned int GetBlockSize ();
static unsigned int GetSpecialSectionType (Page page);
static bool IsBtreeMetaPage(Page page);
static void CreateDumpFileHeader (int numOptions, char **options);
! static int FormatHeader (Page page, BlockNumber blkno);
static void FormatItemBlock (Page page);
static void FormatItem (unsigned int numBytes, unsigned int startIndex,
unsigned int formatAs);
***************
*** 288,293 ****
--- 294,304 ----
SET_OPTION (itemOptions, ITEM_DETAIL, 'i');
break;
+ // Verify block checksums
+ case 'k':
+ SET_OPTION (blockOptions, BLOCK_CHECKSUMS, 'k');
+ break;
+
// Interpret items as standard index values
case 'x':
SET_OPTION (itemOptions, ITEM_INDEX, 'x');
***************
*** 555,561 ****
// Dump out a formatted block header for the requested block
static int
! FormatHeader (Page page)
{
int rc = 0;
unsigned int headerBytes;
--- 566,572 ----
// Dump out a formatted block header for the requested block
static int
! FormatHeader (Page page, BlockNumber blkno)
{
int rc = 0;
unsigned int headerBytes;
***************
*** 609,623 ****
" Block: Size %4d Version %4u Upper %4u (0x%04hx)\n"
" LSN: logid %6d recoff 0x%08x Special %4u (0x%04hx)\n"
" Items: %4d Free Space: %4u\n"
! " TLI: 0x%04x Prune XID: 0x%08x Flags: 0x%04x (%s)\n"
" Length (including item array): %u\n\n",
pageOffset, pageHeader->pd_lower, pageHeader->pd_lower,
(int) PageGetPageSize (page), blockVersion,
pageHeader->pd_upper, pageHeader->pd_upper,
! pageLSN.xlogid, pageLSN.xrecoff,
pageHeader->pd_special, pageHeader->pd_special,
maxOffset, pageHeader->pd_upper - pageHeader->pd_lower,
! pageHeader->pd_tli, pageHeader->pd_prune_xid,
pageHeader->pd_flags, flagString,
headerBytes);
--- 620,634 ----
" Block: Size %4d Version %4u Upper %4u (0x%04hx)\n"
" LSN: logid %6d recoff 0x%08x Special %4u (0x%04hx)\n"
" Items: %4d Free Space: %4u\n"
! " Checksum: %05hu Prune XID: 0x%08x Flags: 0x%04x (%s)\n"
" Length (including item array): %u\n\n",
pageOffset, pageHeader->pd_lower, pageHeader->pd_lower,
(int) PageGetPageSize (page), blockVersion,
pageHeader->pd_upper, pageHeader->pd_upper,
! (uint32) (pageLSN >> 32), (uint32) pageLSN,
pageHeader->pd_special, pageHeader->pd_special,
maxOffset, pageHeader->pd_upper - pageHeader->pd_lower,
! pageHeader->pd_checksum, pageHeader->pd_prune_xid,
pageHeader->pd_flags, flagString,
headerBytes);
***************
*** 647,652 ****
--- 658,671 ----
|| (pageHeader->pd_upper < pageHeader->pd_lower)
|| (pageHeader->pd_special > blockSize))
printf (" Error: Invalid header information.\n\n");
+
+ if (blockOptions & BLOCK_CHECKSUMS)
+ {
+ uint16 calc_checksum = pg_checksum_page(page, blkno);
+ if (calc_checksum != pageHeader->pd_checksum)
+ printf(" Error: checksum failure: calculated %05hu.\n\n",
+ calc_checksum);
+ }
}
// If we have reached the end of file while interpreting the header, let
***************
*** 933,939 ****
printf (" XMIN: %u XMAX: %u CID|XVAC: %u",
HeapTupleHeaderGetXmin(htup),
! HeapTupleHeaderGetXmax(htup),
HeapTupleHeaderGetRawCommandId(htup));
if (infoMask & HEAP_HASOID)
--- 952,958 ----
printf (" XMIN: %u XMAX: %u CID|XVAC: %u",
HeapTupleHeaderGetXmin(htup),
! HeapTupleHeaderGetRawXmax(htup),
HeapTupleHeaderGetRawCommandId(htup));
if (infoMask & HEAP_HASOID)
***************
*** 958,969 ****
strcat (flagString, "HASEXTERNAL|");
if (infoMask & HEAP_HASOID)
strcat (flagString, "HASOID|");
if (infoMask & HEAP_COMBOCID)
strcat (flagString, "COMBOCID|");
if (infoMask & HEAP_XMAX_EXCL_LOCK)
strcat (flagString, "XMAX_EXCL_LOCK|");
! if (infoMask & HEAP_XMAX_SHARED_LOCK)
! strcat (flagString, "XMAX_SHARED_LOCK|");
if (infoMask & HEAP_XMIN_COMMITTED)
strcat (flagString, "XMIN_COMMITTED|");
if (infoMask & HEAP_XMIN_INVALID)
--- 977,992 ----
strcat (flagString, "HASEXTERNAL|");
if (infoMask & HEAP_HASOID)
strcat (flagString, "HASOID|");
+ if (infoMask & HEAP_XMAX_KEYSHR_LOCK)
+ strcat (flagString, "XMAX_KEYSHR_LOCK|");
if (infoMask & HEAP_COMBOCID)
strcat (flagString, "COMBOCID|");
if (infoMask & HEAP_XMAX_EXCL_LOCK)
strcat (flagString, "XMAX_EXCL_LOCK|");
! if (infoMask & HEAP_XMAX_SHR_LOCK)
! strcat (flagString, "XMAX_SHR_LOCK|");
! if (infoMask & HEAP_XMAX_LOCK_ONLY)
! strcat (flagString, "XMAX_LOCK_ONLY|");
if (infoMask & HEAP_XMIN_COMMITTED)
strcat (flagString, "XMIN_COMMITTED|");
if (infoMask & HEAP_XMIN_INVALID)
***************
*** 981,986 ****
--- 1004,1011 ----
if (infoMask & HEAP_MOVED_IN)
strcat (flagString, "MOVED_IN|");
+ if (infoMask2 & HEAP_KEYS_UPDATED)
+ strcat (flagString, "KEYS_UPDATED|");
if (infoMask2 & HEAP_HOT_UPDATED)
strcat (flagString, "HOT_UPDATED|");
if (infoMask2 & HEAP_ONLY_TUPLE)
***************
*** 1204,1210 ****
// For each block, dump out formatted header and content information
static void
! FormatBlock ()
{
Page page = (Page) buffer;
pageOffset = blockSize * currentBlock;
--- 1229,1235 ----
// For each block, dump out formatted header and content information
static void
! FormatBlock (BlockNumber blkno)
{
Page page = (Page) buffer;
pageOffset = blockSize * currentBlock;
***************
*** 1224,1230 ****
int rc;
// Every block contains a header, items and possibly a special
// section. Beware of partial block reads though
! rc = FormatHeader (page);
// If we didn't encounter a partial read in the header, carry on...
if (rc != EOF_ENCOUNTERED)
--- 1249,1255 ----
int rc;
// Every block contains a header, items and possibly a special
// section. Beware of partial block reads though
! rc = FormatHeader (page, blkno);
// If we didn't encounter a partial read in the header, carry on...
if (rc != EOF_ENCOUNTERED)
***************
*** 1340,1354 ****
controlData->system_identifier,
dbState,
ctime (&(cd_time)),
! controlData->checkPoint.xlogid, controlData->checkPoint.xrecoff,
! controlData->prevCheckPoint.xlogid, controlData->prevCheckPoint.xrecoff,
! checkPoint->redo.xlogid, checkPoint->redo.xrecoff,
checkPoint->ThisTimeLineID,
checkPoint->nextXidEpoch, checkPoint->nextXid,
checkPoint->nextOid,
checkPoint->nextMulti, checkPoint->nextMultiOffset,
ctime (&cp_time),
! controlData->minRecoveryPoint.xlogid, controlData->minRecoveryPoint.xrecoff,
controlData->maxAlign,
controlData->floatFormat,
(controlData->floatFormat == FLOATFORMAT_VALUE ?
--- 1365,1379 ----
controlData->system_identifier,
dbState,
ctime (&(cd_time)),
! (uint32) (controlData->checkPoint >> 32), (uint32) controlData->checkPoint,
! (uint32) (controlData->prevCheckPoint >> 32), (uint32) controlData->prevCheckPoint,
! (uint32) (checkPoint->redo >> 32), (uint32) checkPoint->redo,
checkPoint->ThisTimeLineID,
checkPoint->nextXidEpoch, checkPoint->nextXid,
checkPoint->nextOid,
checkPoint->nextMulti, checkPoint->nextMultiOffset,
ctime (&cp_time),
! (uint32) (controlData->minRecoveryPoint), (uint32) (controlData->minRecoveryPoint),
controlData->maxAlign,
controlData->floatFormat,
(controlData->floatFormat == FLOATFORMAT_VALUE ?
***************
*** 1494,1500 ****
contentsToDump = false;
}
else
! FormatBlock ();
}
}
--- 1519,1525 ----
contentsToDump = false;
}
else
! FormatBlock (currentBlock);
}
}
diff -Nc pg_filedump-9.2.0/pg_filedump.h pg_filedump-9.3.0j/pg_filedump.h
*** pg_filedump-9.2.0/pg_filedump.h 2012-03-12 08:58:23.000000000 -0700
--- pg_filedump-9.3.0j/pg_filedump.h 2013-06-18 09:10:28.010225685 -0700
***************
*** 22,29 ****
* Original Author: Patrick Macdonald <[email protected]>
*/
! #define FD_VERSION "9.2.0" /* version ID of pg_filedump */
! #define FD_PG_VERSION "PostgreSQL 9.2.x" /* PG version it works with */
#include "postgres.h"
--- 22,29 ----
* Original Author: Patrick Macdonald <[email protected]>
*/
! #define FD_VERSION "9.3.0" /* version ID of pg_filedump */
! #define FD_PG_VERSION "PostgreSQL 9.3.x" /* PG version it works with */
#include "postgres.h"
***************
*** 34,44 ****
--- 34,46 ----
#include "access/gist.h"
#include "access/hash.h"
#include "access/htup.h"
+ #include "access/htup_details.h"
#include "access/itup.h"
#include "access/nbtree.h"
#include "access/spgist_private.h"
#include "catalog/pg_control.h"
#include "storage/bufpage.h"
+ #include "storage/checksum.h"
// Options for Block formatting operations
static unsigned int blockOptions = 0;
***************
*** 49,55 ****
BLOCK_FORMAT = 0x00000004, // -f: Formatted dump of blocks / control file
BLOCK_FORCED = 0x00000008, // -S: Block size forced
BLOCK_NO_INTR = 0x00000010, // -d: Dump straight blocks
! BLOCK_RANGE = 0x00000020 // -R: Specific block range to dump
}
blockSwitches;
--- 51,58 ----
BLOCK_FORMAT = 0x00000004, // -f: Formatted dump of blocks / control file
BLOCK_FORCED = 0x00000008, // -S: Block size forced
BLOCK_NO_INTR = 0x00000010, // -d: Dump straight blocks
! BLOCK_RANGE = 0x00000020, // -R: Specific block range to dump
! BLOCK_CHECKSUMS = 0x00000040 // -k: verify block checksums
}
blockSwitches;
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers