mirror of
https://github.com/postgres/postgres.git
synced 2025-06-27 23:21:58 +03:00
Finish reverting "recheck_on_update" patch.
This reverts commitc203d6cf8
and some follow-on fixes, completing the task begun in commit5d28c9bd7
. If that feature is ever resurrected, the code will look quite a bit different from this, so it seems best to start from a clean slate. The v11 branch is not touched; in that branch, the recheck_on_update storage option remains present, but nonfunctional and undocumented. Discussion: https://postgr.es/m/20190114223409.3tcvejfhlvbucrv5@alap3.anarazel.de
This commit is contained in:
@ -57,7 +57,6 @@
|
||||
#include "access/xlogutils.h"
|
||||
#include "catalog/catalog.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "catalog/index.h"
|
||||
#include "miscadmin.h"
|
||||
#include "pgstat.h"
|
||||
#include "port/atomics.h"
|
||||
@ -76,9 +75,7 @@
|
||||
#include "utils/snapmgr.h"
|
||||
#include "utils/syscache.h"
|
||||
#include "utils/tqual.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "nodes/execnodes.h"
|
||||
#include "executor/executor.h"
|
||||
|
||||
|
||||
/* GUC variable */
|
||||
bool synchronize_seqscans = true;
|
||||
@ -130,7 +127,6 @@ static bool ConditionalMultiXactIdWait(MultiXactId multi, MultiXactStatus status
|
||||
static XLogRecPtr log_heap_new_cid(Relation relation, HeapTuple tup);
|
||||
static HeapTuple ExtractReplicaIdentity(Relation rel, HeapTuple tup, bool key_modified,
|
||||
bool *copy);
|
||||
static bool ProjIndexIsUnchanged(Relation relation, HeapTuple oldtup, HeapTuple newtup);
|
||||
|
||||
|
||||
/*
|
||||
@ -3511,7 +3507,6 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
|
||||
HTSU_Result result;
|
||||
TransactionId xid = GetCurrentTransactionId();
|
||||
Bitmapset *hot_attrs;
|
||||
Bitmapset *proj_idx_attrs;
|
||||
Bitmapset *key_attrs;
|
||||
Bitmapset *id_attrs;
|
||||
Bitmapset *interesting_attrs;
|
||||
@ -3575,11 +3570,12 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
|
||||
* Note that we get copies of each bitmap, so we need not worry about
|
||||
* relcache flush happening midway through.
|
||||
*/
|
||||
hot_attrs = RelationGetIndexAttrBitmap(relation, INDEX_ATTR_BITMAP_HOT);
|
||||
proj_idx_attrs = RelationGetIndexAttrBitmap(relation, INDEX_ATTR_BITMAP_PROJ);
|
||||
hot_attrs = RelationGetIndexAttrBitmap(relation, INDEX_ATTR_BITMAP_ALL);
|
||||
key_attrs = RelationGetIndexAttrBitmap(relation, INDEX_ATTR_BITMAP_KEY);
|
||||
id_attrs = RelationGetIndexAttrBitmap(relation,
|
||||
INDEX_ATTR_BITMAP_IDENTITY_KEY);
|
||||
|
||||
|
||||
block = ItemPointerGetBlockNumber(otid);
|
||||
buffer = ReadBuffer(relation, block);
|
||||
page = BufferGetPage(buffer);
|
||||
@ -3599,7 +3595,6 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
|
||||
if (!PageIsFull(page))
|
||||
{
|
||||
interesting_attrs = bms_add_members(interesting_attrs, hot_attrs);
|
||||
interesting_attrs = bms_add_members(interesting_attrs, proj_idx_attrs);
|
||||
hot_attrs_checked = true;
|
||||
}
|
||||
interesting_attrs = bms_add_members(interesting_attrs, key_attrs);
|
||||
@ -3883,7 +3878,6 @@ l2:
|
||||
if (vmbuffer != InvalidBuffer)
|
||||
ReleaseBuffer(vmbuffer);
|
||||
bms_free(hot_attrs);
|
||||
bms_free(proj_idx_attrs);
|
||||
bms_free(key_attrs);
|
||||
bms_free(id_attrs);
|
||||
bms_free(modified_attrs);
|
||||
@ -4191,18 +4185,11 @@ l2:
|
||||
/*
|
||||
* Since the new tuple is going into the same page, we might be able
|
||||
* to do a HOT update. Check if any of the index columns have been
|
||||
* changed, or if we have projection functional indexes, check whether
|
||||
* the old and the new values are the same. If the page was already
|
||||
* full, we may have skipped checking for index columns. If so, HOT
|
||||
* update is possible.
|
||||
* changed. If the page was already full, we may have skipped checking
|
||||
* for index columns. If so, HOT update is possible.
|
||||
*/
|
||||
if (hot_attrs_checked
|
||||
&& !bms_overlap(modified_attrs, hot_attrs)
|
||||
&& (!bms_overlap(modified_attrs, proj_idx_attrs)
|
||||
|| ProjIndexIsUnchanged(relation, &oldtup, newtup)))
|
||||
{
|
||||
if (hot_attrs_checked && !bms_overlap(modified_attrs, hot_attrs))
|
||||
use_hot_update = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4364,7 +4351,6 @@ l2:
|
||||
heap_freetuple(old_key_tuple);
|
||||
|
||||
bms_free(hot_attrs);
|
||||
bms_free(proj_idx_attrs);
|
||||
bms_free(key_attrs);
|
||||
bms_free(id_attrs);
|
||||
bms_free(modified_attrs);
|
||||
@ -4450,87 +4436,6 @@ heap_tuple_attr_equals(TupleDesc tupdesc, int attrnum,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether the value is unchanged after update of a projection
|
||||
* functional index. Compare the new and old values of the indexed
|
||||
* expression to see if we are able to use a HOT update or not.
|
||||
*/
|
||||
static bool
|
||||
ProjIndexIsUnchanged(Relation relation, HeapTuple oldtup, HeapTuple newtup)
|
||||
{
|
||||
ListCell *l;
|
||||
List *indexoidlist = RelationGetIndexList(relation);
|
||||
EState *estate = CreateExecutorState();
|
||||
ExprContext *econtext = GetPerTupleExprContext(estate);
|
||||
TupleTableSlot *slot = MakeSingleTupleTableSlot(RelationGetDescr(relation),
|
||||
&TTSOpsHeapTuple);
|
||||
bool equals = true;
|
||||
Datum old_values[INDEX_MAX_KEYS];
|
||||
bool old_isnull[INDEX_MAX_KEYS];
|
||||
Datum new_values[INDEX_MAX_KEYS];
|
||||
bool new_isnull[INDEX_MAX_KEYS];
|
||||
int indexno = 0;
|
||||
|
||||
econtext->ecxt_scantuple = slot;
|
||||
|
||||
foreach(l, indexoidlist)
|
||||
{
|
||||
if (bms_is_member(indexno, relation->rd_projidx))
|
||||
{
|
||||
Oid indexOid = lfirst_oid(l);
|
||||
Relation indexDesc = index_open(indexOid, AccessShareLock);
|
||||
IndexInfo *indexInfo = BuildIndexInfo(indexDesc);
|
||||
int i;
|
||||
|
||||
ResetExprContext(econtext);
|
||||
ExecStoreHeapTuple(oldtup, slot, false);
|
||||
FormIndexDatum(indexInfo,
|
||||
slot,
|
||||
estate,
|
||||
old_values,
|
||||
old_isnull);
|
||||
|
||||
ExecStoreHeapTuple(newtup, slot, false);
|
||||
FormIndexDatum(indexInfo,
|
||||
slot,
|
||||
estate,
|
||||
new_values,
|
||||
new_isnull);
|
||||
|
||||
for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
|
||||
{
|
||||
if (old_isnull[i] != new_isnull[i])
|
||||
{
|
||||
equals = false;
|
||||
break;
|
||||
}
|
||||
else if (!old_isnull[i])
|
||||
{
|
||||
Form_pg_attribute att = TupleDescAttr(RelationGetDescr(indexDesc), i);
|
||||
|
||||
if (!datumIsEqual(old_values[i], new_values[i], att->attbyval, att->attlen))
|
||||
{
|
||||
equals = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
index_close(indexDesc, AccessShareLock);
|
||||
|
||||
if (!equals)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
indexno += 1;
|
||||
}
|
||||
ExecDropSingleTupleTableSlot(slot);
|
||||
FreeExecutorState(estate);
|
||||
|
||||
return equals;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check which columns are being updated.
|
||||
*
|
||||
|
Reference in New Issue
Block a user