Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OID Wraparound #295

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/backend/access/transam/varsup.c
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,14 @@ GetNewObjectId(void)
return result;
}

/*
* Simple function to get VAR_OID_PREFETCH when needed outside of this file.
*/
int GetVarOidPrefetch(void)
{
return VAR_OID_PREFETCH;
}

/*
* SetNextObjectId
*
Expand Down
35 changes: 31 additions & 4 deletions src/backend/catalog/catalog.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "catalog/pg_tablespace.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "parser/parser.h"
#include "storage/fd.h"
#include "utils/fmgroids.h"
#include "utils/fmgrprotos.h"
Expand All @@ -53,6 +54,9 @@ IsExtendedCatalogHookType IsExtendedCatalogHook;
IsToastRelationHookType IsToastRelationHook;
IsToastClassHookType IsToastClassHook;

GetNewTempObjectId_hook_type GetNewTempObjectId_hook;
GetNewTempOidWithIndex_hook_type GetNewTempOidWithIndex_hook;

/*
* Parameters to determine when to emit a log message in
* GetNewOidWithIndex()
Expand Down Expand Up @@ -418,7 +422,7 @@ GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
/* Only system relations are supported */
Assert(IsSystemRelation(relation));

/* In bootstrap mode, we don't have any indexes to use */
/* In bootstrap mode, we don't have any indexes to use. No temp objects in bootstrap mode. */
if (IsBootstrapProcessingMode())
return GetNewObjectId();

Expand Down Expand Up @@ -515,12 +519,14 @@ GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
* created by bootstrap have preassigned OIDs, so there's no need.
*/
RelFileNumber
GetNewRelFileNumber(Oid reltablespace, Relation pg_class, char relpersistence)
GetNewRelFileNumber(Oid reltablespace, Relation pg_class, char relpersistence, bool override_temp)
{
RelFileLocatorBackend rlocator;
char *rpath;
bool collides;
BackendId backend;
int tries = 0;
bool use_bbf_oid_buffer;

/*
* If we ever get here during pg_upgrade, there's something wrong; all
Expand Down Expand Up @@ -556,16 +562,32 @@ GetNewRelFileNumber(Oid reltablespace, Relation pg_class, char relpersistence)
*/
rlocator.backend = backend;

use_bbf_oid_buffer = (relpersistence == RELPERSISTENCE_TEMP && sql_dialect == SQL_DIALECT_TSQL
&& GetNewTempOidWithIndex_hook && temp_oid_buffer_size > 0 && !override_temp);

do
{
CHECK_FOR_INTERRUPTS();

/* Generate the OID */
if (pg_class)
rlocator.locator.relNumber = GetNewOidWithIndex(pg_class, ClassOidIndexId,
{
/* Temp tables use temp OID logic */
if (use_bbf_oid_buffer)
rlocator.locator.relNumber = GetNewTempOidWithIndex_hook(pg_class, ClassOidIndexId,
Anum_pg_class_oid);
else
rlocator.locator.relNumber = GetNewOidWithIndex(pg_class, ClassOidIndexId,
Anum_pg_class_oid);
}
else
rlocator.locator.relNumber = GetNewObjectId();
{
/* Temp tables use temp OID logic */
if (use_bbf_oid_buffer)
rlocator.locator.relNumber = GetNewTempObjectId_hook();
else
rlocator.locator.relNumber = GetNewObjectId();
}

/* Check for existing file of same name */
rpath = relpath(rlocator, MAIN_FORKNUM);
Expand All @@ -587,7 +609,12 @@ GetNewRelFileNumber(Oid reltablespace, Relation pg_class, char relpersistence)
collides = false;
}

if (use_bbf_oid_buffer && tries > temp_oid_buffer_size)
ereport(ERROR,
(errmsg("Unable to allocate oid for temp table. Drop some temporary tables or start a new session.")));

pfree(rpath);
tries++;
} while (collides);

return rlocator.locator.relNumber;
Expand Down
2 changes: 1 addition & 1 deletion src/backend/catalog/heap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1307,7 +1307,7 @@ heap_create_with_catalog(const char *relname,

if (!OidIsValid(relid))
relid = GetNewRelFileNumber(reltablespace, pg_class_desc,
relpersistence);
relpersistence, false);
}

/*
Expand Down
8 changes: 6 additions & 2 deletions src/backend/catalog/index.c
Original file line number Diff line number Diff line change
Expand Up @@ -962,8 +962,12 @@ index_create(Relation heapRelation,
}
else
{
indexRelationId =
GetNewRelFileNumber(tableSpaceId, pg_class, relpersistence);
/*
* Index OIDs must be kept in normal OID range due to deletion issues.
* Since deletion is sorted by OID, adding indexes to temp OID range
* causes deletion order issues.
*/
indexRelationId = GetNewRelFileNumber(tableSpaceId, pg_class, relpersistence, is_enr);
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/backend/catalog/pg_depend.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,8 @@ deleteDependencyRecordsFor(Oid classId, Oid objectId,
((Form_pg_depend) GETSTRUCT(tup))->deptype == DEPENDENCY_EXTENSION)
continue;

CatalogTupleDelete(depRel, &tup->t_self);
if (!ENRdropTuple(depRel, tup))
CatalogTupleDelete(depRel, &tup->t_self);
count++;
}

Expand Down
2 changes: 2 additions & 0 deletions src/backend/catalog/toasting.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
*/
if (sql_dialect == SQL_DIALECT_TSQL && RelationIsBBFTableVariable(rel))
pg_toast_prefix = "@pg_toast";
else if (sql_dialect == SQL_DIALECT_TSQL && rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP && get_ENR_withoid(currentQueryEnv, rel->rd_id, ENR_TSQL_TEMP))
pg_toast_prefix = "#pg_toast";

snprintf(toast_relname, sizeof(toast_relname),
"%s_%u", pg_toast_prefix, relOid);
Expand Down
10 changes: 9 additions & 1 deletion src/backend/commands/cluster.c
Original file line number Diff line number Diff line change
Expand Up @@ -736,8 +736,14 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod,
* a shared rel. However, we do make the new heap mapped if the source is
* mapped. This simplifies swap_relation_files, and is absolutely
* necessary for rebuilding pg_class, for reasons explained there.
*
* We also must ensure that these temp tables are properly named in TSQL
* so that the metadata is properly cleaned up after in this function.
*/
snprintf(NewHeapName, sizeof(NewHeapName), "pg_temp_%u", OIDOldHeap);
if (sql_dialect == SQL_DIALECT_TSQL && relpersistence == RELPERSISTENCE_TEMP && get_ENR_withoid(currentQueryEnv, OIDOldHeap, ENR_TSQL_TEMP))
snprintf(NewHeapName, sizeof(NewHeapName), "#pg_temp_%u", OIDOldHeap);
else
snprintf(NewHeapName, sizeof(NewHeapName), "pg_temp_%u", OIDOldHeap);

OIDNewHeap = heap_create_with_catalog(NewHeapName,
namespaceid,
Expand Down Expand Up @@ -1608,6 +1614,8 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
/* rename the toast table ... */
if (sql_dialect == SQL_DIALECT_TSQL && RelationIsBBFTableVariable(newrel))
pg_toast_prefix = "@pg_toast";
else if (sql_dialect == SQL_DIALECT_TSQL && newrel->rd_rel->relpersistence == RELPERSISTENCE_TEMP && get_ENR_withoid(currentQueryEnv, newrel->rd_id, ENR_TSQL_TEMP))
pg_toast_prefix = "#pg_toast";

snprintf(NewToastName, NAMEDATALEN, "%s_%u",
pg_toast_prefix, OIDOldHeap);
Expand Down
2 changes: 1 addition & 1 deletion src/backend/commands/tablecmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -14609,7 +14609,7 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode)
* need to allocate a new one in the new tablespace.
*/
newrelfilenumber = GetNewRelFileNumber(newTableSpace, NULL,
rel->rd_rel->relpersistence);
rel->rd_rel->relpersistence, false);

/* Open old and new relation */
newrlocator = rel->rd_locator;
Expand Down
8 changes: 8 additions & 0 deletions src/backend/utils/activity/pgstat_relation.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
#include "utils/timestamp.h"
#include "catalog/catalog.h"

#include "parser/parser.h"
#include "utils/queryenvironment.h"


/* Record that's written to 2PC state file when pgstat state is persisted */
typedef struct TwoPhasePgStatRecord
Expand Down Expand Up @@ -169,6 +172,9 @@ pgstat_unlink_relation(Relation rel)
void
pgstat_create_relation(Relation rel)
{
/* Skip pg_stat */
if (sql_dialect == SQL_DIALECT_TSQL && rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
return;
pgstat_create_transactional(PGSTAT_KIND_RELATION,
rel->rd_rel->relisshared ? InvalidOid : MyDatabaseId,
RelationGetRelid(rel));
Expand All @@ -183,6 +189,8 @@ pgstat_drop_relation(Relation rel)
int nest_level = GetCurrentTransactionNestLevel();
PgStat_TableStatus *pgstat_info;

if (sql_dialect == SQL_DIALECT_TSQL && rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
return;
pgstat_drop_transactional(PGSTAT_KIND_RELATION,
rel->rd_rel->relisshared ? InvalidOid : MyDatabaseId,
RelationGetRelid(rel));
Expand Down
2 changes: 1 addition & 1 deletion src/backend/utils/cache/relcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -3722,7 +3722,7 @@ RelationSetNewRelfilenumber(Relation relation, char persistence)
{
/* Allocate a new relfilenumber */
newrelfilenumber = GetNewRelFileNumber(relation->rd_rel->reltablespace,
NULL, persistence);
NULL, persistence, false);
}
else if (relation->rd_rel->relkind == RELKIND_INDEX)
{
Expand Down
5 changes: 5 additions & 0 deletions src/backend/utils/misc/guc.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ char *GUC_check_errhint_string;
/* Kluge: for speed, we examine this GUC variable's value directly */
extern bool in_hot_standby_guc;

/*
* OIDs are stored as uint32, so we will add INT_MIN to match the range.
*/
int temp_oid_buffer_start;
int temp_oid_buffer_size;

/*
* Unit conversion tables.
Expand Down
8 changes: 8 additions & 0 deletions src/include/access/transam.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,12 @@ typedef struct VariableCacheData
*/
TransactionId oldestClogXid; /* oldest it's safe to look up in clog */

/*
* This field is also protected by OidGenLock. For tempOidStart, Shmem will
* be the source of truth, as another process may have gotten there first and
* updated the start.
*/
Oid tempOidStart;
} VariableCacheData;

typedef VariableCacheData *VariableCache;
Expand Down Expand Up @@ -295,6 +301,8 @@ extern bool ForceTransactionIdLimitUpdate(void);
extern Oid GetNewObjectId(void);
extern void StopGeneratingPinnedObjectIds(void);

extern int GetVarOidPrefetch(void);

typedef void (*GetNewObjectId_hook_type) (VariableCache variableCache);
extern PGDLLEXPORT GetNewObjectId_hook_type GetNewObjectId_hook;

Expand Down
9 changes: 8 additions & 1 deletion src/include/catalog/catalog.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,14 @@ extern Oid GetNewOidWithIndex(Relation relation, Oid indexId,
AttrNumber oidcolumn);
extern RelFileNumber GetNewRelFileNumber(Oid reltablespace,
Relation pg_class,
char relpersistence);
char relpersistence,
bool override_temp);

typedef Oid (*GetNewTempObjectId_hook_type) (void);
extern GetNewTempObjectId_hook_type GetNewTempObjectId_hook;

typedef Oid (*GetNewTempOidWithIndex_hook_type) (Relation relation, Oid indexId, AttrNumber oidcolumn);
extern GetNewTempOidWithIndex_hook_type GetNewTempOidWithIndex_hook;

typedef bool (*IsExtendedCatalogHookType) (Oid relationId);
extern PGDLLEXPORT IsExtendedCatalogHookType IsExtendedCatalogHook;
Expand Down
3 changes: 3 additions & 0 deletions src/include/utils/guc.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,9 @@ extern PGDLLIMPORT int temp_file_limit;

extern PGDLLIMPORT int num_temp_buffers;

extern PGDLLIMPORT int temp_oid_buffer_start;
extern PGDLLIMPORT int temp_oid_buffer_size;

extern PGDLLIMPORT char *cluster_name;
extern PGDLLIMPORT char *ConfigFileName;
extern PGDLLIMPORT char *HbaFileName;
Expand Down
Loading