You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-08-01 06:46:52 +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));
|
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 *
|
const String *
|
||||||
pgLsnName(unsigned int pgVersion)
|
pgLsnName(unsigned int pgVersion)
|
||||||
|
@ -132,6 +132,10 @@ String *pgLsnToStr(uint64_t lsn);
|
|||||||
// Convert a timeline and lsn to a wal segment
|
// Convert a timeline and lsn to a wal segment
|
||||||
String *pgLsnToWalSegment(uint32_t timeline, uint64_t lsn, unsigned int walSegmentSize);
|
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)
|
// 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);
|
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("1/1")), 0x0000000100000001, "lsn to string");
|
||||||
TEST_RESULT_UINT(pgLsnFromStr(STRDEF("ffffffff/ffffffff")), 0xFFFFFFFFFFFFFFFF, "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, 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, 0xFFFFFFFFAAAAAAAA, 0x40000000), "00000001FFFFFFFF00000002", "lsn to wal segment");
|
||||||
TEST_RESULT_STR_Z(pgLsnToWalSegment(1, 0xFFFFFFFF40000000, 0x40000000), "00000001FFFFFFFF00000001", "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