Skip to content

Commit 4435c55

Browse files
committed
Fixes to maintenance: purge ledger headers in the background, properly do SCP history maintenance, improve tests
1 parent f7355a7 commit 4435c55

File tree

2 files changed

+48
-3
lines changed

2 files changed

+48
-3
lines changed

src/history/test/HistoryTests.cpp

+21-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "bucket/test/BucketTestUtils.h"
77
#include "catchup/LedgerApplyManagerImpl.h"
88
#include "catchup/test/CatchupWorkTests.h"
9+
#include "herder/HerderPersistence.h"
910
#include "history/CheckpointBuilder.h"
1011
#include "history/FileTransferInfo.h"
1112
#include "history/HistoryArchiveManager.h"
@@ -15,6 +16,7 @@
1516
#include "historywork/GunzipFileWork.h"
1617
#include "historywork/GzipFileWork.h"
1718
#include "historywork/PutHistoryArchiveStateWork.h"
19+
#include "ledger/LedgerHeaderUtils.h"
1820
#include "ledger/LedgerManager.h"
1921
#include "main/Maintainer.h"
2022
#include "main/PersistentState.h"
@@ -1440,12 +1442,29 @@ TEST_CASE("persist publish queue", "[history][publish][acceptance]")
14401442
// Trim history after publishing whenever possible.
14411443
app1->getMaintainer().performMaintenance(50000);
14421444
}
1445+
1446+
// Verify old history got trimmed
1447+
XDROutputFileStream out(app1->getClock().getIOContext(), true);
1448+
// Ledgers to add to genesis, maintenance keeps at least one checkpoint
1449+
// of data, so last ledger trimmed is (5 * 8 - 1) - 8 = 31
1450+
uint32_t publishedCount = 30;
1451+
auto scp = app1->getHerderPersistence().copySCPHistoryToStream(
1452+
app1->getDatabase().getRawSession(),
1453+
LedgerManager::GENESIS_LEDGER_SEQ, publishedCount, out);
1454+
REQUIRE(scp == 0);
1455+
1456+
CheckpointBuilder cb(*app1);
1457+
auto headers = LedgerHeaderUtils::copyToStream(
1458+
app1->getDatabase().getRawSession(),
1459+
LedgerManager::GENESIS_LEDGER_SEQ, publishedCount, cb);
1460+
REQUIRE(headers == 0);
1461+
14431462
// We should have either an empty publish queue or a
1444-
// ledger sometime after the 5th checkpoint
1463+
// ledger sometime after the 5th checkpoint (ledger 5 * 8 - 1 = 39)
14451464
auto minLedger =
14461465
HistoryManager::getMinLedgerQueuedToPublish(hm1.getConfig());
14471466
LOG_INFO(DEFAULT_LOG, "minLedger {}", minLedger);
1448-
bool okQueue = minLedger == 0 || minLedger >= 35;
1467+
bool okQueue = minLedger == 0 || minLedger >= 39;
14491468
REQUIRE(okQueue);
14501469
}
14511470
}

src/main/Maintainer.cpp

+27-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// of this distribution or at http://www.apache.org/licenses/LICENSE-2.0
44

55
#include "main/Maintainer.h"
6+
#include "herder/HerderPersistence.h"
7+
#include "ledger/LedgerHeaderUtils.h"
68
#include "ledger/LedgerManager.h"
79
#include "main/Application.h"
810
#include "main/Config.h"
@@ -25,6 +27,7 @@ void
2527
Maintainer::start()
2628
{
2729
ZoneScoped;
30+
releaseAssert(threadIsMain());
2831
auto& c = mApp.getConfig();
2932
if (c.AUTOMATIC_MAINTENANCE_PERIOD.count() > 0 &&
3033
c.AUTOMATIC_MAINTENANCE_COUNT > 0)
@@ -51,6 +54,7 @@ Maintainer::start()
5154
void
5255
Maintainer::scheduleMaintenance()
5356
{
57+
releaseAssert(threadIsMain());
5458
mTimer.expires_from_now(mApp.getConfig().AUTOMATIC_MAINTENANCE_PERIOD);
5559
mTimer.async_wait([this]() { tick(); }, VirtualTimer::onFailureNoop);
5660
}
@@ -59,6 +63,7 @@ void
5963
Maintainer::tick()
6064
{
6165
ZoneScoped;
66+
releaseAssert(threadIsMain());
6267
performMaintenance(mApp.getConfig().AUTOMATIC_MAINTENANCE_COUNT);
6368
scheduleMaintenance();
6469
}
@@ -67,6 +72,8 @@ void
6772
Maintainer::performMaintenance(uint32_t count)
6873
{
6974
ZoneScoped;
75+
releaseAssert(threadIsMain());
76+
7077
LOG_INFO(DEFAULT_LOG, "Performing maintenance");
7178
auto logSlow = LogSlowExecution(
7279
"Performing maintenance", LogSlowExecution::Mode::AUTOMATIC_RAII,
@@ -88,6 +95,25 @@ Maintainer::performMaintenance(uint32_t count)
8895

8996
CLOG_INFO(History, "Trimming history <= ledger {}", lmin);
9097

91-
mApp.getLedgerManager().deleteOldEntries(mApp.getDatabase(), lmin, count);
98+
// Cleanup SCP history, always from main
99+
HerderPersistence::deleteOldEntries(mApp.getDatabase().getRawSession(),
100+
lmin, count);
101+
102+
if (mApp.getConfig().parallelLedgerClose())
103+
{
104+
// Cleanup headers from background, to avoid conflicts with closing
105+
// ledgers
106+
mApp.postOnLedgerCloseThread(
107+
[&db = mApp.getDatabase(), lmin, count]() {
108+
auto session = std::make_unique<soci::session>(db.getPool());
109+
LedgerHeaderUtils::deleteOldEntries(*session, lmin, count);
110+
},
111+
"maintenance: deleteOldEntries");
112+
}
113+
else
114+
{
115+
LedgerHeaderUtils::deleteOldEntries(mApp.getDatabase().getRawSession(),
116+
lmin, count);
117+
}
92118
}
93119
}

0 commit comments

Comments
 (0)