From fd6ec93bf890314ac694dc8a7f3c45702ecc1bbd Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Thu, 1 Aug 2019 11:05:08 +0200 Subject: [PATCH] Add error codes to some corruption log messages In some cases we have elog(ERROR) while corruption is certain and we can give a clear error code ERRCODE_DATA_CORRUPTED or ERRCODE_INDEX_CORRUPTED. Author: Andrey Borodin Discussion: https://www.postgresql.org/message-id/flat/25F6C686-6442-4A6B-BAF8-A6F7B84B16DE@yandex-team.ru --- src/backend/access/heap/heapam_handler.c | 4 +- src/backend/access/heap/tuptoaster.c | 58 ++++++++++++++---------- src/backend/access/nbtree/nbtinsert.c | 16 ++++--- src/backend/access/nbtree/nbtpage.c | 30 +++++++----- src/backend/access/nbtree/nbtsearch.c | 6 ++- 5 files changed, 70 insertions(+), 44 deletions(-) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index 09bc6fe98a..f1ff01e8cb 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -423,7 +423,9 @@ tuple_lock_retry: /* otherwise xmin should not be dirty... */ if (TransactionIdIsValid(SnapshotDirty.xmin)) - elog(ERROR, "t_xmin is uncommitted in tuple to be updated"); + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg_internal("t_xmin is uncommitted in tuple to be updated"))); /* * If tuple is being updated by other transaction then we diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c index 55d6e91d1c..74233bb931 100644 --- a/src/backend/access/heap/tuptoaster.c +++ b/src/backend/access/heap/tuptoaster.c @@ -1966,35 +1966,43 @@ toast_fetch_datum(struct varlena *attr) * Some checks on the data we've found */ if (residx != nextidx) - elog(ERROR, "unexpected chunk number %d (expected %d) for toast value %u in %s", - residx, nextidx, - toast_pointer.va_valueid, - RelationGetRelationName(toastrel)); + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg_internal("unexpected chunk number %d (expected %d) for toast value %u in %s", + residx, nextidx, + toast_pointer.va_valueid, + RelationGetRelationName(toastrel)))); if (residx < numchunks - 1) { if (chunksize != TOAST_MAX_CHUNK_SIZE) - elog(ERROR, "unexpected chunk size %d (expected %d) in chunk %d of %d for toast value %u in %s", - chunksize, (int) TOAST_MAX_CHUNK_SIZE, - residx, numchunks, - toast_pointer.va_valueid, - RelationGetRelationName(toastrel)); + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg_internal("unexpected chunk size %d (expected %d) in chunk %d of %d for toast value %u in %s", + chunksize, (int) TOAST_MAX_CHUNK_SIZE, + residx, numchunks, + toast_pointer.va_valueid, + RelationGetRelationName(toastrel)))); } else if (residx == numchunks - 1) { if ((residx * TOAST_MAX_CHUNK_SIZE + chunksize) != ressize) - elog(ERROR, "unexpected chunk size %d (expected %d) in final chunk %d for toast value %u in %s", - chunksize, - (int) (ressize - residx * TOAST_MAX_CHUNK_SIZE), - residx, - toast_pointer.va_valueid, - RelationGetRelationName(toastrel)); + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg_internal("unexpected chunk size %d (expected %d) in final chunk %d for toast value %u in %s", + chunksize, + (int) (ressize - residx * TOAST_MAX_CHUNK_SIZE), + residx, + toast_pointer.va_valueid, + RelationGetRelationName(toastrel)))); } else - elog(ERROR, "unexpected chunk number %d (out of range %d..%d) for toast value %u in %s", - residx, - 0, numchunks - 1, - toast_pointer.va_valueid, - RelationGetRelationName(toastrel)); + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg_internal("unexpected chunk number %d (out of range %d..%d) for toast value %u in %s", + residx, + 0, numchunks - 1, + toast_pointer.va_valueid, + RelationGetRelationName(toastrel)))); /* * Copy the data into proper place in our result @@ -2010,10 +2018,12 @@ toast_fetch_datum(struct varlena *attr) * Final checks that we successfully fetched the datum */ if (nextidx != numchunks) - elog(ERROR, "missing chunk number %d for toast value %u in %s", - nextidx, - toast_pointer.va_valueid, - RelationGetRelationName(toastrel)); + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg_internal("missing chunk number %d for toast value %u in %s", + nextidx, + toast_pointer.va_valueid, + RelationGetRelationName(toastrel)))); /* * End scan and close relations diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c index 602f8849d4..5890f393f6 100644 --- a/src/backend/access/nbtree/nbtinsert.c +++ b/src/backend/access/nbtree/nbtinsert.c @@ -1568,10 +1568,12 @@ _bt_split(Relation rel, BTScanInsert itup_key, Buffer buf, Buffer cbuf, if (sopaque->btpo_prev != origpagenumber) { memset(rightpage, 0, BufferGetPageSize(rbuf)); - elog(ERROR, "right sibling's left-link doesn't match: " - "block %u links to %u instead of expected %u in index \"%s\"", - oopaque->btpo_next, sopaque->btpo_prev, origpagenumber, - RelationGetRelationName(rel)); + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg_internal("right sibling's left-link doesn't match: " + "block %u links to %u instead of expected %u in index \"%s\"", + oopaque->btpo_next, sopaque->btpo_prev, origpagenumber, + RelationGetRelationName(rel)))); } /* @@ -1827,8 +1829,10 @@ _bt_insert_parent(Relation rel, _bt_relbuf(rel, rbuf); if (pbuf == InvalidBuffer) - elog(ERROR, "failed to re-find parent key in index \"%s\" for split pages %u/%u", - RelationGetRelationName(rel), bknum, rbknum); + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg_internal("failed to re-find parent key in index \"%s\" for split pages %u/%u", + RelationGetRelationName(rel), bknum, rbknum))); /* Recursively update the parent */ _bt_insertonpg(rel, NULL, pbuf, buf, stack->bts_parent, diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c index 5962126743..9c1f7de60f 100644 --- a/src/backend/access/nbtree/nbtpage.c +++ b/src/backend/access/nbtree/nbtpage.c @@ -1192,8 +1192,10 @@ _bt_lock_branch_parent(Relation rel, BlockNumber child, BTStack stack, stack->bts_btentry = child; pbuf = _bt_getstackbuf(rel, stack); if (pbuf == InvalidBuffer) - elog(ERROR, "failed to re-find parent key in index \"%s\" for deletion target page %u", - RelationGetRelationName(rel), child); + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg_internal("failed to re-find parent key in index \"%s\" for deletion target page %u", + RelationGetRelationName(rel), child))); parent = stack->bts_blkno; poffset = stack->bts_offset; @@ -1611,9 +1613,11 @@ _bt_mark_page_halfdead(Relation rel, Buffer leafbuf, BTStack stack) itemid = PageGetItemId(page, nextoffset); itup = (IndexTuple) PageGetItem(page, itemid); if (BTreeInnerTupleGetDownLink(itup) != rightsib) - elog(ERROR, "right sibling %u of block %u is not next child %u of block %u in index \"%s\"", - rightsib, target, BTreeInnerTupleGetDownLink(itup), - BufferGetBlockNumber(topparent), RelationGetRelationName(rel)); + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg_internal("right sibling %u of block %u is not next child %u of block %u in index \"%s\"", + rightsib, target, BTreeInnerTupleGetDownLink(itup), + BufferGetBlockNumber(topparent), RelationGetRelationName(rel)))); /* * Any insert which would have gone on the leaf block will now go to its @@ -1878,8 +1882,10 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, bool *rightsib_empty) target, RelationGetRelationName(rel)); } if (opaque->btpo_prev != leftsib) - elog(ERROR, "left link changed unexpectedly in block %u of index \"%s\"", - target, RelationGetRelationName(rel)); + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg_internal("left link changed unexpectedly in block %u of index \"%s\"", + target, RelationGetRelationName(rel)))); if (target == leafblkno) { @@ -1911,10 +1917,12 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, bool *rightsib_empty) page = BufferGetPage(rbuf); opaque = (BTPageOpaque) PageGetSpecialPointer(page); if (opaque->btpo_prev != target) - elog(ERROR, "right sibling's left-link doesn't match: " - "block %u links to %u instead of expected %u in index \"%s\"", - rightsib, opaque->btpo_prev, target, - RelationGetRelationName(rel)); + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg_internal("right sibling's left-link doesn't match: " + "block %u links to %u instead of expected %u in index \"%s\"", + rightsib, opaque->btpo_prev, target, + RelationGetRelationName(rel)))); rightsib_is_rightmost = P_RIGHTMOST(opaque); *rightsib_empty = (P_FIRSTDATAKEY(opaque) > PageGetMaxOffsetNumber(page)); diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c index c655dadb96..19735bf733 100644 --- a/src/backend/access/nbtree/nbtsearch.c +++ b/src/backend/access/nbtree/nbtsearch.c @@ -2113,8 +2113,10 @@ _bt_get_endpoint(Relation rel, uint32 level, bool rightmost, if (opaque->btpo.level == level) break; if (opaque->btpo.level < level) - elog(ERROR, "btree level %u not found in index \"%s\"", - level, RelationGetRelationName(rel)); + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg_internal("btree level %u not found in index \"%s\"", + level, RelationGetRelationName(rel)))); /* Descend to leftmost or rightmost child page */ if (rightmost) -- 2.40.0