]> granicus.if.org Git - postgresql/commitdiff
Disable recheck_on_update optimization to avoid crashes.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 6 Nov 2018 23:33:15 +0000 (18:33 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 6 Nov 2018 23:33:28 +0000 (18:33 -0500)
The code added by commit c203d6cf8 causes a crash in at least one case,
where a potentially-optimizable expression index has a storage type
different from the input data type.  A cursory code review turned up
numerous other problems that seem impractical to fix on short notice.

Andres argued for revert of that patch some time ago, and if additional
senior committers had been paying attention, that's likely what would
have happened, but we were not :-(

At this point we can't just revert, at least not in v11, because that would
mean an ABI break for code touching relcache entries.  And we should not
remove the (also buggy) support for the recheck_on_update index reloption,
since it might already be used in some databases in the field.  So this
patch just does the as-little-invasive-as-possible measure of disabling
the feature as though recheck_on_update were forced off for all indexes.
I also removed the related regression tests (which would otherwise fail)
and the user-facing documentation of the reloption.

We should undertake a more thorough code cleanup if the patch can't be
fixed, but not under the extreme time pressure of being already overdue
for 11.1 release.

Per report from OndÅ™ej Bouda and subsequent private discussion among
pgsql-release.

Discussion: https://postgr.es/m/20181106185255.776mstcyehnc63ty@alvherre.pgsql

doc/src/sgml/ref/create_index.sgml
doc/src/sgml/release-11.sgml
src/backend/utils/cache/relcache.c
src/test/regress/expected/func_index.out [deleted file]
src/test/regress/parallel_schedule
src/test/regress/serial_schedule
src/test/regress/sql/func_index.sql [deleted file]

index 4df3d756de7e50f5c376b60d14e78abd0391fdd7..ad619cdcfe486cd1edb785debe43863b8b979d18 100644 (file)
@@ -356,41 +356,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] <replaceable class=
    <para>
     The optional <literal>WITH</literal> clause specifies <firstterm>storage
     parameters</firstterm> for the index.  Each index method has its own set of allowed
-    storage parameters.  All indexes accept the following parameter:
-   </para>
-
-   <variablelist>
-   <varlistentry>
-    <term><literal>recheck_on_update</literal></term>
-    <listitem>
-     <para>
-       Specifies whether to recheck a functional index value to see whether
-       we can use a HOT update or not. The default value is on for functional
-       indexes with an total expression cost less than 1000, otherwise off.
-       You might decide to turn this off if you knew that a function used in
-       an index is unlikely to return the same value when one of the input
-       columns is updated and so the recheck is not worth the additional cost
-       of executing the function.
-     </para>
-
-     <para>
-       Functional indexes are used frequently for the case where the function
-       returns a subset of the argument. Examples of this would be accessing
-       part of a string with <literal>SUBSTR()</literal> or accessing a single
-       field in a JSON document using an expression such as
-       <literal>(bookinfo-&gt;&gt;'isbn')</literal>. In this example, the JSON
-       document might be updated frequently, yet it is uncommon for the ISBN
-       field for a book to change so we would keep the parameter set to on
-       for that index. A more frequently changing field might have an index
-       with this parameter turned off, while very frequently changing fields
-       might be better to avoid indexing at all under high load.
-     </para>
-    </listitem>
-   </varlistentry>
-   </variablelist>
-
-   <para>
-     The B-tree, hash, GiST and SP-GiST index methods all accept this parameter:
+    storage parameters.  The B-tree, hash, GiST and SP-GiST index methods all
+    accept this parameter:
    </para>
 
    <variablelist>
index f7ddcec1208213b9372a662bb86a656bbb61b816..36e69654e24fedcebc50e6021addc4745384d6ee 100644 (file)
@@ -1437,19 +1437,6 @@ same commits as above
        </para>
       </listitem>
 
-      <listitem>
-<!--
-2018-03-27 [c203d6cf8] Allow HOT updates for some expression indexes
--->
-
-       <para>
-        Allow heap-only-tuple (<acronym>HOT</acronym>) updates for
-        expression indexes when the values of the expressions are unchanged
-        (Konstantin Knizhnik)
-       </para>
-
-      </listitem>
-
      </itemizedlist>
 
      <sect5>
index fd3d010b7783219141f7f25979fde7f61cc5a47c..aecbd4a943711a102a4a5a5aaca698f0999e8ab0 100644 (file)
@@ -4755,6 +4755,7 @@ IsProjectionFunctionalIndex(Relation index, IndexInfo *ii)
 {
        bool            is_projection = false;
 
+#ifdef NOT_USED
        if (ii->ii_Expressions)
        {
                HeapTuple       tuple;
@@ -4800,6 +4801,8 @@ IsProjectionFunctionalIndex(Relation index, IndexInfo *ii)
                }
                ReleaseSysCache(tuple);
        }
+#endif
+
        return is_projection;
 }
 
diff --git a/src/test/regress/expected/func_index.out b/src/test/regress/expected/func_index.out
deleted file mode 100644 (file)
index 307ac97..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-begin;
-create table keyvalue(id integer primary key, info jsonb);
-create index nameindex on keyvalue((info->>'name')) with (recheck_on_update=false);
-insert into keyvalue values (1, '{"name": "john", "data": "some data"}');
-update keyvalue set info='{"name": "john", "data": "some other data"}' where id=1;
-select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass);
- pg_stat_get_xact_tuples_hot_updated 
--------------------------------------
-                                   0
-(1 row)
-
-rollback;
-begin;
-create table keyvalue(id integer primary key, info jsonb);
-create index nameindex on keyvalue((info->>'name')) with (recheck_on_update=true);
-insert into keyvalue values (1, '{"name": "john", "data": "some data"}');
-update keyvalue set info='{"name": "john", "data": "some other data"}' where id=1;
-select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass);
- pg_stat_get_xact_tuples_hot_updated 
--------------------------------------
-                                   1
-(1 row)
-
-update keyvalue set info='{"name": "smith", "data": "some other data"}' where id=1;
-select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass);
- pg_stat_get_xact_tuples_hot_updated 
--------------------------------------
-                                   1
-(1 row)
-
-update keyvalue set info='{"name": "smith", "data": "some more data"}' where id=1;
-select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass);
- pg_stat_get_xact_tuples_hot_updated 
--------------------------------------
-                                   2
-(1 row)
-
-rollback;
-begin;
-create table keyvalue(id integer primary key, info jsonb);
-create index nameindex on keyvalue((info->>'name'));
-insert into keyvalue values (1, '{"name": "john", "data": "some data"}');
-update keyvalue set info='{"name": "john", "data": "some other data"}' where id=1;
-select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass);
- pg_stat_get_xact_tuples_hot_updated 
--------------------------------------
-                                   1
-(1 row)
-
-update keyvalue set info='{"name": "smith", "data": "some other data"}' where id=1;
-select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass);
- pg_stat_get_xact_tuples_hot_updated 
--------------------------------------
-                                   1
-(1 row)
-
-update keyvalue set info='{"name": "smith", "data": "some more data"}' where id=1;
-select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass);
- pg_stat_get_xact_tuples_hot_updated 
--------------------------------------
-                                   2
-(1 row)
-
-rollback;
index b5e15501dd74fdb724fb4b20b6d3b4d254e20331..289c658483c840536e3e078b8bb88fe26782a6fe 100644 (file)
@@ -84,7 +84,7 @@ test: select_into select_distinct select_distinct_on select_implicit select_havi
 # ----------
 # Another group of parallel tests
 # ----------
-test: brin gin gist spgist privileges init_privs security_label collate matview lock replica_identity rowsecurity object_address tablesample groupingsets drop_operator password func_index
+test: brin gin gist spgist privileges init_privs security_label collate matview lock replica_identity rowsecurity object_address tablesample groupingsets drop_operator password
 
 # ----------
 # Another group of parallel tests
index 49329ffbb62fafdb90477b74aa42e4deb4a73f10..bc43b18c628ade0bb78fcb7252ba36596d78076d 100644 (file)
@@ -99,7 +99,6 @@ test: portals
 test: arrays
 test: btree_index
 test: hash_index
-test: func_index
 test: update
 test: delete
 test: namespace
diff --git a/src/test/regress/sql/func_index.sql b/src/test/regress/sql/func_index.sql
deleted file mode 100644 (file)
index c267c93..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-begin;
-create table keyvalue(id integer primary key, info jsonb);
-create index nameindex on keyvalue((info->>'name')) with (recheck_on_update=false);
-insert into keyvalue values (1, '{"name": "john", "data": "some data"}');
-update keyvalue set info='{"name": "john", "data": "some other data"}' where id=1;
-select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass);
-rollback;
-
-begin;
-create table keyvalue(id integer primary key, info jsonb);
-create index nameindex on keyvalue((info->>'name')) with (recheck_on_update=true);
-insert into keyvalue values (1, '{"name": "john", "data": "some data"}');
-update keyvalue set info='{"name": "john", "data": "some other data"}' where id=1;
-select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass);
-update keyvalue set info='{"name": "smith", "data": "some other data"}' where id=1;
-select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass);
-update keyvalue set info='{"name": "smith", "data": "some more data"}' where id=1;
-select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass);
-rollback;
-
-begin;
-create table keyvalue(id integer primary key, info jsonb);
-create index nameindex on keyvalue((info->>'name'));
-insert into keyvalue values (1, '{"name": "john", "data": "some data"}');
-update keyvalue set info='{"name": "john", "data": "some other data"}' where id=1;
-select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass);
-update keyvalue set info='{"name": "smith", "data": "some other data"}' where id=1;
-select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass);
-update keyvalue set info='{"name": "smith", "data": "some more data"}' where id=1;
-select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass);
-rollback;