You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by fp...@apache.org on 2012/12/10 11:04:19 UTC
svn commit: r1419311 - in /zookeeper/bookkeeper/trunk: CHANGES.txt
bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/EntryLogger.java
bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/CreateNewLogTest.java
Author: fpj
Date: Mon Dec 10 10:04:18 2012
New Revision: 1419311
URL: http://svn.apache.org/viewvc?rev=1419311&view=rev
Log:
BOOKKEEPER-465: CreateNewLog may overwrite lastLogId with smaller value (yixue, fpj via fpj)
Added:
zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/CreateNewLogTest.java
Modified:
zookeeper/bookkeeper/trunk/CHANGES.txt
zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/EntryLogger.java
Modified: zookeeper/bookkeeper/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/CHANGES.txt?rev=1419311&r1=1419310&r2=1419311&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/CHANGES.txt (original)
+++ zookeeper/bookkeeper/trunk/CHANGES.txt Mon Dec 10 10:04:18 2012
@@ -128,6 +128,8 @@ Trunk (unreleased changes)
BOOKKEEPER-474: BookieReadWriteTest#testShutdown doesn't make sense (ivank via fpj)
+ BOOKKEEPER-465: CreateNewLog may overwrite lastLogId with smaller value (yixue, fpj via fpj)
+
hedwig-protocol:
BOOKKEEPER-394: CompositeException message is not useful (Stu Hood via sijie)
Modified: zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/EntryLogger.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/EntryLogger.java?rev=1419311&r1=1419310&r2=1419311&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/EntryLogger.java (original)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/EntryLogger.java Mon Dec 10 10:04:18 2012
@@ -63,6 +63,7 @@ public class EntryLogger {
private AtomicBoolean shouldCreateNewEntryLog = new AtomicBoolean(false);
private long logId;
+
/**
* The maximum size of a entry logger file.
*/
@@ -121,6 +122,7 @@ public class EntryLogger {
// so there can be race conditions when entry logs are rolled over and
// this header buffer is cleared before writing it into the new logChannel.
LOGFILE_HEADER.put("BKLO".getBytes());
+
// Find the largest logId
logId = -1;
for (File dir : ledgerDirsManager.getAllLedgerDirs()) {
@@ -190,28 +192,28 @@ public class EntryLogger {
}
// It would better not to overwrite existing entry log files
- File newLogFile = null;
+ String logFileName = null;
do {
- String logFileName = Long.toHexString(++logId) + ".log";
- File dir = ledgerDirsManager.pickRandomWritableDir();
- newLogFile = new File(dir, logFileName);
- currentDir = dir;
- if (newLogFile.exists()) {
- LOG.warn("Found existed entry log " + newLogFile
- + " when trying to create it as a new log.");
- newLogFile = null;
- continue;
+ logFileName = Long.toHexString(++logId) + ".log";
+ for (File dir : ledgerDirsManager.getAllLedgerDirs()) {
+ File newLogFile = new File(dir, logFileName);
+ if (newLogFile.exists()) {
+ LOG.warn("Found existed entry log " + newLogFile
+ + " when trying to create it as a new log.");
+ logFileName = null;
+ break;
+ }
}
- } while (newLogFile == null);
+ } while (logFileName == null);
+ // Update last log id first
+ currentDir = ledgerDirsManager.pickRandomWritableDir();
+ setLastLogId(currentDir, logId);
+
+ File newLogFile = new File(currentDir, logFileName);
logChannel = new BufferedChannel(new RandomAccessFile(newLogFile, "rw").getChannel(), 64*1024);
logChannel.write((ByteBuffer) LOGFILE_HEADER.clear());
channels.put(logId, logChannel);
-
- List<File> listOfDirs = ledgerDirsManager.getWritableLedgerDirs();
- for (File f : listOfDirs) {
- setLastLogId(f, logId);
- }
}
/**
Added: zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/CreateNewLogTest.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/CreateNewLogTest.java?rev=1419311&view=auto
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/CreateNewLogTest.java (added)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/CreateNewLogTest.java Mon Dec 10 10:04:18 2012
@@ -0,0 +1,102 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.bookkeeper.bookie;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.bookkeeper.conf.ServerConfiguration;
+
+import org.junit.Test;
+import org.junit.After;
+import org.junit.Before;
+import junit.framework.Assert;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CreateNewLogTest {
+ private static final Logger LOG = LoggerFactory
+ .getLogger(CreateNewLogTest.class);
+
+ private String[] ledgerDirs;
+ private int numDirs = 100;
+
+ @Before
+ public void setUp() throws Exception{
+ ledgerDirs = new String[numDirs];
+ for(int i = 0; i < numDirs; i++){
+ File temp = File.createTempFile("bookie", "test");
+ temp.delete();
+ temp.mkdir();
+ File currentTemp = new File(temp.getAbsoluteFile() + "/current");
+ currentTemp.mkdir();
+ ledgerDirs[i] = temp.getPath();
+ }
+ }
+
+ @After
+ public void tearDown() throws Exception{
+ for(int i = 0; i < numDirs; i++){
+ File f = new File(ledgerDirs[i]);
+ deleteRecursive(f);
+ }
+ }
+
+ private void deleteRecursive(File f) {
+ if (f.isDirectory()){
+ for (File c : f.listFiles()){
+ deleteRecursive(c);
+ }
+ }
+
+ f.delete();
+ }
+
+ /**
+ * Checks if new log file id is verified against all directories.
+ *
+ * {@link https://issues.apache.org/jira/browse/BOOKKEEPER-465}
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testCreateNewLog() throws Exception {
+ ServerConfiguration conf = new ServerConfiguration();
+
+ // Creating a new configuration with a number of
+ // ledger directories.
+ conf.setLedgerDirNames(ledgerDirs);
+ LedgerDirsManager ledgerDirsManager = new LedgerDirsManager(conf);
+ EntryLogger el = new EntryLogger(conf, ledgerDirsManager);
+
+ // Extracted from createNewLog()
+ String logFileName = Long.toHexString(1) + ".log";
+ File dir = ledgerDirsManager.pickRandomWritableDir();
+ LOG.info("Picked this directory: " + dir);
+ File newLogFile = new File(dir, logFileName);
+ newLogFile.createNewFile();
+
+ // Calls createNewLog, and with the number of directories we
+ // are using, if it picks one at random it will fail.
+ el.createNewLog();
+ LOG.info("This is the current log id: " + el.getCurrentLogId());
+ Assert.assertTrue("Wrong log id", el.getCurrentLogId() > 1);
+ }
+
+}
\ No newline at end of file