You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-07-30 19:23:04 +03:00
Add pgLsnRangeToWalSegmentList() to convert lsn range to wal segments.
This commit is contained in:
@ -622,6 +622,66 @@ pgLsnToWalSegment(uint32_t timeline, uint64_t lsn, unsigned int walSegmentSize)
|
||||
strNewFmt("%08X%08X%08X", timeline, (unsigned int)(lsn >> 32), (unsigned int)(lsn & 0xFFFFFFFF) / walSegmentSize));
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
StringList *
|
||||
pgLsnRangeToWalSegmentList(
|
||||
unsigned int pgVersion, uint32_t timeline, uint64_t lsnStart, uint64_t lsnStop, unsigned int walSegmentSize)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(UINT, pgVersion);
|
||||
FUNCTION_TEST_PARAM(UINT, timeline);
|
||||
FUNCTION_TEST_PARAM(UINT64, lsnStart);
|
||||
FUNCTION_TEST_PARAM(UINT64, lsnStop);
|
||||
FUNCTION_TEST_PARAM(UINT, walSegmentSize);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(pgVersion != 0);
|
||||
ASSERT(timeline != 0);
|
||||
ASSERT(lsnStart <= lsnStop);
|
||||
ASSERT(walSegmentSize != 0);
|
||||
ASSERT(pgVersion > PG_VERSION_92 || walSegmentSize == PG_WAL_SEGMENT_SIZE_DEFAULT);
|
||||
|
||||
StringList *result = NULL;
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
result = strLstNew();
|
||||
|
||||
// Skip the FF segment when PostgreSQL <= 9.2 (in this case segment size should always be 16MB)
|
||||
bool skipFF = pgVersion <= PG_VERSION_92;
|
||||
|
||||
// Calculate the start and stop segments
|
||||
unsigned int startMajor = (unsigned int)(lsnStart >> 32);
|
||||
unsigned int startMinor = (unsigned int)(lsnStart & 0xFFFFFFFF) / walSegmentSize;
|
||||
|
||||
unsigned int stopMajor = (unsigned int)(lsnStop >> 32);
|
||||
unsigned int stopMinor = (unsigned int)(lsnStop & 0xFFFFFFFF) / walSegmentSize;
|
||||
|
||||
unsigned int minorPerMajor = 0xFFFFFFFF / walSegmentSize;
|
||||
|
||||
// Create list
|
||||
strLstAdd(result, strNewFmt("%08X%08X%08X", timeline, startMajor, startMinor));
|
||||
|
||||
while (!(startMajor == stopMajor && startMinor == stopMinor))
|
||||
{
|
||||
startMinor++;
|
||||
|
||||
if ((skipFF && startMinor == 0xFF) || (!skipFF && startMinor > minorPerMajor))
|
||||
{
|
||||
startMajor++;
|
||||
startMinor = 0;
|
||||
}
|
||||
|
||||
strLstAdd(result, strNewFmt("%08X%08X%08X", timeline, startMajor, startMinor));
|
||||
}
|
||||
|
||||
strLstMove(result, MEM_CONTEXT_OLD());
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
||||
FUNCTION_TEST_RETURN(result);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
const String *
|
||||
pgLsnName(unsigned int pgVersion)
|
||||
|
@ -132,6 +132,10 @@ String *pgLsnToStr(uint64_t lsn);
|
||||
// Convert a timeline and lsn to a wal segment
|
||||
String *pgLsnToWalSegment(uint32_t timeline, uint64_t lsn, unsigned int walSegmentSize);
|
||||
|
||||
// Convert a timeline and lsn range to a list of wal segments
|
||||
StringList *pgLsnRangeToWalSegmentList(
|
||||
unsigned int pgVersion, uint32_t timeline, uint64_t lsnStart, uint64_t lsnStop, unsigned int walSegmentSize);
|
||||
|
||||
// Get name used for lsn in functions (this was changed in PostgreSQL 10 for consistency since lots of names were changing)
|
||||
const String *pgLsnName(unsigned int pgVersion);
|
||||
|
||||
|
@ -102,7 +102,7 @@ testRun(void)
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("pgLsnFromStr(), pgLsnToStr(), and pgLsnToWalSegment()"))
|
||||
if (testBegin("pgLsnFromStr(), pgLsnToStr(), pgLsnToWalSegment(), and pgLsnRangeToWalSegmentList()"))
|
||||
{
|
||||
TEST_RESULT_UINT(pgLsnFromStr(STRDEF("1/1")), 0x0000000100000001, "lsn to string");
|
||||
TEST_RESULT_UINT(pgLsnFromStr(STRDEF("ffffffff/ffffffff")), 0xFFFFFFFFFFFFFFFF, "lsn to string");
|
||||
@ -115,6 +115,42 @@ testRun(void)
|
||||
TEST_RESULT_STR_Z(pgLsnToWalSegment(1, 0xFFFFFFFFAAAAAAAA, 0x1000000), "00000001FFFFFFFF000000AA", "lsn to wal segment");
|
||||
TEST_RESULT_STR_Z(pgLsnToWalSegment(1, 0xFFFFFFFFAAAAAAAA, 0x40000000), "00000001FFFFFFFF00000002", "lsn to wal segment");
|
||||
TEST_RESULT_STR_Z(pgLsnToWalSegment(1, 0xFFFFFFFF40000000, 0x40000000), "00000001FFFFFFFF00000001", "lsn to wal segment");
|
||||
|
||||
TEST_RESULT_STR_Z(
|
||||
strLstJoin(
|
||||
pgLsnRangeToWalSegmentList(
|
||||
PG_VERSION_92, 1, pgLsnFromStr(STRDEF("1/60")), pgLsnFromStr(STRDEF("1/60")), 16 * 1024 * 1024),
|
||||
", "),
|
||||
"000000010000000100000000", "get single");
|
||||
TEST_RESULT_STR_Z(
|
||||
strLstJoin(
|
||||
pgLsnRangeToWalSegmentList(
|
||||
PG_VERSION_92, 2, pgLsnFromStr(STRDEF("1/FD000000")), pgLsnFromStr(STRDEF("2/1000000")), 16 * 1024 * 1024),
|
||||
", "),
|
||||
"0000000200000001000000FD, 0000000200000001000000FE, 000000020000000200000000, 000000020000000200000001",
|
||||
"get range <= 9.2");
|
||||
TEST_RESULT_STR_Z(
|
||||
strLstJoin(
|
||||
pgLsnRangeToWalSegmentList(
|
||||
PG_VERSION_93, 2, pgLsnFromStr(STRDEF("1/FD000000")), pgLsnFromStr(STRDEF("2/60")), 16 * 1024 * 1024),
|
||||
", "),
|
||||
"0000000200000001000000FD, 0000000200000001000000FE, 0000000200000001000000FF, 000000020000000200000000",
|
||||
"get range > 9.2");
|
||||
TEST_RESULT_STR_Z(
|
||||
strLstJoin(
|
||||
pgLsnRangeToWalSegmentList(
|
||||
PG_VERSION_11, 2, pgLsnFromStr(STRDEF("A/800")), pgLsnFromStr(STRDEF("B/C0000000")), 1024 * 1024 * 1024),
|
||||
", "),
|
||||
"000000020000000A00000000, 000000020000000A00000001, 000000020000000A00000002, 000000020000000A00000003"
|
||||
", 000000020000000B00000000, 000000020000000B00000001, 000000020000000B00000002, 000000020000000B00000003",
|
||||
"get range >= 11/1GB");
|
||||
TEST_RESULT_STR_Z(
|
||||
strLstJoin(
|
||||
pgLsnRangeToWalSegmentList(
|
||||
PG_VERSION_11, 3, pgLsnFromStr(STRDEF("7/FFEFFFFF")), pgLsnFromStr(STRDEF("8/001AAAAA")), 1024 * 1024),
|
||||
", "),
|
||||
"000000030000000700000FFE, 000000030000000700000FFF, 000000030000000800000000, 000000030000000800000001",
|
||||
"get range >= 11/1MB");
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
|
Reference in New Issue
Block a user