Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1b5d797

Browse files
committed
Lower lock level for renaming indexes
Change lock level for renaming index (either ALTER INDEX or implicitlyvia some other commands) from AccessExclusiveLock toShareUpdateExclusiveLock.One reason we need a strong lock for relation renaming is that thename change causes a rebuild of the relcache entry. Concurrentsessions that have the relation open might not be able to handle therelcache entry changing underneath them. Therefore, we need to lockthe relation in a way that no one can have the relation openconcurrently. But for indexes, the relcache handles reloads speciallyin RelationReloadIndexInfo() in a way that keeps changes in therelcache entry to a minimum. As long as no one keeps pointers tord_amcache and rd_options around across possible relcache flushes,which is the case, this ought to be safe.We also want to use a self-exclusive lock for correctness, so thatconcurrent DDL doesn't overwrite the rename if they start updatingwhile still seeing the old version. Therefore, we useShareUpdateExclusiveLock, which is already used by other DDL commandsthat want to operate in a concurrent manner.The reason this is interesting at all is that renaming an index is atypical part of a concurrent reindexing workflow (CREATE INDEXCONCURRENTLY new + DROP INDEX CONCURRENTLY old + rename back). Andindeed a future built-in REINDEX CONCURRENTLY might rely on the abilityto do concurrent renames as well.Reviewed-by: Andrey Klychkov <aaklychkov@mail.ru>Reviewed-by: Fabrízio de Royes Mello <fabriziomello@gmail.com>Discussion:https://www.postgresql.org/message-id/flat/1531767486.432607658@f357.i.mail.ru
1 parentb4721f3 commit1b5d797

File tree

6 files changed

+36
-21
lines changed

6 files changed

+36
-21
lines changed

‎doc/src/sgml/mvcc.sgml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -926,10 +926,10 @@ ERROR: could not serialize access due to read/write dependencies among transact
926926
<para>
927927
Acquired by <command>VACUUM</command> (without <option>FULL</option>),
928928
<command>ANALYZE</command>, <command>CREATE INDEX CONCURRENTLY</command>,
929-
<command>CREATE STATISTICS</command> and
930-
<command>ALTER TABLE VALIDATE</command>and other
931-
<command>ALTER TABLE</command> variants (for full details see
932-
<xreflinkend="sql-altertable"/>).
929+
<command>CREATE STATISTICS</command>, and certain <command>ALTER
930+
INDEX</command> and <command>ALTER TABLE</command>variants (for full
931+
details see <xref linkend="sql-alterindex"/> and <xref
932+
linkend="sql-altertable"/>).
933933
</para>
934934
</listitem>
935935
</varlistentry>
@@ -970,7 +970,7 @@ ERROR: could not serialize access due to read/write dependencies among transact
970970
</para>
971971

972972
<para>
973-
Acquired by <command>CREATE TRIGGER</command> andmany forms of
973+
Acquired by <command>CREATE TRIGGER</command> andsome forms of
974974
<command>ALTER TABLE</command> (see <xref linkend="sql-altertable"/>).
975975
</para>
976976
</listitem>
@@ -1020,7 +1020,7 @@ ERROR: could not serialize access due to read/write dependencies among transact
10201020
<command>CLUSTER</command>, <command>VACUUM FULL</command>,
10211021
and <command>REFRESH MATERIALIZED VIEW</command> (without
10221022
<option>CONCURRENTLY</option>)
1023-
commands. Many forms of <command>ALTER TABLE</command> also acquire
1023+
commands. Many forms of <command>ALTERINDEX</command> and <command>ALTERTABLE</command> also acquire
10241024
a lock at this level. This is also the default lock mode for
10251025
<command>LOCK TABLE</command> statements that do not specify
10261026
a mode explicitly.

‎doc/src/sgml/ref/alter_index.sgml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ ALTER INDEX ALL IN TABLESPACE <replaceable class="parameter">name</replaceable>
3939

4040
<para>
4141
<command>ALTER INDEX</command> changes the definition of an existing index.
42-
There are several subforms:
42+
There are several subforms described below. Note that the lock level required
43+
may differ for each subform. An <literal>ACCESS EXCLUSIVE</literal> lock is held
44+
unless explicitly noted. When multiple subcommands are listed, the lock
45+
held will be the strictest one required from any subcommand.
4346

4447
<variablelist>
4548

@@ -53,6 +56,10 @@ ALTER INDEX ALL IN TABLESPACE <replaceable class="parameter">name</replaceable>
5356
or <literal>EXCLUDE</literal>), the constraint is renamed as well.
5457
There is no effect on the stored data.
5558
</para>
59+
<para>
60+
Renaming an index acquires a <literal>SHARE UPDATE EXCLUSIVE</literal>
61+
lock.
62+
</para>
5663
</listitem>
5764
</varlistentry>
5865

‎src/backend/commands/cluster.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1661,14 +1661,14 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
16611661
snprintf(NewToastName,NAMEDATALEN,"pg_toast_%u",
16621662
OIDOldHeap);
16631663
RenameRelationInternal(newrel->rd_rel->reltoastrelid,
1664-
NewToastName, true);
1664+
NewToastName, true, false);
16651665

16661666
/* ... and its valid index too. */
16671667
snprintf(NewToastName,NAMEDATALEN,"pg_toast_%u_index",
16681668
OIDOldHeap);
16691669

16701670
RenameRelationInternal(toastidx,
1671-
NewToastName, true);
1671+
NewToastName, true, true);
16721672
}
16731673
relation_close(newrel,NoLock);
16741674
}

‎src/backend/commands/tablecmds.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3044,7 +3044,7 @@ rename_constraint_internal(Oid myrelid,
30443044
||con->contype==CONSTRAINT_UNIQUE
30453045
||con->contype==CONSTRAINT_EXCLUSION))
30463046
/* rename the index; this renames the constraint as well */
3047-
RenameRelationInternal(con->conindid,newconname, false);
3047+
RenameRelationInternal(con->conindid,newconname, false, true);
30483048
else
30493049
RenameConstraintById(constraintOid,newconname);
30503050

@@ -3112,6 +3112,7 @@ RenameConstraint(RenameStmt *stmt)
31123112
ObjectAddress
31133113
RenameRelation(RenameStmt*stmt)
31143114
{
3115+
boolis_index=stmt->renameType==OBJECT_INDEX;
31153116
Oidrelid;
31163117
ObjectAddressaddress;
31173118

@@ -3123,7 +3124,8 @@ RenameRelation(RenameStmt *stmt)
31233124
* Lock level used here should match RenameRelationInternal, to avoid lock
31243125
* escalation.
31253126
*/
3126-
relid=RangeVarGetRelidExtended(stmt->relation,AccessExclusiveLock,
3127+
relid=RangeVarGetRelidExtended(stmt->relation,
3128+
is_index ?ShareUpdateExclusiveLock :AccessExclusiveLock,
31273129
stmt->missing_ok ?RVR_MISSING_OK :0,
31283130
RangeVarCallbackForAlterRelation,
31293131
(void*)stmt);
@@ -3137,7 +3139,7 @@ RenameRelation(RenameStmt *stmt)
31373139
}
31383140

31393141
/* Do the work */
3140-
RenameRelationInternal(relid,stmt->newname, false);
3142+
RenameRelationInternal(relid,stmt->newname, false,is_index);
31413143

31423144
ObjectAddressSet(address,RelationRelationId,relid);
31433145

@@ -3148,7 +3150,7 @@ RenameRelation(RenameStmt *stmt)
31483150
*RenameRelationInternal - change the name of a relation
31493151
*/
31503152
void
3151-
RenameRelationInternal(Oidmyrelid,constchar*newrelname,boolis_internal)
3153+
RenameRelationInternal(Oidmyrelid,constchar*newrelname,boolis_internal,boolis_index)
31523154
{
31533155
Relationtargetrelation;
31543156
Relationrelrelation;/* for RELATION relation */
@@ -3157,11 +3159,16 @@ RenameRelationInternal(Oid myrelid, const char *newrelname, bool is_internal)
31573159
OidnamespaceId;
31583160

31593161
/*
3160-
* Grab an exclusive lock on the target table, index, sequence, view,
3161-
* materialized view, or foreign table, which we will NOT release until
3162-
* end of transaction.
3162+
* Grab a lock on the target relation, which we will NOT release until end
3163+
* of transaction. We need at least a self-exclusive lock so that
3164+
* concurrent DDL doesn't overwrite the rename if they start updating
3165+
* while still seeing the old version. The lock also guards against
3166+
* triggering relcache reloads in concurrent sessions, which might not
3167+
* handle this information changing under them. For indexes, we can use a
3168+
* reduced lock level because RelationReloadIndexInfo() handles indexes
3169+
* specially.
31633170
*/
3164-
targetrelation=relation_open(myrelid,AccessExclusiveLock);
3171+
targetrelation=relation_open(myrelid,is_index ?ShareUpdateExclusiveLock :AccessExclusiveLock);
31653172
namespaceId=RelationGetNamespace(targetrelation);
31663173

31673174
/*
@@ -3214,7 +3221,7 @@ RenameRelationInternal(Oid myrelid, const char *newrelname, bool is_internal)
32143221
}
32153222

32163223
/*
3217-
* Close rel, but keepexclusivelock!
3224+
* Close rel, but keep lock!
32183225
*/
32193226
relation_close(targetrelation,NoLock);
32203227
}
@@ -7076,7 +7083,7 @@ ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel,
70767083
ereport(NOTICE,
70777084
(errmsg("ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"",
70787085
indexName,constraintName)));
7079-
RenameRelationInternal(index_oid,constraintName, false);
7086+
RenameRelationInternal(index_oid,constraintName, false, true);
70807087
}
70817088

70827089
/* Extra checks needed if making primary key */

‎src/backend/commands/typecmds.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3255,7 +3255,7 @@ RenameType(RenameStmt *stmt)
32553255
* RenameRelationInternal will call RenameTypeInternal automatically.
32563256
*/
32573257
if (typTup->typtype==TYPTYPE_COMPOSITE)
3258-
RenameRelationInternal(typTup->typrelid,newTypeName, false);
3258+
RenameRelationInternal(typTup->typrelid,newTypeName, false, false);
32593259
else
32603260
RenameTypeInternal(typeOid,newTypeName,
32613261
typTup->typnamespace);

‎src/include/commands/tablecmds.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ extern ObjectAddress RenameConstraint(RenameStmt *stmt);
6767
externObjectAddressRenameRelation(RenameStmt*stmt);
6868

6969
externvoidRenameRelationInternal(Oidmyrelid,
70-
constchar*newrelname,boolis_internal);
70+
constchar*newrelname,boolis_internal,
71+
boolis_index);
7172

7273
externvoidfind_composite_type_dependencies(OidtypeOid,
7374
RelationorigRelation,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp