PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
verify_common.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "access/table.h"
#include "access/tableam.h"
#include "verify_common.h"
#include "catalog/index.h"
#include "catalog/pg_am.h"
#include "commands/tablecmds.h"
#include "utils/guc.h"
#include "utils/syscache.h"
Include dependency graph for verify_common.c:

Go to the source code of this file.

Functions

static bool amcheck_index_mainfork_expected (Relation rel)
 
void amcheck_lock_relation_and_check (Oid indrelid, Oid am_id, IndexDoCheckCallback check, LOCKMODE lockmode, void *state)
 
bool index_checkable (Relation rel, Oid am_id)
 

Function Documentation

◆ amcheck_index_mainfork_expected()

static bool amcheck_index_mainfork_expected ( Relation  rel)
static

Definition at line 36 of file verify_common.c.

37{
38 if (rel->rd_rel->relpersistence != RELPERSISTENCE_UNLOGGED ||
40 return true;
41
43 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
44 errmsg("cannot verify unlogged index \"%s\" during recovery, skipping",
46
47 return false;
48}
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define NOTICE
Definition: elog.h:35
#define ereport(elevel,...)
Definition: elog.h:149
#define RelationGetRelationName(relation)
Definition: rel.h:550
Form_pg_class rd_rel
Definition: rel.h:111
bool RecoveryInProgress(void)
Definition: xlog.c:6522

References ereport, errcode(), errmsg(), NOTICE, RelationData::rd_rel, RecoveryInProgress(), and RelationGetRelationName.

Referenced by index_checkable().

◆ amcheck_lock_relation_and_check()

void amcheck_lock_relation_and_check ( Oid  indrelid,
Oid  am_id,
IndexDoCheckCallback  check,
LOCKMODE  lockmode,
void *  state 
)

Definition at line 60 of file verify_common.c.

65{
66 Oid heapid;
67 Relation indrel;
68 Relation heaprel;
69 Oid save_userid;
70 int save_sec_context;
71 int save_nestlevel;
72
73 /*
74 * We must lock table before index to avoid deadlocks. However, if the
75 * passed indrelid isn't an index then IndexGetRelation() will fail.
76 * Rather than emitting a not-very-helpful error message, postpone
77 * complaining, expecting that the is-it-an-index test below will fail.
78 *
79 * In hot standby mode this will raise an error when parentcheck is true.
80 */
81 heapid = IndexGetRelation(indrelid, true);
82 if (OidIsValid(heapid))
83 {
84 heaprel = table_open(heapid, lockmode);
85
86 /*
87 * Switch to the table owner's userid, so that any index functions are
88 * run as that user. Also lock down security-restricted operations
89 * and arrange to make GUC variable changes local to this command.
90 */
91 GetUserIdAndSecContext(&save_userid, &save_sec_context);
92 SetUserIdAndSecContext(heaprel->rd_rel->relowner,
93 save_sec_context | SECURITY_RESTRICTED_OPERATION);
94 save_nestlevel = NewGUCNestLevel();
95 }
96 else
97 {
98 heaprel = NULL;
99 /* Set these just to suppress "uninitialized variable" warnings */
100 save_userid = InvalidOid;
101 save_sec_context = -1;
102 save_nestlevel = -1;
103 }
104
105 /*
106 * Open the target index relations separately (like relation_openrv(), but
107 * with heap relation locked first to prevent deadlocking). In hot
108 * standby mode this will raise an error when parentcheck is true.
109 *
110 * There is no need for the usual indcheckxmin usability horizon test
111 * here, even in the heapallindexed case, because index undergoing
112 * verification only needs to have entries for a new transaction snapshot.
113 * (If this is a parentcheck verification, there is no question about
114 * committed or recently dead heap tuples lacking index entries due to
115 * concurrent activity.)
116 */
117 indrel = index_open(indrelid, lockmode);
118
119 /*
120 * Since we did the IndexGetRelation call above without any lock, it's
121 * barely possible that a race against an index drop/recreation could have
122 * netted us the wrong table.
123 */
124 if (heaprel == NULL || heapid != IndexGetRelation(indrelid, false))
127 errmsg("could not open parent table of index \"%s\"",
128 RelationGetRelationName(indrel))));
129
130 /* Check that relation suitable for checking */
131 if (index_checkable(indrel, am_id))
132 check(indrel, heaprel, state, lockmode == ShareLock);
133
134 /* Roll back any GUC changes executed by index functions */
135 AtEOXact_GUC(false, save_nestlevel);
136
137 /* Restore userid and security context */
138 SetUserIdAndSecContext(save_userid, save_sec_context);
139
140 /*
141 * Release locks early. That's ok here because nothing in the called
142 * routines will trigger shared cache invalidations to be sent, so we can
143 * relax the usual pattern of only releasing locks after commit.
144 */
145 index_close(indrel, lockmode);
146 if (heaprel)
147 table_close(heaprel, lockmode);
148}
#define OidIsValid(objectId)
Definition: c.h:746
#define ERROR
Definition: elog.h:39
int NewGUCNestLevel(void)
Definition: guc.c:2235
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition: guc.c:2262
Oid IndexGetRelation(Oid indexId, bool missing_ok)
Definition: index.c:3583
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:177
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:133
#define ShareLock
Definition: lockdefs.h:40
#define SECURITY_RESTRICTED_OPERATION
Definition: miscadmin.h:319
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
Definition: miscinit.c:663
void SetUserIdAndSecContext(Oid userid, int sec_context)
Definition: miscinit.c:670
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:79
#define InvalidOid
Definition: postgres_ext.h:35
unsigned int Oid
Definition: postgres_ext.h:30
Definition: regguts.h:323
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40
bool index_checkable(Relation rel, Oid am_id)

References AtEOXact_GUC(), ereport, errcode(), ERRCODE_UNDEFINED_TABLE, errmsg(), ERROR, GetUserIdAndSecContext(), index_checkable(), index_close(), index_open(), IndexGetRelation(), InvalidOid, NewGUCNestLevel(), OidIsValid, RelationData::rd_rel, RelationGetRelationName, SECURITY_RESTRICTED_OPERATION, SetUserIdAndSecContext(), ShareLock, table_close(), and table_open().

Referenced by bt_index_check(), bt_index_parent_check(), and gin_index_check().

◆ index_checkable()

bool index_checkable ( Relation  rel,
Oid  am_id 
)

Definition at line 159 of file verify_common.c.

160{
161 if (rel->rd_rel->relkind != RELKIND_INDEX ||
162 rel->rd_rel->relam != am_id)
163 {
164 HeapTuple amtup;
165 HeapTuple amtuprel;
166
167 amtup = SearchSysCache1(AMOID, ObjectIdGetDatum(am_id));
168 amtuprel = SearchSysCache1(AMOID, ObjectIdGetDatum(rel->rd_rel->relam));
170 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
171 errmsg("expected \"%s\" index as targets for verification", NameStr(((Form_pg_am) GETSTRUCT(amtup))->amname)),
172 errdetail("Relation \"%s\" is a %s index.",
173 RelationGetRelationName(rel), NameStr(((Form_pg_am) GETSTRUCT(amtuprel))->amname))));
174 }
175
176 if (RELATION_IS_OTHER_TEMP(rel))
178 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
179 errmsg("cannot access temporary tables of other sessions"),
180 errdetail("Index \"%s\" is associated with temporary relation.",
182
183 if (!rel->rd_index->indisvalid)
185 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
186 errmsg("cannot check index \"%s\"",
188 errdetail("Index is not valid.")));
189
191}
#define NameStr(name)
Definition: c.h:717
int errdetail(const char *fmt,...)
Definition: elog.c:1204
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
FormData_pg_am * Form_pg_am
Definition: pg_am.h:48
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
#define RELATION_IS_OTHER_TEMP(relation)
Definition: rel.h:669
Form_pg_index rd_index
Definition: rel.h:192
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:221
static bool amcheck_index_mainfork_expected(Relation rel)
Definition: verify_common.c:36

References amcheck_index_mainfork_expected(), ereport, errcode(), errdetail(), errmsg(), ERROR, GETSTRUCT(), NameStr, ObjectIdGetDatum(), RelationData::rd_index, RelationData::rd_rel, RELATION_IS_OTHER_TEMP, RelationGetRelationName, and SearchSysCache1().

Referenced by amcheck_lock_relation_and_check().