[
https://issues.apache.org/jira/browse/BOOKKEEPER-82?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13148239#comment-13148239
]
Sijie Guo commented on BOOKKEEPER-82:
-------------------------------------
ah, this failure is introduced in my code.
I added SyncThread#interrupt during bookie shutdown to interrupt
SyncThread#wait(flush_interval).
{code:title=Bookie.java}
public synchronized void shutdown() throws InterruptedException {
if (!running) { // avoid shutdown twice
return;
}
// Shutdown the ZK client
if(zk != null) zk.close();
this.interrupt();
this.join();
syncThread.running = false;
// sync thread may in wait status
syncThread.interrupt();
syncThread.join();
for(LedgerDescriptor d: ledgers.values()) {
d.close();
}
// Shutdown the EntryLogger which has the GarbageCollector Thread running
entryLogger.shutdown();
// setting running to false here, so watch thread in bookie server know it
only after bookie shut down
running = false;
}
{code}
If a thread is blocked in an I/O operation upon an interruptible channel then
the channel will be closed, the thread's interrupt status will be set, and it
will receive a ClosedByInterruptException.
So if SyncThread is running flushing ledger index / entry loggers, it will
cause ClosedByInterruptException.
Since sync thread may be blocked in #wait or I/O operations, I suggested that
interrupts SyncThread when it doesn't do flushing as below:
{code:title=SyncThread}
// flag to ensure sync thread will not be interrupted during flush
final AtomicBoolean flushing = new AtomicBoolean(false);
public void run() {
while(running) {
synchronized(this) {
try {
wait(flushInterval);
if (!entryLogger.testAndClearSomethingWritten()) {
continue;
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
continue;
}
}
// try to mark flushing flag to make sure it would not be
interrupted
// by shutdown during flushing. otherwise it will receive
// ClosedByInterruptException which may cause index file &
entry logger
// closed and corrupted.
if (!flushing.compareAndSet(false, true)) {
// set flushing flag failed, means flushing is true now
// indicates another thread wants to interrupt sync thread
to exit
break;
}
// ... doing flush ...
}
}
void shutdown() {
running = false;
if (flushing.compareAndSet(false, true)) {
// if setting flushing flag succeed, means syncThread is not
flushing now
// it is safe to interrupt itself now
this.interrupt();
}
this.join();
}
{code}
> support journal rolling
> -----------------------
>
> Key: BOOKKEEPER-82
> URL: https://issues.apache.org/jira/browse/BOOKKEEPER-82
> Project: Bookkeeper
> Issue Type: Improvement
> Components: bookkeeper-server
> Affects Versions: 4.0.0
> Reporter: Sijie Guo
> Assignee: Sijie Guo
> Fix For: 4.0.0
>
> Attachments: BOOKKEEPER-82.patch_v3, BOOKKEEPER-82.patch_v4,
> bookkeeper-82.patch, bookkeeper-82.patch_v2, bookkeeper-server.log
>
>
> now bookkeeper is writing a single journal file, so the journal file has no
> chance to be garbage collected and the disk space keeps growing.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators:
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira