Skip to content

Commit

Permalink
[#20908] YSQL: Gate inplace index updates behind feature enablement GUC
Browse files Browse the repository at this point in the history
Summary:
D36588 introduced an optimization that enabled updates to non-key columns of secondary indexes to be performed in-place (ie. not require a DELETE + INSERT).
This optimization was ON by default and was not gated behind a feature flag.

This revision introduces a Postgres GUC `yb_enable_inplace_index_update` to enable/disable the feature.
By default the GUC is set to true, keeping the optimization turned ON.
Jira: DB-9891

Test Plan:
Run the following tests:
```
./yb_build.sh --java-test 'org.yb.pgsql.TestPgRegressUpdateOptimized#schedule'
```

Reviewers: smishra, amartsinchyk, tnayak

Reviewed By: smishra

Subscribers: yql

Tags: #jenkins-ready

Differential Revision: https://phorge.dev.yugabyte.com/D38763
  • Loading branch information
karthik-ramanathan-3006 committed Oct 14, 2024
1 parent e1c8f7e commit 73eb957
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 8 deletions.
13 changes: 7 additions & 6 deletions src/postgres/src/backend/executor/execIndexing.c
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,8 @@ YbExecUpdateIndexTuples(ResultRelInfo *resultRelInfo,
ItemPointer tupleid,
EState *estate,
Bitmapset *updatedCols,
bool is_pk_updated)
bool is_pk_updated,
bool is_inplace_update_enabled)
{
int i;
int numIndices;
Expand Down Expand Up @@ -882,7 +883,7 @@ YbExecUpdateIndexTuples(ResultRelInfo *resultRelInfo,

econtext->ecxt_scantuple = slot;
insertApplicable = ExecQual(predicate, econtext);

if (deleteApplicable != insertApplicable)
{
/*
Expand All @@ -897,8 +898,7 @@ YbExecUpdateIndexTuples(ResultRelInfo *resultRelInfo,

continue;
}



if (!deleteApplicable)
{
/* Neither deletes nor updates applicable. Nothing to be done for this index. */
Expand Down Expand Up @@ -934,7 +934,8 @@ YbExecUpdateIndexTuples(ResultRelInfo *resultRelInfo,
}
}

if (!indexRelation->rd_indam->ybamcanupdatetupleinplace)
if (!(is_inplace_update_enabled &&
indexRelation->rd_indam->ybamcanupdatetupleinplace))
{
deleteIndexes = lappend_int(deleteIndexes, i);
insertIndexes = lappend_int(insertIndexes, i);
Expand Down Expand Up @@ -987,7 +988,7 @@ YbExecUpdateIndexTuples(ResultRelInfo *resultRelInfo,
*
* To achieve this, we compute the list of all indexes whose key columns
* are updated. These need the DELETE + INSERT. For all indexes, first
* issue the deletes, followed by the inserts.
* issue the deletes, followed by the inserts.
*/

int j = 0;
Expand Down
4 changes: 3 additions & 1 deletion src/postgres/src/backend/executor/nodeModifyTable.c
Original file line number Diff line number Diff line change
Expand Up @@ -2456,7 +2456,7 @@ ExecUpdateEpilogue(ModifyTableContext *context, UpdateContext *updateCxt,
recheckIndexes = YbExecUpdateIndexTuples(
resultRelInfo, slot, YBCGetYBTupleIdFromSlot(context->planSlot),
oldtuple, tupleid, context->estate, yb_cols_marked_for_update,
yb_is_pk_updated);
yb_is_pk_updated, mtstate->yb_is_inplace_index_update_enabled);
}
}
else
Expand Down Expand Up @@ -4564,6 +4564,8 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
(node->yb_update_affected_entities != NULL &&
operation == CMD_UPDATE && YbIsUpdateOptimizationEnabled());

mtstate->yb_is_inplace_index_update_enabled = yb_enable_inplace_index_update;

/* set up epqstate with dummy subplan data for the moment */
EvalPlanQualInit(&mtstate->mt_epqstate, estate, NULL, NIL, node->epqParam);
mtstate->fireBSTriggers = true;
Expand Down
13 changes: 13 additions & 0 deletions src/postgres/src/backend/utils/misc/guc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2979,6 +2979,19 @@ static struct config_bool ConfigureNamesBool[] =
NULL, NULL, NULL
},

{
{"yb_enable_inplace_index_update", PGC_USERSET, QUERY_TUNING_OTHER,
gettext_noop("Enables the in-place update of non-key columns of secondary indexes "
"when key columns of the index are not updated. This is useful when "
"updating the included columns in a covering index among others."),
NULL,
GUC_NOT_IN_SAMPLE
},
&yb_enable_inplace_index_update,
true,
NULL, NULL, NULL
},

{
{"yb_enable_fkey_catcache", PGC_USERSET, DEVELOPER_OPTIONS,
gettext_noop("Enable preloading of foreign key information into the relation cache."),
Expand Down
1 change: 1 addition & 0 deletions src/postgres/src/backend/utils/misc/pg_yb_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -1640,6 +1640,7 @@ int yb_parallel_range_size = 1024 * 1024;
int yb_insert_on_conflict_read_batch_size = 1024;
bool yb_enable_fkey_catcache = true;
bool yb_enable_nop_alter_role_optimization = true;
bool yb_enable_inplace_index_update = true;

YBUpdateOptimizationOptions yb_update_optimization_options = {
.has_infra = true,
Expand Down
3 changes: 2 additions & 1 deletion src/postgres/src/include/executor/executor.h
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,8 @@ extern List *YbExecUpdateIndexTuples(ResultRelInfo *resultRelInfo,
ItemPointer tupleid,
EState *estate,
Bitmapset *updatedCols,
bool is_pk_updated);
bool is_pk_updated,
bool is_inplace_update_enabled);

/*
* prototypes from functions in execReplication.c
Expand Down
7 changes: 7 additions & 0 deletions src/postgres/src/include/nodes/execnodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1404,6 +1404,13 @@ typedef struct ModifyTableState
* constraint checks etc. This field is set to false for single row txns.
*/
bool yb_is_update_optimization_enabled;

/*
* If enabled, execution seeks to perform inplace update of non-key columns
* of secondary indexes. This field is not applicable to single row txns
* because they do not involve updates to secondary indexes.
*/
bool yb_is_inplace_index_update_enabled;
} ModifyTableState;

/* ----------------
Expand Down
6 changes: 6 additions & 0 deletions src/postgres/src/include/pg_yb_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,12 @@ YbDdlRollbackEnabled () {

extern bool yb_use_hash_splitting_by_default;

/*
* If set to true, non-key columns of secondary indexes are updated in-place
* when no key columns are modified.
*/
extern bool yb_enable_inplace_index_update;

typedef struct YBUpdateOptimizationOptions
{
bool has_infra;
Expand Down

0 comments on commit 73eb957

Please sign in to comment.