Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix force GC doesn't work under forceAllowCompaction when disk is full #3205

Merged
merged 6 commits into from
Apr 20, 2022

Conversation

hangc0276
Copy link
Contributor

Motivation

When I set forceAllowCompaction=true and one ledger disk reaches max usage threshold and transfer bookie to readOnly mode, I expire some pulsar topics or delete some topics to free up disk space. I found that ledger compression cannot be triggered when using curl -XPUT http://localhost:8000/api/v1/bookie/gc command.

The root cause is that when one ledger disk reaches max usage threshold, it will suspend minor and major compaction

public void diskFull(File disk) {
if (gcThread.isForceGCAllowWhenNoSpace()) {
gcThread.enableForceGC();
} else {
gcThread.suspendMajorGC();
gcThread.suspendMinorGC();
}
}
@Override
public void allDisksFull(boolean highPriorityWritesAllowed) {
if (gcThread.isForceGCAllowWhenNoSpace()) {
gcThread.enableForceGC();
} else {
gcThread.suspendMajorGC();
gcThread.suspendMinorGC();
}
}

When we use curl -XPUT http://localhost:8000/api/v1/bookie/gc command to trigger compaction, it will be filtered by suspendMajor and suspendMinor flag.

if (((isForceMajorCompactionAllow && force) || (enableMajorCompaction
&& (force || curTime - lastMajorCompactionTime > majorCompactionInterval)))
&& (!suspendMajor)) {
// enter major compaction
LOG.info("Enter major compaction, suspendMajor {}", suspendMajor);
majorCompacting.set(true);
try {
doCompactEntryLogs(majorCompactionThreshold, majorCompactionMaxTimeMillis);
} finally {
lastMajorCompactionTime = System.currentTimeMillis();
// and also move minor compaction time
lastMinorCompactionTime = lastMajorCompactionTime;
gcStats.getMajorCompactionCounter().inc();
majorCompacting.set(false);
}
} else if (((isForceMinorCompactionAllow && force) || (enableMinorCompaction
&& (force || curTime - lastMinorCompactionTime > minorCompactionInterval)))
&& (!suspendMinor)) {
// enter minor compaction
LOG.info("Enter minor compaction, suspendMinor {}", suspendMinor);
minorCompacting.set(true);
try {
doCompactEntryLogs(minorCompactionThreshold, minorCompactionMaxTimeMillis);
} finally {
lastMinorCompactionTime = System.currentTimeMillis();
gcStats.getMinorCompactionCounter().inc();
minorCompacting.set(false);
}
}

It will lead to

  • The bookie won't clean up deleted ledgers
  • Ledger disk can't free up disk usage
  • Bookie can't recover from readOnly state into Writeable state.

And then we can only trigger compaction by the following steps.

  • Increase max disk usage threshold
  • Restart the bookie
  • Use command curl -XPUT http://localhost:8000/api/v1/bookie/gc to trigger compaction

Changes

  1. Don't take the suspendMajor and suspendMinor flag into consideration when setting forceAllowCompaction=true and triggered by force GC.

@hangc0276
Copy link
Contributor Author

rerun failure checks

Copy link
Contributor

@nicoloboschi nicoloboschi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add unit tests?

Copy link
Member

@zymap zymap left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it's expected behavior? We have another configuration isForceGCAllowWhenNoSpace which is used to control the force gc is allowed when no space, maybe you need to set it to true?

@hangc0276
Copy link
Contributor Author

Looks like it's expected behavior? We have another configuration isForceGCAllowWhenNoSpace which is used to control the force gc is allowed when no space, maybe you need to set it to true?

@zymap If we set isForceGCAllowWhenNoSpace to true, it won't suspend minor and major compaction on GC, which will easily lead to ledger disk space exhaustion. After we delete topic or shorten the retention to release disk space, we can't trigger compaction due to compaction need another disk space and the current disk space has been exhausted. So we are not recommend to set isForceGCAllowWhenNoSpace to true

What we need is that the bookie suspend the minor and major compaction when disk usage reaches max threshold, but when we deleted topic or shorten the retention, we trigger GC by rest api, and bookie server neglect the current suspendMajor and suspendMinor flag to trigger compaction.

@zymap
Copy link
Member

zymap commented Apr 14, 2022

But after your change, it will run the major compaction first, which may lead to the dist exhaust as well and cannot compact the entry, right?

@hangc0276
Copy link
Contributor Author

But after your change, it will run the major compaction first, which may lead to the dist exhaust as well and cannot compact the entry, right?

@zymap In order to keep the original logic, I add two flag for REST API to trigger GC, Please take a look, thanks.

@hangc0276
Copy link
Contributor Author

Could we add unit tests?

@nicoloboschi I have added the unit test, please take a look, thanks.

@hangc0276
Copy link
Contributor Author

rerun failure checks

@hangc0276
Copy link
Contributor Author

rerun failure checks

getGCThread().triggerGC(true, true, true).get();
majorCompactionCntAfterGC = getGCThread().getGarbageCollectionStatus().getMajorCompactionCounter();
minorCompactionCntAfterGC = getGCThread().getGarbageCollectionStatus().getMinorCompactionCounter();
if (isForceCompactionAllowWhenDisableCompaction) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the difference between the if and else? Looks like they are asserting the same thing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whether we will enter major or minor compaction is controlled by

((isForceMajorCompactionAllow && force) || (enableMajorCompaction
                    && (force || curTime - lastMajorCompactionTime > majorCompactionInterval)))
                    && (!suspendMajor)

That is:

  1. isForceMajorCompactionAllow && force or (enableMajorCompaction && (force || curTime - lastMajorCompactionTime > majorCompactionInterval)
  2. suspendMajor

We must meet above both conditions.

The if and else is different code path controlled by isForceMajorCompactionAllow && force and (enableMajorCompaction && (force || curTime - lastMajorCompactionTime > majorCompactionInterval)

Ghatage pushed a commit to sijie/bookkeeper that referenced this pull request Jul 12, 2024
apache#3205)

## Motivation
When I set `forceAllowCompaction=true` and one ledger disk reaches max usage threshold and transfer bookie to readOnly mode, I expire some pulsar topics or delete some topics to free up disk space. I found that ledger compression cannot be triggered when using `curl -XPUT http://localhost:8000/api/v1/bookie/gc` command.

The root cause is that when one ledger disk reaches max usage threshold, it will suspend minor and major compaction
https://github.com/apache/bookkeeper/blob/f7579fd13d62ce630ea26638e73f5884da505ec8/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/SingleDirectoryDbLedgerStorage.java#L1041-L1058

When we use `curl -XPUT http://localhost:8000/api/v1/bookie/gc` command to trigger compaction, it will be filtered by `suspendMajor` and `suspendMinor` flag.  

https://github.com/apache/bookkeeper/blob/f7579fd13d62ce630ea26638e73f5884da505ec8/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/GarbageCollectorThread.java#L416-L444

It will lead to 
- The bookie won't clean up deleted ledgers 
- Ledger disk can't free up disk usage
- Bookie can't recover from readOnly state into Writeable state.

And then we can only trigger compaction by the following steps.
- Increase max disk usage threshold
- Restart the bookie
- Use command `curl -XPUT http://localhost:8000/api/v1/bookie/gc` to trigger compaction

### Changes
1. Don't take the `suspendMajor` and `suspendMinor` flag into consideration when setting `forceAllowCompaction=true` and triggered by force GC.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants