mirror of
https://github.com/postgres/postgres.git
synced 2025-11-24 00:23:06 +03:00
Track collation versions for indexes.
Record the current version of dependent collations in pg_depend when creating or rebuilding an index. When accessing the index later, warn that the index may be corrupted if the current version doesn't match. Thanks to Douglas Doole, Peter Eisentraut, Christoph Berg, Laurenz Albe, Michael Paquier, Robert Haas, Tom Lane and others for very helpful discussion. Author: Thomas Munro <thomas.munro@gmail.com> Author: Julien Rouhaud <rjuju123@gmail.com> Reviewed-by: Peter Eisentraut <peter.eisentraut@2ndquadrant.com> (earlier versions) Discussion: https://postgr.es/m/CAEepm%3D0uEQCpfq_%2BLYFBdArCe4Ot98t1aR4eYiYTe%3DyavQygiQ%40mail.gmail.com
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
#include "access/table.h"
|
||||
#include "catalog/dependency.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/pg_collation.h"
|
||||
#include "catalog/pg_constraint.h"
|
||||
#include "catalog/pg_depend.h"
|
||||
#include "catalog/pg_extension.h"
|
||||
@@ -27,6 +28,7 @@
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/fmgroids.h"
|
||||
#include "utils/lsyscache.h"
|
||||
#include "utils/pg_locale.h"
|
||||
#include "utils/rel.h"
|
||||
|
||||
|
||||
@@ -45,19 +47,24 @@ recordDependencyOn(const ObjectAddress *depender,
|
||||
const ObjectAddress *referenced,
|
||||
DependencyType behavior)
|
||||
{
|
||||
recordMultipleDependencies(depender, referenced, 1, NULL, behavior);
|
||||
recordMultipleDependencies(depender, referenced, 1, behavior, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Record multiple dependencies (of the same kind) for a single dependent
|
||||
* object. This has a little less overhead than recording each separately.
|
||||
*
|
||||
* If record_version is true, then a record is added even if the referenced
|
||||
* object is pinned, and the dependency version will be retrieved according to
|
||||
* the referenced object kind. For now, only collation version is
|
||||
* supported.
|
||||
*/
|
||||
void
|
||||
recordMultipleDependencies(const ObjectAddress *depender,
|
||||
const ObjectAddress *referenced,
|
||||
int nreferenced,
|
||||
const char *version,
|
||||
DependencyType behavior)
|
||||
DependencyType behavior,
|
||||
bool record_version)
|
||||
{
|
||||
Relation dependDesc;
|
||||
CatalogIndexState indstate;
|
||||
@@ -66,6 +73,7 @@ recordMultipleDependencies(const ObjectAddress *depender,
|
||||
max_slots,
|
||||
slot_init_count,
|
||||
slot_stored_count;
|
||||
char *version = NULL;
|
||||
|
||||
if (nreferenced <= 0)
|
||||
return; /* nothing to do */
|
||||
@@ -96,12 +104,38 @@ recordMultipleDependencies(const ObjectAddress *depender,
|
||||
slot_init_count = 0;
|
||||
for (i = 0; i < nreferenced; i++, referenced++)
|
||||
{
|
||||
bool ignore_systempin = false;
|
||||
|
||||
if (record_version)
|
||||
{
|
||||
/* For now we only know how to deal with collations. */
|
||||
if (referenced->classId == CollationRelationId)
|
||||
{
|
||||
/* C and POSIX don't need version tracking. */
|
||||
if (referenced->objectId == C_COLLATION_OID ||
|
||||
referenced->objectId == POSIX_COLLATION_OID)
|
||||
continue;
|
||||
|
||||
version = get_collation_version_for_oid(referenced->objectId);
|
||||
|
||||
/*
|
||||
* Default collation is pinned, so we need to force recording
|
||||
* the dependency to store the version.
|
||||
*/
|
||||
if (referenced->objectId == DEFAULT_COLLATION_OID)
|
||||
ignore_systempin = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
Assert(!version);
|
||||
|
||||
/*
|
||||
* If the referenced object is pinned by the system, there's no real
|
||||
* need to record dependencies on it. This saves lots of space in
|
||||
* pg_depend, so it's worth the time taken to check.
|
||||
* need to record dependencies on it, unless we need to record a
|
||||
* version. This saves lots of space in pg_depend, so it's worth the
|
||||
* time taken to check.
|
||||
*/
|
||||
if (isObjectPinned(referenced, dependDesc))
|
||||
if (!ignore_systempin && isObjectPinned(referenced, dependDesc))
|
||||
continue;
|
||||
|
||||
if (slot_init_count < max_slots)
|
||||
|
||||
Reference in New Issue
Block a user