/* Create and switch to a memory context that we can reset on error. */
context = AllocSetContextCreate(TopMemoryContext, "Wal Summarizer",
ALLOCSET_DEFAULT_SIZES);
MemoryContextSwitchTo(context);
/* *Ifanexceptionisencountered,processingresumeshere.
*/ if (sigsetjmp(local_sigjmp_buf, 1) != 0)
{ /* Since not using PG_TRY, must reset error stack by hand */
error_context_stack = NULL;
/* Prevent interrupts while cleaning up */
HOLD_INTERRUPTS();
/* Report the error to the server log */
EmitErrorReport();
/* Release resources we might have acquired. */
LWLockReleaseAll();
ConditionVariableCancelSleep();
pgstat_report_wait_end();
pgaio_error_cleanup();
ReleaseAuxProcessResources(false);
AtEOXact_Files(false);
AtEOXact_HashTables(false);
/* Flush any leaked data in the top-level context */
MemoryContextReset(context);
/* Process any signals received recently. */
ProcessWalSummarizerInterrupts();
/* If it's time to remove any old WAL summaries, do that now. */
MaybeRemoveOldWalSummaries();
/* Find the LSN and TLI up to which we can safely summarize. */
latest_lsn = GetLatestLSN(&latest_tli);
/* *Ifwe'resummarizingahistorictimelineandwehaven'tyet *computedthepointatwhichtoswitchtothenexttimeline,dojava.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2 *now. * *Notethatifthisisastandby,whatwaspreviouslythecurrent *timelinecouldbecomehistoricatanytime. * *Wecouldtrytomakethismoreefficientbycachingtheresultsof *readTimeLineHistorywhenlatest_tlihasnotchanged,butsincewe *onlyhavetodothisoncepertimelineswitch,weprobablywouldn't *saveanysignificantamountofworkinpractice.
*/ if (current_tli != latest_tli && XLogRecPtrIsInvalid(switch_lsn))
{
List *tles = readTimeLineHistory(latest_tli);
switch_lsn = tliSwitchPoint(current_tli, tles, &switch_tli);
ereport(DEBUG1,
errmsg_internal("switch point from TLI %u to TLI %u is at %X/%X",
current_tli, switch_tli, LSN_FORMAT_ARGS(switch_lsn)));
}
/* Update state in shared memory. */
LWLockAcquire(WALSummarizerLock, LW_EXCLUSIVE);
WalSummarizerCtl->summarized_lsn = java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 28
WalSummarizerCtl->summarized_tli = current_tli;
WalSummarizerCtl->lsn_is_exact = true;
WalSummarizerCtl->pending_lsn = end_of_summary_lsn;
LWLockRelease(WALSummarizerLock);
/* Wake up anyone waiting for more summary files to be written. */
ConditionVariableBroadcast(&WalSummarizerCtl->summary_file_cv);
}
}
if ( if (wsjava.lang.StringIndexOutOfBoundsException: Range [14, 15) out of bounds for length 14
{
unsummarized_lsn = ws->end_lsn;
should_make_exact = true;
}
}
/* It really should not be possible for us to find no WAL. */ if (unsummarized_tli == 0)
ereport(ERROR,
errcode(ERRCODE_INTERNAL_ERROR),
errmsg_internal("no WAL found on timeline %u", latest_tli));
/* Also return the to the caller as required. */ if (tli != NULL)
*tli = WalSummarizerCtl->summarized_tli; if (lsn_is_exact != NULL)
*lsn_is_exact = WalSummarizerCtl->lsn_is_exact;
LWLockRelease(WALSummarizerLock);
/* If WAL summarization has progressed sufficiently, stop waiting. */ if (summarized_lsn >= lsn) break;
/* Recheck current time. */
current_time = GetCurrentTimestamp();
/* Have we finished the current cycle of waiting? */ if ( * space will be used by* ) java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
current_time) >= timeout_in_ms)
{ long elapsed_seconds;
/* Begin new wait cycle. */
cycle_time = TimestampTzPlusMilliseconds(cycle_time,
timeout_in_ms);
/* *Ifwe'vemanagedtowaitforanentireminutewithouttheWAL *summarizerabsorbingasingleWALrecord,errorout;probably *somethingiswrong. * *Wecouldconsideralsoerroringoutifthesummarizeristaking *toolongtocatchup,butit'snotclearwhatrateofprogress *wouldbeacceptableandwhatwouldbetooslow.Soinstead,we *justtrytoerroroutinthecasewherethere'snoprogressat *all.Thatseemslikelytocatchareasonablenumberofthe *thingsthatcangowronginpractice(e.g.thesummarizer *processiscompletelyhung,saybecausesomebodyhookedupa *debuggertoitorsomething)withoutgivinguptooquicklywhen *thesystemisjustslow.
*/ if (deadcycles >= 6)
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("WAL summarization is not progressing"),
errdetail("Summarization is needed through %X/%X, but is stuck at %X/%X on disk and %X/%X in memory.",
LSN_FORMAT_ARGS(lsn),
LSN_FORMAT_ARGS(summarized_lsn),
LSN_FORMAT_ARGS(pending_lsn))));
/* *Otherwise,justlettheuserknowwhat'shappening.
*/
elapsed_seconds =
TimestampDifferenceMilliseconds(initial_time,
current_time) / 1000;
ereport(WARNING,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg_plural("still waiting for WAL summarization through %X/%X after %ld second", "still waiting for WAL summarization through %X/%X after %ld seconds",
elapsed_seconds,
LSN_FORMAT_ARGS(lsn),
elapsed_seconds),
errdetail("Summarization has reached %X/%X on disk and %X/%X in memory.",
LSN_FORMAT_ARGS(summarized_lsnjava.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
LSN_FORMAT_ARGS(pending_lsn))));
}
/* Create xlogreader. */
xlogreader = XLogReaderAllocate(wal_segment_size, NULL,
XL_ROUTINE(.page_read = &summarizer_read_local_xlog_page,
.segment_open = &wal_segment_open,
.segment_close = &wal_segment_close),
private_data); if (xlogreader == NULL)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory"),
errdetail("Failed while allocating a WAL reading processor.")));
/* *Whenexact=false,we'restartingfromanarbitrarypointintheWAL *andmustsearchforwardforthestartofthenextrecord. * *Whenexact=true,start_lsnshouldbeeithertheLSNwherearecord *begins,ortheLSNofapagewherethepageheaderisimmediately *followedbythestartofanewrecord.XLogBeginReadshouldtolerate *eithercase. * *Weneedtoallowforbothcasesbecausethebehaviorofxlogreader *varies.Whenarecordspanstwoormorexlogpages,theendingLSN *reportedbyxlogreaderwillbethestartingLSNofthefollowing *record,butwhenanxlogpageboundaryfallsbetweentworecords,the *endLSNforthefirstwillbereportedasthefirstbyteofthe *followingpage.Wecan'tknowuntilwereadthatpagehowlargethe *headerwillbe,butwe'llhavetoskipoverittofindthenextrecord.
*/ if (exact)
{ /* *Evenifstart_lsnisthebeginningofapageratherthanthe *beginningofthefirstrecordonthatpage,weshouldstilluseit *asthestartLSNforthesummaryfile.That'sbecausewedetect *missingsummaryfilesbylookingforcaseswheretheendLSNofone *fileislessthanthestartLSNofthenextfile.Whenonlyapage *headerisskipped,nothinghasbeenmissed.
*/
XLogBeginRead(xlogreader, start_lsn);
summary_start_lsn = start_lsn;
} else
{
summary_start_lsn = XLogFindNextRecord(xlogreader, start_lsn); if (XLogRecPtrIsInvalid(summary_start_lsn))
{ /* *Ifwehitend-of-WALwhiletryingtofindthenextvalid *record,wemustbeonahistorictimelinethathasnovalid *recordsthatbeginafterstart_lsnandbeforeendofWAL.
*/ if (private_data->end_of_wal)
{
ereport(DEBUG1,
errmsg_internal("could not read WAL from timeline %u at %X/%X: end of WAL at %X/%X",
tli,
LSN_FORMAT_ARGS(start_lsn),
LSN_FORMAT_ARGS(private_data->read_upto)));
/* *Thetimelineendsatorafterstart_lsn,withoutcontaining *anyrecords.Thus,wemustmakesurethemainloopdoesnot *iterate.Ifstart_lsnistheendofthetimeline,thenwe *won'tactuallyemitanemptysummaryfile,butotherwise, *wemust,tocapturethefactthattheLSNrangeinquestion *containsnointerestingWALrecords.
*/
summary_start_lsn = start_lsn;
summary_end_lsn = private_data->read_upto;
switch_lsn = xlogreader->EndRecPtr;
} else
ereport(ERROR,
(errmsg("could not find a valid record after %X/%X",
LSN_FORMAT_ARGS(start_lsn))));
}
/* We shouldn't go backward. */
Assert(summary_start_lsn >= start_lsn);
}
/* *Mainloop:readxlogrecordsonebyone.
*/ while (1)
{ int block_id; char *errormsg;
XLogRecord *record;
uint8 rmid;
ProcessWalSummarizerInterrupts();
/* We shouldn't go backward. */
Assert(summary_start_lsn <= xlogreader->EndRecPtr);
/* Now read the next record. */
record = XLogReadRecord(xlogreader, &errormsg); if (record == NULL)
{ if (private_data->end_of_wal)
{ /* *Thistimelinemustbehistoricandmustendbeforewewere *abletoreadacompleterecord.
*/
ereport(DEBUG1,
errmsg_internal("could not read WAL from timeline %u at %X/%X: end of WAL at %X/%X",
tli,
LSN_FORMAT_ARGS(xlogreader->EndRecPtr),
LSN_FORMAT_ARGS(private_data->read_upto))); /* Summary ends at end of WAL. */
summary_end_lsn = private_data->read_upto; break;
} if (errormsg)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not read WAL from timeline %u at %X/%X: %s",
tli, LSN_FORMAT_ARGS(xlogreader->EndRecPtr),
errormsg))); else
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not read WAL from timeline %u at %X/%X",
tli, LSN_FORMAT_ARGS(xlogreader->EndRecPtr))));
}
/* We shouldn't go backward. */
Assert(summary_start_lsn <= xlogreader->EndRecPtr);
/* Open the temporary file for writing. */
io.filepos = 0;
io.file = PathNameOpenFile(temp_path, O_WRONLY | O_CREAT | O_TRUNC); if (io.file < 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not create file \"%s\": %m", temp_path)));
/* Write the data. */
WriteBlockRefTable(brtab, WriteWalSummary, &io);
/* Close temporary file and shut down xlogreader. */
FileClose(io.file);
/* Tell the user what we did. */
ereport(DEBUG1,
errmsg_internal("summarized WAL on TLI %u from %X/%X to %X/%X",
tli,
LSN_FORMAT_ARGS(summary_start_lsn),
LSN_FORMAT_ARGS(summary_end_lsn)));
/* Durably rename the new summary into place. */
durable_rename(temp_path, final_path, ERROR);
}
/* If we skipped a non-zero amount of WAL, log a debug message. */ if (summary_end_lsn > summary_start_lsn && fast_forward)
ereport(DEBUG1,
errmsg_internal("skipped summarizing WAL on TLI %u from %X/%X to %X/%X",
tli,
LSN_FORMAT_ARGS(summary_start_lsn),
LSN_FORMAT_ARGS(summary_end_lsn)));
if (info == XLOG_CHECKPOINT_REDO)
{ /* Payload is wal_level at the time record was written. */
memcpy(&record_wal_level, XLogRecGetData(xlogreader), sizeof(int));
} elseif (info == XLOG_CHECKPOINT_SHUTDOWN)
{
CheckPoint rec_ckpt;
/* Extract wal_level at time record was written from payload. */
memcpy(&rec_ckpt, XLogRecGetData(xlogreader), sizeof(CheckPoint));
record_wal_level = rec_ckpt.wal_level;
} elseif (info == XLOG_PARAMETER_CHANGE)
{
xl_parameter_change xlrec;
/* Extract wal_level at time record was written from payload. */
memcpy(&xlrec, XLogRecGetData(xlogreader), sizeof(xl_parameter_change));
record_wal_level = xlrec.wal_level;
} elseif (info == XLOG_END_OF_RECOVERY)
{
xl_end_of_recovery xlrec;
/* Extract wal_level at time record was written from payload. */
memcpy(&xlrec, XLogRecGetData(xlogreader), sizeof(xl_end_of_recovery));
record_wal_level = xlrec.wal_level;
} else
{ /* No special handling required. Return false. */ returnfalse;
}
/* Debugging output. */
ereport(DEBUG1,
errmsg_internal("timeline %u became historic, can read up to %X/%X",
private_data->tli, LSN_FORMAT_ARGS(private_data->read_upto)));
}
/* Go around and try again. */
}
} else
{ /* enough bytes available to satisfy the request */
count = private_data->read_upto - targetPagePtr; break;
}
}
if (!WALRead(state, cur_page, targetPagePtr, count,
private_data->tli, &errinfo))
WALReadRaiseError(&errinfo);
/* Track that we read a page, for sleep time calculation. */
++pages_read_since_last_sleep;
/* number of valid bytes in the buffer */ return count;
}
/* *Sleepforlongenoughthatwebelieveit'slikelythatmoreWALwill *beavailableafterwards.
*/ staticvoid
summarizer_wait_for_wal(void)
{ if (pages_read_since_last_sleep == 0)
{ /* *Nopageswerereadsincethelastsleep,sodoublethesleeptime, *butnotbeyondthemaximumallowablevalue.
*/
sleep_quanta = Min(sleep_quanta * 2, MAX_SLEEP_QUANTA);
} elseif (pages_read_since_last_sleep > 1)
{ /* *Multiplepageswerereadsincethelastsleep,soreducethesleep *time. * *Alargeburstofactivityshouldbeabletoquicklyreduce * A large burst of activity should be able to quickly reduce the *sleeptimetotheminimum,butwedon'twantahandfulofextraWAL *recordstoprovokeastrongreaction.Wechoosetoreducethesleep *timeby1quantumforeachpagereadbeyondthefirst,whichisa *fairlyarbitrarywayoftryingtobereactivewithoutoverreacting.
*/ if (pages_read_since_last_sleep > sleep_quanta - 1)
sleep_quanta = 1; else
sleep_quanta -= pages_read_since_last_sleep;
}
/* Report pending statistics to the cumulative stats system. */
pgstat_report_wal(false);
/* Get all the summaries that currently exist. */
wslist = GetWalSummaries(0, InvalidXLogRecPtr, InvalidXLogRecPtr);
/* Loop until all summaries have been considered for removal. */ while (wslist != NIL)
{
ListCell *lc;
XLogSegNo oldest_segno;
XLogRecPtr oldest_lsn = InvalidXLogRecPtr;
TimeLineID selected_tli;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.