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

Commita8aaa0c

Browse files
committed
Morph pg_replication_slots.min_safe_lsn to safe_wal_size
The previous definition of the column was almost universally disliked,so provide this updated definition which is more useful for monitoringpurposes: a large positive value is good, while zero or a negative valuemeans danger. This should be operationally more convenient.Backpatch to 13, where the new column to pg_replication_slots (and thefeature it represents) were added.Author: Kyotaro Horiguchi <horikyota.ntt@gmail.com>Author: Álvaro Herrera <alvherre@alvh.no-ip.org>Reported-by: Fujii Masao <masao.fujii@oss.nttdata.com>Discussion:https://postgr.es/m/9ddfbf8c-2f67-904d-44ed-cf8bc5916228@oss.nttdata.com
1 parent6a5c750 commita8aaa0c

File tree

9 files changed

+60
-34
lines changed

9 files changed

+60
-34
lines changed

‎doc/src/sgml/catalogs.sgml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11275,10 +11275,13 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
1127511275

1127611276
<row>
1127711277
<entry role="catalog_table_entry"><para role="column_definition">
11278-
<structfield>min_safe_lsn</structfield> <type>pg_lsn</type>
11278+
<structfield>safe_wal_size</structfield> <type>int8</type>
1127911279
</para>
1128011280
<para>
11281-
The minimum LSN currently available for walsenders.
11281+
The number of bytes that can be written to WAL such that this slot
11282+
is not in danger of getting in state "lost". It is NULL for lost
11283+
slots, as well as if <varname>max_slot_wal_keep_size</varname>
11284+
is <literal>-1</literal>.
1128211285
</para></entry>
1128311286
</row>
1128411287
</tbody>

‎src/backend/access/transam/xlog.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -764,8 +764,7 @@ static ControlFileData *ControlFile = NULL;
764764
* Convert values of GUCs measured in megabytes to equiv. segment count.
765765
* Rounds down.
766766
*/
767-
#defineConvertToXSegs(x,segsize)\
768-
((x) / ((segsize) / (1024 * 1024)))
767+
#defineConvertToXSegs(x,segsize)XLogMBVarToSegs((x), (segsize))
769768

770769
/* The number of bytes in a WAL segment usable for WAL data. */
771770
staticintUsableBytesInSegment;
@@ -9513,8 +9512,7 @@ GetWALAvailability(XLogRecPtr targetLSN)
95139512
XLogSegNotargetSeg;/* segid of targetLSN */
95149513
XLogSegNooldestSeg;/* actual oldest segid */
95159514
XLogSegNooldestSegMaxWalSize;/* oldest segid kept by max_wal_size */
9516-
XLogSegNooldestSlotSeg=InvalidXLogRecPtr;/* oldest segid kept by
9517-
* slot */
9515+
XLogSegNooldestSlotSeg;/* oldest segid kept by slot */
95189516
uint64keepSegs;
95199517

95209518
/*

‎src/backend/catalog/system_views.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -879,7 +879,7 @@ CREATE VIEW pg_replication_slots AS
879879
L.restart_lsn,
880880
L.confirmed_flush_lsn,
881881
L.wal_status,
882-
L.min_safe_lsn
882+
L.safe_wal_size
883883
FROM pg_get_replication_slots()AS L
884884
LEFT JOIN pg_database DON (L.datoid=D.oid);
885885

‎src/backend/replication/slotfuncs.c

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
242242
Tuplestorestate*tupstore;
243243
MemoryContextper_query_ctx;
244244
MemoryContextoldcontext;
245+
XLogRecPtrcurrlsn;
245246
intslotno;
246247

247248
/* check to see if caller supports us returning a tuplestore */
@@ -274,6 +275,8 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
274275

275276
MemoryContextSwitchTo(oldcontext);
276277

278+
currlsn=GetXLogWriteRecPtr();
279+
277280
LWLockAcquire(ReplicationSlotControlLock,LW_SHARED);
278281
for (slotno=0;slotno<max_replication_slots;slotno++)
279282
{
@@ -282,7 +285,6 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
282285
Datumvalues[PG_GET_REPLICATION_SLOTS_COLS];
283286
boolnulls[PG_GET_REPLICATION_SLOTS_COLS];
284287
WALAvailabilitywalstate;
285-
XLogSegNolast_removed_seg;
286288
inti;
287289

288290
if (!slot->in_use)
@@ -380,36 +382,54 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
380382
* we looked. If checkpointer signalled the process to
381383
* termination, then it's definitely lost; but if a process is
382384
* still alive, then "unreserved" seems more appropriate.
385+
*
386+
* If we do change it, save the state for safe_wal_size below.
383387
*/
384388
if (!XLogRecPtrIsInvalid(slot_contents.data.restart_lsn))
385389
{
386390
intpid;
387391

388392
SpinLockAcquire(&slot->mutex);
389393
pid=slot->active_pid;
394+
slot_contents.data.restart_lsn=slot->data.restart_lsn;
390395
SpinLockRelease(&slot->mutex);
391396
if (pid!=0)
392397
{
393398
values[i++]=CStringGetTextDatum("unreserved");
399+
walstate=WALAVAIL_UNRESERVED;
394400
break;
395401
}
396402
}
397403
values[i++]=CStringGetTextDatum("lost");
398404
break;
399405
}
400406

401-
if (max_slot_wal_keep_size_mb >=0&&
402-
(walstate==WALAVAIL_RESERVED||walstate==WALAVAIL_EXTENDED)&&
403-
((last_removed_seg=XLogGetLastRemovedSegno())!=0))
407+
/*
408+
* safe_wal_size is only computed for slots that have not been lost,
409+
* and only if there's a configured maximum size.
410+
*/
411+
if (walstate==WALAVAIL_REMOVED||max_slot_wal_keep_size_mb<0)
412+
nulls[i++]= true;
413+
else
404414
{
405-
XLogRecPtrmin_safe_lsn;
415+
XLogSegNotargetSeg;
416+
XLogSegNokeepSegs;
417+
XLogSegNofailSeg;
418+
XLogRecPtrfailLSN;
406419

407-
XLogSegNoOffsetToRecPtr(last_removed_seg+1,0,
408-
wal_segment_size,min_safe_lsn);
409-
values[i++]=Int64GetDatum(min_safe_lsn);
420+
XLByteToSeg(slot_contents.data.restart_lsn,targetSeg,wal_segment_size);
421+
422+
/* determine how many segments slots can be kept by slots ... */
423+
keepSegs=XLogMBVarToSegs(max_slot_wal_keep_size_mb,wal_segment_size);
424+
/* ... and override by wal_keep_segments as needed */
425+
keepSegs=Max(keepSegs,wal_keep_segments);
426+
427+
/* if currpos reaches failLSN, we lose our segment */
428+
failSeg=targetSeg+keepSegs+1;
429+
XLogSegNoOffsetToRecPtr(failSeg,0,wal_segment_size,failLSN);
430+
431+
values[i++]=Int64GetDatum(failLSN-currlsn);
410432
}
411-
else
412-
nulls[i++]= true;
413433

414434
Assert(i==PG_GET_REPLICATION_SLOTS_COLS);
415435

‎src/include/access/xlog_internal.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,13 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
121121
#defineXLByteToPrevSeg(xlrp,logSegNo,wal_segsz_bytes) \
122122
logSegNo = ((xlrp) - 1) / (wal_segsz_bytes)
123123

124+
/*
125+
* Convert values of GUCs measured in megabytes to equiv. segment count.
126+
* Rounds down.
127+
*/
128+
#defineXLogMBVarToSegs(mbvar,wal_segsz_bytes) \
129+
((mbvar) / ((wal_segsz_bytes) / (1024 * 1024)))
130+
124131
/*
125132
* Is an XLogRecPtr within a particular XLOG segment?
126133
*

‎src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/*yyyymmddN */
56-
#defineCATALOG_VERSION_NO202007061
56+
#defineCATALOG_VERSION_NO202007071
5757

5858
#endif

‎src/include/catalog/pg_proc.dat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10075,9 +10075,9 @@
1007510075
proname => 'pg_get_replication_slots', prorows => '10', proisstrict => 'f',
1007610076
proretset => 't', provolatile => 's', prorettype => 'record',
1007710077
proargtypes => '',
10078-
proallargtypes => '{name,name,text,oid,bool,bool,int4,xid,xid,pg_lsn,pg_lsn,text,pg_lsn}',
10078+
proallargtypes => '{name,name,text,oid,bool,bool,int4,xid,xid,pg_lsn,pg_lsn,text,int8}',
1007910079
proargmodes => '{o,o,o,o,o,o,o,o,o,o,o,o,o}',
10080-
proargnames => '{slot_name,plugin,slot_type,datoid,temporary,active,active_pid,xmin,catalog_xmin,restart_lsn,confirmed_flush_lsn,wal_status,min_safe_lsn}',
10080+
proargnames => '{slot_name,plugin,slot_type,datoid,temporary,active,active_pid,xmin,catalog_xmin,restart_lsn,confirmed_flush_lsn,wal_status,safe_wal_size}',
1008110081
prosrc => 'pg_get_replication_slots' },
1008210082
{ oid => '3786', descr => 'set up a logical replication slot',
1008310083
proname => 'pg_create_logical_replication_slot', provolatile => 'v',

‎src/test/recovery/t/019_replslot_limit.pl

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
# The slot state and remain should be null before the first connection
3030
my$result =$node_master->safe_psql('postgres',
31-
"SELECT restart_lsn IS NULL, wal_status is NULL,min_safe_lsn is NULL FROM pg_replication_slots WHERE slot_name = 'rep1'"
31+
"SELECT restart_lsn IS NULL, wal_status is NULL,safe_wal_size is NULL FROM pg_replication_slots WHERE slot_name = 'rep1'"
3232
);
3333
is($result,"t|t|t",'check the state of non-reserved slot is "unknown"');
3434

@@ -52,9 +52,9 @@
5252
# Stop standby
5353
$node_standby->stop;
5454

55-
# Preparation done, the slot is the state "normal" now
55+
# Preparation done, the slot is the state "reserved" now
5656
$result =$node_master->safe_psql('postgres',
57-
"SELECT wal_status,min_safe_lsn is NULL FROM pg_replication_slots WHERE slot_name = 'rep1'"
57+
"SELECT wal_status,safe_wal_size IS NULL FROM pg_replication_slots WHERE slot_name = 'rep1'"
5858
);
5959
is($result,"reserved|t",'check the catching-up state');
6060

@@ -64,7 +64,7 @@
6464

6565
# The slot is always "safe" when fitting max_wal_size
6666
$result =$node_master->safe_psql('postgres',
67-
"SELECT wal_status,min_safe_lsn is NULL FROM pg_replication_slots WHERE slot_name = 'rep1'"
67+
"SELECT wal_status,safe_wal_size IS NULL FROM pg_replication_slots WHERE slot_name = 'rep1'"
6868
);
6969
is($result,"reserved|t",
7070
'check that it is safe if WAL fits in max_wal_size');
@@ -74,7 +74,7 @@
7474

7575
# The slot is always "safe" when max_slot_wal_keep_size is not set
7676
$result =$node_master->safe_psql('postgres',
77-
"SELECT wal_status,min_safe_lsn is NULL FROM pg_replication_slots WHERE slot_name = 'rep1'"
77+
"SELECT wal_status,safe_wal_size IS NULL FROM pg_replication_slots WHERE slot_name = 'rep1'"
7878
);
7979
is($result,"reserved|t",'check that slot is working');
8080

@@ -94,9 +94,7 @@
9494
));
9595
$node_master->reload;
9696

97-
# The slot is in safe state. The distance from the min_safe_lsn should
98-
# be as almost (max_slot_wal_keep_size - 1) times large as the segment
99-
# size
97+
# The slot is in safe state.
10098

10199
$result =$node_master->safe_psql('postgres',
102100
"SELECT wal_status FROM pg_replication_slots WHERE slot_name = 'rep1'");
@@ -110,7 +108,7 @@
110108
$result =$node_master->safe_psql('postgres',
111109
"SELECT wal_status FROM pg_replication_slots WHERE slot_name = 'rep1'");
112110
is($result,"reserved",
113-
'check thatmin_safe_lsn gets close to the current LSN');
111+
'check thatsafe_wal_size gets close to the current LSN');
114112

115113
# The standby can reconnect to master
116114
$node_standby->start;
@@ -152,9 +150,9 @@
152150
# Advance WAL again without checkpoint; remain goes to 0.
153151
advance_wal($node_master, 1);
154152

155-
# Slot gets into 'unreserved' state
153+
# Slot gets into 'unreserved' state and safe_wal_size is negative
156154
$result =$node_master->safe_psql('postgres',
157-
"SELECT wal_status,min_safe_lsn is NULL FROM pg_replication_slots WHERE slot_name = 'rep1'"
155+
"SELECT wal_status,safe_wal_size <= 0 FROM pg_replication_slots WHERE slot_name = 'rep1'"
158156
);
159157
is($result,"unreserved|t",
160158
'check that the slot state changes to "unreserved"');
@@ -186,7 +184,7 @@
186184

187185
# This slot should be broken
188186
$result =$node_master->safe_psql('postgres',
189-
"SELECT slot_name, active, restart_lsn IS NULL, wal_status,min_safe_lsn FROM pg_replication_slots WHERE slot_name = 'rep1'"
187+
"SELECT slot_name, active, restart_lsn IS NULL, wal_status,safe_wal_size FROM pg_replication_slots WHERE slot_name = 'rep1'"
190188
);
191189
is($result,"rep1|f|t|lost|",
192190
'check that the slot became inactive and the state "lost" persists');

‎src/test/regress/expected/rules.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,8 +1464,8 @@ pg_replication_slots| SELECT l.slot_name,
14641464
l.restart_lsn,
14651465
l.confirmed_flush_lsn,
14661466
l.wal_status,
1467-
l.min_safe_lsn
1468-
FROM (pg_get_replication_slots() l(slot_name, plugin, slot_type, datoid, temporary, active, active_pid, xmin, catalog_xmin, restart_lsn, confirmed_flush_lsn, wal_status,min_safe_lsn)
1467+
l.safe_wal_size
1468+
FROM (pg_get_replication_slots() l(slot_name, plugin, slot_type, datoid, temporary, active, active_pid, xmin, catalog_xmin, restart_lsn, confirmed_flush_lsn, wal_status,safe_wal_size)
14691469
LEFT JOIN pg_database d ON ((l.datoid = d.oid)));
14701470
pg_roles| SELECT pg_authid.rolname,
14711471
pg_authid.rolsuper,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp