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

Commit3cb2f13

Browse files
Fix pg_sequence_last_value() for unlogged sequences on standbys.
Presently, when this function is called for an unlogged sequence ona standby server, it will error out with a message likeERROR: could not open file "base/5/16388": No such file or directorySince the pg_sequences system view uses pg_sequence_last_value(),it can error similarly. To fix, modify the function to return NULLfor unlogged sequences on standby servers. Since this bug ispresent on all versions since v15, this approach is preferable tomaking the ERROR nicer because we need to repair the pg_sequencesview without modifying its definition on released versions. Forconsistency, this commit also modifies the function to return NULLfor other sessions' temporary sequences. The pg_sequences viewalready appropriately filters out such sequences, so there's no bugthere, but we might as well offer some defense in case someoneinvokes this function directly.Unlogged sequences were first introduced in v15, but temporarysequences are much older, so while the fix for unlogged sequencesis only back-patched to v15, the temporary sequence portion isback-patched to all supported versions.We could also remove the privilege check in the pg_sequences viewdefinition in v18 if we modify this function to return NULL forsequences for which the current user lacks privileges, but that isleft as a future exercise for when v18 development begins.Reviewed-by: Tom Lane, Michael PaquierDiscussion:https://postgr.es/m/20240501005730.GA594666%40nathanxps13Backpatch-through: 12
1 parent1f7452f commit3cb2f13

File tree

3 files changed

+55
-13
lines changed

3 files changed

+55
-13
lines changed

‎doc/src/sgml/system-views.sgml‎

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3091,15 +3091,36 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
30913091
<para>
30923092
The last sequence value written to disk. If caching is used,
30933093
this value can be greater than the last value handed out from the
3094-
sequence. Null if the sequence has not been read from yet. Also, if
3095-
the current user does not have <literal>USAGE</literal>
3096-
or <literal>SELECT</literal> privilege on the sequence, the value is
3097-
null.
3094+
sequence.
30983095
</para></entry>
30993096
</row>
31003097
</tbody>
31013098
</tgroup>
31023099
</table>
3100+
3101+
<para>
3102+
The <structfield>last_value</structfield> column will read as null if any of
3103+
the following are true:
3104+
<itemizedlist>
3105+
<listitem>
3106+
<para>
3107+
The sequence has not been read from yet.
3108+
</para>
3109+
</listitem>
3110+
<listitem>
3111+
<para>
3112+
The current user does not have <literal>USAGE</literal> or
3113+
<literal>SELECT</literal> privilege on the sequence.
3114+
</para>
3115+
</listitem>
3116+
<listitem>
3117+
<para>
3118+
The sequence is unlogged and the server is a standby.
3119+
</para>
3120+
</listitem>
3121+
</itemizedlist>
3122+
</para>
3123+
31033124
</sect1>
31043125

31053126
<sect1 id="view-pg-settings">

‎src/backend/commands/sequence.c‎

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1777,11 +1777,8 @@ pg_sequence_last_value(PG_FUNCTION_ARGS)
17771777
Oidrelid=PG_GETARG_OID(0);
17781778
SeqTableelm;
17791779
Relationseqrel;
1780-
Bufferbuf;
1781-
HeapTupleDataseqtuple;
1782-
Form_pg_sequence_dataseq;
1783-
boolis_called;
1784-
int64result;
1780+
boolis_called= false;
1781+
int64result=0;
17851782

17861783
/* open and lock sequence */
17871784
init_sequence(relid,&elm,&seqrel);
@@ -1792,12 +1789,28 @@ pg_sequence_last_value(PG_FUNCTION_ARGS)
17921789
errmsg("permission denied for sequence %s",
17931790
RelationGetRelationName(seqrel))));
17941791

1795-
seq=read_seq_tuple(seqrel,&buf,&seqtuple);
1792+
/*
1793+
* We return NULL for other sessions' temporary sequences. The
1794+
* pg_sequences system view already filters those out, but this offers a
1795+
* defense against ERRORs in case someone invokes this function directly.
1796+
*
1797+
* Also, for the benefit of the pg_sequences view, we return NULL for
1798+
* unlogged sequences on standbys instead of throwing an error.
1799+
*/
1800+
if (!RELATION_IS_OTHER_TEMP(seqrel)&&
1801+
(RelationIsPermanent(seqrel)|| !RecoveryInProgress()))
1802+
{
1803+
Bufferbuf;
1804+
HeapTupleDataseqtuple;
1805+
Form_pg_sequence_dataseq;
1806+
1807+
seq=read_seq_tuple(seqrel,&buf,&seqtuple);
17961808

1797-
is_called=seq->is_called;
1798-
result=seq->last_value;
1809+
is_called=seq->is_called;
1810+
result=seq->last_value;
17991811

1800-
UnlockReleaseBuffer(buf);
1812+
UnlockReleaseBuffer(buf);
1813+
}
18011814
sequence_close(seqrel,NoLock);
18021815

18031816
if (is_called)

‎src/test/recovery/t/001_stream_rep.pl‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ BEGIN
9595
print"standby 2:$result\n";
9696
is($result,qq(33|0|t),'check streamed sequence content on standby 2');
9797

98+
# Check pg_sequence_last_value() returns NULL for unlogged sequence on standby
99+
$node_primary->safe_psql('postgres',
100+
"CREATE UNLOGGED SEQUENCE ulseq; SELECT nextval('ulseq')");
101+
$node_primary->wait_for_replay_catchup($node_standby_1);
102+
is($node_standby_1->safe_psql('postgres',
103+
"SELECT pg_sequence_last_value('ulseq'::regclass) IS NULL"),
104+
't','pg_sequence_last_value() on unlogged sequence on standby 1');
105+
98106
# Check that only READ-only queries can run on standbys
99107
is($node_standby_1->psql('postgres','INSERT INTO tab_int VALUES (1)'),
100108
3,'read-only queries on standby 1');

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp