HBASE-4799 Catalog Janitor logic bug causes region leackage

git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1203308 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael Stack 2011-11-17 18:16:30 +00:00
parent 9c6b3b375d
commit c9d5a838d0
2 changed files with 18 additions and 53 deletions

View File

@ -276,24 +276,21 @@ public class MetaEditor {
}
/**
* Deletes daughter reference in offlined split parent.
* Deletes daughters references in offlined split parent.
* @param catalogTracker
* @param parent Parent row we're to remove daughter reference from
* @param qualifier SplitA or SplitB daughter to remove
* @param daughter
* @throws NotAllMetaRegionsOnlineException
* @throws IOException
*/
public static void deleteDaughterReferenceInParent(CatalogTracker catalogTracker,
final HRegionInfo parent, final byte [] qualifier,
final HRegionInfo daughter)
public static void deleteDaughtersReferencesInParent(CatalogTracker catalogTracker,
final HRegionInfo parent)
throws NotAllMetaRegionsOnlineException, IOException {
Delete delete = new Delete(parent.getRegionName());
delete.deleteColumns(HConstants.CATALOG_FAMILY, qualifier);
delete.deleteColumns(HConstants.CATALOG_FAMILY, HConstants.SPLITA_QUALIFIER);
delete.deleteColumns(HConstants.CATALOG_FAMILY, HConstants.SPLITB_QUALIFIER);
deleteMetaTable(catalogTracker, delete);
LOG.info("Deleted daughter reference " + daughter.getRegionNameAsString() +
", qualifier=" + Bytes.toStringBinary(qualifier) + ", from parent " +
parent.getRegionNameAsString());
LOG.info("Deleted daughters references, qualifier=" + Bytes.toStringBinary(HConstants.SPLITA_QUALIFIER) + " and qualifier="
+ Bytes.toStringBinary(HConstants.SPLITA_QUALIFIER) + ", from parent " + parent.getRegionNameAsString());
}
public static HRegionInfo getHRegionInfo(

View File

@ -194,13 +194,18 @@ class CatalogJanitor extends Chore {
throws IOException {
boolean result = false;
// Run checks on each daughter split.
HRegionInfo a_region = getDaughterRegionInfo(rowContent, HConstants.SPLITA_QUALIFIER);
HRegionInfo b_region = getDaughterRegionInfo(rowContent, HConstants.SPLITB_QUALIFIER);
Pair<Boolean, Boolean> a =
checkDaughter(parent, rowContent, HConstants.SPLITA_QUALIFIER);
checkDaughterInFs(parent, a_region, HConstants.SPLITA_QUALIFIER);
Pair<Boolean, Boolean> b =
checkDaughter(parent, rowContent, HConstants.SPLITB_QUALIFIER);
checkDaughterInFs(parent, b_region, HConstants.SPLITB_QUALIFIER);
if (hasNoReferences(a) && hasNoReferences(b)) {
LOG.debug("Deleting region " + parent.getRegionNameAsString() +
" because daughter splits no longer hold references");
// wipe out daughter references from parent region
removeDaughtersFromParent(parent);
// This latter regionOffline should not be necessary but is done for now
// until we let go of regionserver to master heartbeats. See HBASE-3368.
if (this.services.getAssignmentManager() != null) {
@ -227,35 +232,6 @@ class CatalogJanitor extends Chore {
return !p.getFirst() || !p.getSecond();
}
/**
* See if the passed daughter has references in the filesystem to the parent
* and if not, remove the note of daughter region in the parent row: its
* column info:splitA or info:splitB.
* @param parent
* @param rowContent
* @param qualifier
* @return A pair where the first boolean says whether or not the daughter
* region directory exists in the filesystem and then the second boolean says
* whether the daughter has references to the parent.
* @throws IOException
*/
Pair<Boolean, Boolean> checkDaughter(final HRegionInfo parent,
final Result rowContent, final byte [] qualifier)
throws IOException {
HRegionInfo hri = getDaughterRegionInfo(rowContent, qualifier);
Pair<Boolean, Boolean> result =
checkDaughterInFs(parent, rowContent, hri, qualifier);
if (result.getFirst() && !result.getSecond()) {
// Remove daughter from the parent IFF the daughter region exists in FS.
// If there is no daughter region in the filesystem, must be because of
// a failed split. The ServerShutdownHandler will do the fixup. Don't
// do any deletes in here that could intefere with ServerShutdownHandler
// fixup
removeDaughterFromParent(parent, hri, qualifier);
}
return result;
}
/**
* Get daughter HRegionInfo out of parent info:splitA/info:splitB columns.
* @param result
@ -272,27 +248,19 @@ class CatalogJanitor extends Chore {
}
/**
* Remove mention of daughter from parent row.
* parent row.
* @param metaRegionName
* @param srvr
* Remove mention of daughters from parent row.
* @param parent
* @param split
* @param qualifier
* @throws IOException
*/
private void removeDaughterFromParent(final HRegionInfo parent,
final HRegionInfo split, final byte [] qualifier)
private void removeDaughtersFromParent(final HRegionInfo parent)
throws IOException {
MetaEditor.deleteDaughterReferenceInParent(this.server.getCatalogTracker(),
parent, qualifier, split);
MetaEditor.deleteDaughtersReferencesInParent(this.server.getCatalogTracker(), parent);
}
/**
* Checks if a daughter region -- either splitA or splitB -- still holds
* references to parent.
* @param parent Parent region name.
* @param rowContent Keyed content of the parent row in meta region.
* @param split Which column family.
* @param qualifier Which of the daughters to look at, splitA or splitB.
* @return A pair where the first boolean says whether or not the daughter
@ -301,7 +269,7 @@ class CatalogJanitor extends Chore {
* @throws IOException
*/
Pair<Boolean, Boolean> checkDaughterInFs(final HRegionInfo parent,
final Result rowContent, final HRegionInfo split,
final HRegionInfo split,
final byte [] qualifier)
throws IOException {
boolean references = false;