HBASE-648 If mapfile index is empty, run repair

git-svn-id: https://svn.apache.org/repos/asf/hadoop/hbase/trunk@661089 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael Stack 2008-05-28 21:17:31 +00:00
parent 6061624031
commit 8d0665881e
3 changed files with 57 additions and 32 deletions

View File

@ -27,6 +27,7 @@ Hbase Change Log
HBASE-642 Splitting log in a hostile environment -- bad hdfs -- we drop
write-ahead-log edits
HBASE-646 EOFException opening HStoreFile info file (spin on HBASE-645and 550)
HBASE-648 If mapfile index is empty, run repair
IMPROVEMENTS
HBASE-559 MR example job to count table rows

View File

@ -263,29 +263,14 @@ public class HStore implements HConstants {
boolean first = true;
for(Map.Entry<Long, HStoreFile> e: this.storefiles.entrySet()) {
MapFile.Reader r = null;
try {
if (first) {
// Use a block cache (if configured) for the first reader only
// so as to control memory usage.
r = e.getValue().getReader(this.fs, this.bloomFilter,
family.isBlockCacheEnabled());
first = false;
} else {
r = e.getValue().getReader(this.fs, this.bloomFilter);
}
} catch (EOFException eofe) {
LOG.warn("Failed open of reader " + e.toString() + "; attempting fix",
eofe);
try {
// Try fixing this file.. if we can.
MapFile.fix(this.fs, e.getValue().getMapFilePath(),
HStoreFile.HbaseMapFile.KEY_CLASS,
HStoreFile.HbaseMapFile.VALUE_CLASS, false, this.conf);
} catch (Exception fixe) {
LOG.warn("Failed fix of " + e.toString() +
"...continuing; Probable DATA LOSS!!!", fixe);
continue;
}
if (first) {
// Use a block cache (if configured) for the first reader only
// so as to control memory usage.
r = e.getValue().getReader(this.fs, this.bloomFilter,
family.isBlockCacheEnabled());
first = false;
} else {
r = e.getValue().getReader(this.fs, this.bloomFilter);
}
this.readers.put(e.getKey(), r);
}
@ -377,7 +362,8 @@ public class HStore implements HConstants {
/*
* Creates a series of HStoreFiles loaded from the given directory.
* There must be a matching 'mapdir' and 'loginfo' pair of files.
* If only one exists, we'll delete it.
* If only one exists, we'll delete it. Does other consistency tests
* checking files are not zero, etc.
*
* @param infodir qualified path for info file directory
* @param mapdir qualified path for map file directory
@ -434,7 +420,6 @@ public class HStore implements HConstants {
LOG.info("HSTORE_LOGINFOFILE " + curfile +
" does not contain a sequence number - ignoring");
}
Path mapfile = curfile.getMapFilePath();
if (!fs.exists(mapfile)) {
fs.delete(curfile.getInfoFilePath(), false);
@ -449,6 +434,23 @@ public class HStore implements HConstants {
"Deleting. Continuing...Probable DATA LOSS!!! See HBASE-646.");
continue;
}
if (isEmptyIndexFile(mapfile)) {
try {
// Try fixing this file.. if we can. Use the hbase version of fix.
// Need to remove the old index file first else fix won't go ahead.
this.fs.delete(new Path(mapfile, MapFile.INDEX_FILE_NAME));
long count = MapFile.fix(this.fs, mapfile, HStoreFile.HbaseMapFile.KEY_CLASS,
HStoreFile.HbaseMapFile.VALUE_CLASS, false, this.conf);
if (LOG.isDebugEnabled()) {
LOG.debug("Fixed index on " + mapfile.toString() + "; had " +
count + " entries");
}
} catch (Exception e) {
LOG.warn("Failed fix of " + mapfile.toString() +
"...continuing; Probable DATA LOSS!!!", e);
continue;
}
}
// TODO: Confirm referent exists.
@ -486,9 +488,32 @@ public class HStore implements HConstants {
throws IOException {
// Mapfiles are made of 'data' and 'index' files. Confirm 'data' is
// non-null if it exists (may not have been written to yet).
Path dataFile = new Path(mapfile, "data");
return this.fs.exists(dataFile) &&
this.fs.getFileStatus(dataFile).getLen() == 0;
return isEmptyFile(new Path(mapfile, MapFile.DATA_FILE_NAME));
}
/*
* @param mapfile
* @return True if the passed mapfile has a zero-length index component (its
* broken).
* @throws IOException
*/
private boolean isEmptyIndexFile(final Path mapfile)
throws IOException {
// Mapfiles are made of 'data' and 'index' files. Confirm 'data' is
// non-null if it exists (may not have been written to yet).
return isEmptyFile(new Path(mapfile, MapFile.INDEX_FILE_NAME));
}
/*
* @param mapfile
* @return True if the passed mapfile has a zero-length index component (its
* broken).
* @throws IOException
*/
private boolean isEmptyFile(final Path f)
throws IOException {
return this.fs.exists(f) &&
this.fs.getFileStatus(f).getLen() == 0;
}
//////////////////////////////////////////////////////////////////////////////

View File

@ -622,8 +622,9 @@ public class HStoreFile implements HConstants {
* Hbase customizations of MapFile.
*/
static class HbaseMapFile extends MapFile {
static final Class KEY_CLASS = HStoreKey.class;
static final Class VALUE_CLASS = ImmutableBytesWritable.class;
static final Class<? extends Writable> KEY_CLASS = HStoreKey.class;
static final Class<? extends Writable> VALUE_CLASS =
ImmutableBytesWritable.class;
/**
* A reader capable of reading and caching blocks of the data file.
@ -696,8 +697,6 @@ public class HStoreFile implements HConstants {
* @param conf
* @param fs
* @param dirName
* @param keyClass
* @param valClass
* @param compression
* @throws IOException
*/