You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by st...@apache.org on 2008/11/21 02:27:25 UTC
svn commit: r719444 - in /hadoop/hbase/trunk: CHANGES.txt
src/java/org/apache/hadoop/hbase/regionserver/HLog.java
src/java/org/apache/hadoop/hbase/regionserver/HStore.java
src/java/org/apache/hadoop/hbase/regionserver/LogRoller.java
Author: stack
Date: Thu Nov 20 17:27:24 2008
New Revision: 719444
URL: http://svn.apache.org/viewvc?rev=719444&view=rev
Log:
HBASE-1013 Add debugging around commit log cleanup
Modified:
hadoop/hbase/trunk/CHANGES.txt
hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HLog.java
hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HStore.java
hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/LogRoller.java
Modified: hadoop/hbase/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/CHANGES.txt?rev=719444&r1=719443&r2=719444&view=diff
==============================================================================
--- hadoop/hbase/trunk/CHANGES.txt (original)
+++ hadoop/hbase/trunk/CHANGES.txt Thu Nov 20 17:27:24 2008
@@ -133,6 +133,7 @@
HBASE-675 Report correct server hosting a table split for assignment to
for MR Jobs
HBASE-927 We don't recover if HRS hosting -ROOT-/.META. goes down
+ HBASE-1013 Add debugging around commit log cleanup
NEW FEATURES
HBASE-875 Use MurmurHash instead of JenkinsHash [in bloomfilters]
Modified: hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HLog.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HLog.java?rev=719444&r1=719443&r2=719444&view=diff
==============================================================================
--- hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HLog.java (original)
+++ hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HLog.java Thu Nov 20 17:27:24 2008
@@ -244,35 +244,17 @@
return;
}
synchronized (updateLock) {
- if (this.writer != null) {
- // Close the current writer, get a new one.
- try {
- this.writer.close();
- } catch (IOException e) {
- // Failed close of log file. Means we're losing edits. For now,
- // shut ourselves down to minimize loss. Alternative is to try and
- // keep going. See HBASE-930.
- FailedLogCloseException flce =
- new FailedLogCloseException("#" + this.filenum);
- flce.initCause(e);
- throw e;
- }
- Path p = computeFilename(old_filenum);
- if (LOG.isDebugEnabled()) {
- LOG.debug("Closing current log writer " + FSUtils.getPath(p));
- }
- if (filenum > 0) {
- synchronized (this.sequenceLock) {
- this.outputfiles.put(Long.valueOf(this.logSeqNum - 1), p);
- }
- }
- }
- old_filenum = filenum;
- filenum = System.currentTimeMillis();
- Path newPath = computeFilename(filenum);
+ // Clean up current writer.
+ Path oldFile = cleanupCurrentWriter();
+ // Create a new one.
+ this.old_filenum = this.filenum;
+ this.filenum = System.currentTimeMillis();
+ Path newPath = computeFilename(this.filenum);
this.writer = SequenceFile.createWriter(this.fs, this.conf, newPath,
- HLogKey.class, HLogEdit.class, getCompressionType(this.conf));
- LOG.info("New log writer created at " + FSUtils.getPath(newPath));
+ HLogKey.class, HLogEdit.class, getCompressionType(this.conf));
+ LOG.info((oldFile != null?
+ "Closed " + oldFile + ", entries=" + this.numEntries + ". ": "") +
+ "New log writer: " + FSUtils.getPath(newPath));
// Can we delete any of the old log files?
if (this.outputfiles.size() > 0) {
@@ -286,38 +268,7 @@
}
this.outputfiles.clear();
} else {
- // Get oldest edit/sequence id. If logs are older than this id,
- // then safe to remove.
- Long oldestOutstandingSeqNum =
- Collections.min(this.lastSeqWritten.values());
- // Get the set of all log files whose final ID is older than or
- // equal to the oldest pending region operation
- TreeSet<Long> sequenceNumbers =
- new TreeSet<Long>(this.outputfiles.headMap(
- (Long.valueOf(oldestOutstandingSeqNum.longValue() + 1L))).keySet());
- // Now remove old log files (if any)
- if (LOG.isDebugEnabled()) {
- // Find region associated with oldest key -- helps debugging.
- byte [] oldestRegion = null;
- for (Map.Entry<byte [], Long> e: this.lastSeqWritten.entrySet()) {
- if (e.getValue().longValue() == oldestOutstandingSeqNum.longValue()) {
- oldestRegion = e.getKey();
- break;
- }
- }
- if (LOG.isDebugEnabled() && sequenceNumbers.size() > 0) {
- LOG.debug("Found " + sequenceNumbers.size() +
- " logs to remove " +
- "using oldest outstanding seqnum of " +
- oldestOutstandingSeqNum + " from region " +
- Bytes.toString(oldestRegion));
- }
- }
- if (sequenceNumbers.size() > 0) {
- for (Long seq : sequenceNumbers) {
- deleteLogFile(this.outputfiles.remove(seq), seq);
- }
- }
+ cleanOldLogs();
}
}
this.numEntries = 0;
@@ -328,6 +279,73 @@
}
}
+ /*
+ * Clean up old commit logs.
+ * @throws IOException
+ */
+ private void cleanOldLogs() throws IOException {
+ // Get oldest edit/sequence id. If logs are older than this id,
+ // then safe to remove.
+ Long oldestOutstandingSeqNum =
+ Collections.min(this.lastSeqWritten.values());
+ // Get the set of all log files whose final ID is older than or
+ // equal to the oldest pending region operation
+ TreeSet<Long> sequenceNumbers =
+ new TreeSet<Long>(this.outputfiles.headMap(
+ (Long.valueOf(oldestOutstandingSeqNum.longValue() + 1L))).keySet());
+ // Now remove old log files (if any)
+ if (LOG.isDebugEnabled()) {
+ // Find region associated with oldest key -- helps debugging.
+ byte [] oldestRegion = null;
+ for (Map.Entry<byte [], Long> e: this.lastSeqWritten.entrySet()) {
+ if (e.getValue().longValue() == oldestOutstandingSeqNum.longValue()) {
+ oldestRegion = e.getKey();
+ break;
+ }
+ }
+ LOG.debug("Found " + sequenceNumbers.size() + " logs to remove " +
+ " out of total " + this.outputfiles.size() + "; " +
+ "oldest outstanding seqnum is " + oldestOutstandingSeqNum +
+ " from region " + Bytes.toString(oldestRegion));
+ }
+ if (sequenceNumbers.size() > 0) {
+ for (Long seq : sequenceNumbers) {
+ deleteLogFile(this.outputfiles.remove(seq), seq);
+ }
+ }
+ }
+
+ /*
+ * Cleans up current writer closing and adding to outputfiles.
+ * Presumes we're operating inside an updateLock scope.
+ * @return Path to current writer or null if none.
+ * @throws IOException
+ */
+ private Path cleanupCurrentWriter() throws IOException {
+ Path oldFile = null;
+ if (this.writer != null) {
+ // Close the current writer, get a new one.
+ try {
+ this.writer.close();
+ } catch (IOException e) {
+ // Failed close of log file. Means we're losing edits. For now,
+ // shut ourselves down to minimize loss. Alternative is to try and
+ // keep going. See HBASE-930.
+ FailedLogCloseException flce =
+ new FailedLogCloseException("#" + this.filenum);
+ flce.initCause(e);
+ throw e;
+ }
+ oldFile = computeFilename(old_filenum);
+ if (filenum > 0) {
+ synchronized (this.sequenceLock) {
+ this.outputfiles.put(Long.valueOf(this.logSeqNum - 1), oldFile);
+ }
+ }
+ }
+ return oldFile;
+ }
+
private void deleteLogFile(final Path p, final Long seqno) throws IOException {
LOG.info("removing old log file " + FSUtils.getPath(p) +
" whose highest sequence/edit id is " + seqno);
@@ -626,8 +644,9 @@
}
/**
- * Split up a bunch of log files, that are no longer being written to, into
- * new files, one per region. Delete the old log files when finished.
+ * Split up a bunch of regionserver commit log files that are no longer
+ * being written to, into new files, one per region for region to replay on
+ * startup. Delete the old log files when finished.
*
* @param rootDir qualified root directory of the HBase instance
* @param srcDir Directory of log files to split: e.g.
@@ -636,19 +655,42 @@
* @param conf HBaseConfiguration
* @throws IOException
*/
- public static void splitLog(Path rootDir, Path srcDir, FileSystem fs,
- Configuration conf) throws IOException {
+ public static void splitLog(final Path rootDir, final Path srcDir,
+ final FileSystem fs, final Configuration conf)
+ throws IOException {
if (!fs.exists(srcDir)) {
// Nothing to do
return;
}
- FileStatus logfiles[] = fs.listStatus(srcDir);
+ FileStatus [] logfiles = fs.listStatus(srcDir);
if (logfiles == null || logfiles.length == 0) {
// Nothing to do
return;
}
- LOG.info("splitting " + logfiles.length + " log(s) in " +
+ LOG.info("Splitting " + logfiles.length + " log(s) in " +
srcDir.toString());
+ splitLog(rootDir, logfiles, fs, conf);
+ try {
+ fs.delete(srcDir, true);
+ } catch (IOException e) {
+ e = RemoteExceptionHandler.checkIOException(e);
+ IOException io = new IOException("Cannot delete: " + srcDir);
+ io.initCause(e);
+ throw io;
+ }
+ LOG.info("log file splitting completed for " + srcDir.toString());
+ }
+
+ /*
+ * @param rootDir
+ * @param logfiles
+ * @param fs
+ * @param conf
+ * @throws IOException
+ */
+ private static void splitLog(final Path rootDir, final FileStatus [] logfiles,
+ final FileSystem fs, final Configuration conf)
+ throws IOException {
Map<byte [], SequenceFile.Writer> logWriters =
new TreeMap<byte [], SequenceFile.Writer>(Bytes.BYTES_COMPARATOR);
try {
@@ -743,16 +785,6 @@
w.close();
}
}
-
- try {
- fs.delete(srcDir, true);
- } catch (IOException e) {
- e = RemoteExceptionHandler.checkIOException(e);
- IOException io = new IOException("Cannot delete: " + srcDir);
- io.initCause(e);
- throw io;
- }
- LOG.info("log file splitting completed for " + srcDir.toString());
}
/**
Modified: hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HStore.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HStore.java?rev=719444&r1=719443&r2=719444&view=diff
==============================================================================
--- hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HStore.java (original)
+++ hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HStore.java Thu Nov 20 17:27:24 2008
@@ -908,7 +908,7 @@
this.compactionDir, this.info, family.getName(), -1L, null);
if (LOG.isDebugEnabled()) {
LOG.debug("Started compaction of " + rdrs.size() + " file(s)" +
- (references? "(hasReferences=true)": " ") + " into " +
+ (references? ", hasReferences=true,": " ") + " into " +
FSUtils.getPath(compactedOutputFile.getMapFilePath()));
}
MapFile.Writer writer = compactedOutputFile.getWriter(this.fs,
Modified: hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/LogRoller.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/LogRoller.java?rev=719444&r1=719443&r2=719444&view=diff
==============================================================================
--- hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/LogRoller.java (original)
+++ hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/LogRoller.java Thu Nov 20 17:27:24 2008
@@ -61,8 +61,6 @@
}
rollLock.lock(); // Don't interrupt us. We're working
try {
- LOG.info("Rolling hlog. Number of entries: " +
- server.getLog().getNumEntries());
server.getLog().rollWriter();
} catch (FailedLogCloseException e) {
LOG.fatal("Forcing server shutdown", e);