In my opinion, this isn't a real issue. I don't see the real problem behind
this. Turning a disk to full is an eventual behavior.

Any real concern behind this?

- Sijie


On Thu, May 18, 2017 at 9:30 AM, Charan Reddy G <reddychara...@gmail.com>
wrote:

> As part of BOOKKEEPER-643 (
> https://github.com/apache/bookkeeper/commit/694568b0ff0d048c284c8d5db0c945
> 5d30dfa3ce),
> "entryLogFilePreallocationEnabled" logic is introduced in
> EntryLogger.java.
>
> Because of this logic, preallocated entryLogChannel will be used as a newly
> created logchannel even though the ledgerDir, in which it is created, is
> full.
>
> Consider the following example -
>
> 1) We have configured Bookies with two LedgerDirs - 'ledgerDir1',
> 'ledgerDir2'
> 2) lets say current active channel in EntryLogger is 'logChannel1' which is
> created in 'ledgerDir1'
> 3) since 'entryLogFilePreallocationEnabled' is enabled by default, when we
> set 'logChannel1' as the current active channel, we create async task to
> create a new logChannel for future purpose (check
> allocatorExecutor.submit(allocateNewLog task))
> 4) currently both the ledgerDirs are in writable state, so for precreation
> of new logchannel it might pick any ledgerdir
> 5) lets say it chose 'ledgerDir1' again for the creation of new logchannel
> - 'logChannel2'
> 6) now lets assume ledgerDir1 is full, in that case shouldCreateNewEntryLog
> will be set to true
> 7) if a new entry is added to entrylogger, then since
> shouldCreateNewEntryLog is set to true, it will close the current active
> logchannel - 'logChannel1' and add it to logChannelsToFlush list.
> 8) For new logChannel it will get the preallocated log - 'logChannel2' and
> will continue to use it as current active channel, though 'ledgerDir1' is
> not writable anymore.
>
> relevant code snippets in EntryLogger.java
>
>     private LedgerDirsListener getLedgerDirsListener() {
>         return new LedgerDirsListener() {
>             @Override
>             public void diskFull(File disk) {
>                 // If the current entry log disk is full, then create new
> entry
>                 // log.
>                 if (currentDir != null && currentDir.equals(disk)) {
>                     shouldCreateNewEntryLog.set(true);
>                 }
>             }
>
>             @Override
>             public void diskAlmostFull(File disk) {
>                 // If the current entry log disk is almost full, then
> create new entry
>                 // log.
>                 if (currentDir != null && currentDir.equals(disk)) {
>                     shouldCreateNewEntryLog.set(true);
>                 }
>             }
> ....
> }
>
>     synchronized long addEntry(long ledger, ByteBuffer entry, boolean
> rollLog) throws IOException {
> .....
>         boolean createNewLog = shouldCreateNewEntryLog.get();
>         if (createNewLog || reachEntryLogLimit) {
>             if (doRegularFlushes) {
>                 flushCurrentLog();
>             }
>             createNewLog();
>             // Reset the flag
>             if (createNewLog) {
>                 shouldCreateNewEntryLog.set(false);
>             }
>         }
> .....
>     }
>
>
>         synchronized BufferedLogChannel createNewLog() throws IOException {
>             BufferedLogChannel bc;
>             if (!entryLogPreAllocationEnabled || null == preallocation) {
>                 // initialization time to create a new log
>                 bc = allocateNewLog();
>             } else {
>                 // has a preallocated entry log
>                 try {
>                     bc = preallocation.get();
> ...
>                 preallocation = allocatorExecutor.submit(new
> Callable<BufferedLogChannel>() {
>                     @Override
>                     public BufferedLogChannel call() throws IOException {
>                         return allocateNewLog();
>                     }
>                 });
>             }
>             LOG.info("Created new entry logger {}.", bc.getLogId());
>             return bc;
>         }
>
> Thanks,
> Charan
>

Reply via email to