diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java index 51bcc54..014836f 100644 --- hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java +++ hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java @@ -732,7 +732,8 @@ public class MetaTableAccessor { List locations = new ArrayList(1); NavigableMap> familyMap = r.getNoVersionMap(); - locations.add(getRegionLocation(r, regionInfo, 0)); + locations.add(getRegionLocation(r, regionInfo, regionInfo.getReplicaId())); + //locations.add(getRegionLocation(r, regionInfo, 0)); NavigableMap infoMap = familyMap.get(getFamily()); if (infoMap == null) return new RegionLocations(locations); @@ -1246,7 +1247,7 @@ public class MetaTableAccessor { putOfMerged.addImmutable(HConstants.CATALOG_FAMILY, HConstants.MERGEA_QUALIFIER, regionA.toByteArray()); putOfMerged.addImmutable(HConstants.CATALOG_FAMILY, HConstants.MERGEB_QUALIFIER, - regionB.toByteArray()); + regionB.toByteArray()); // Deletes for merging regions Delete deleteA = makeDeleteFromRegionInfo(regionA, time); @@ -1389,7 +1390,11 @@ public class MetaTableAccessor { // region replicas are kept in the primary region's row Put put = new Put(getMetaKeyForRegion(regionInfo), time); - addRegionInfo(put, regionInfo); + HRegionInfo defaultRegionInfo = regionInfo; + if (regionInfo.getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID) { + defaultRegionInfo = new HRegionInfo(regionInfo, HRegionInfo.DEFAULT_REPLICA_ID); + } + addRegionInfo(put, defaultRegionInfo); addLocation(put, sn, openSeqNum, time, regionInfo.getReplicaId()); putToMetaTable(connection, put); LOG.info("Updated row " + regionInfo.getRegionNameAsString() + diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java index bad841f..09692db 100644 --- hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java +++ hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java @@ -876,6 +876,36 @@ public class TestHBaseFsck { } } + /* + * This creates a table with region_replica > 1 and verifies hbck can fix replica region showing + * up as key in meta table. + */ + @Test + public void testHbckReplicaRegionAsKeyInMeta() throws Exception { + TableName table = TableName.valueOf("testHbckReplicaRegionAsKeyInMeta"); + try { + setupTableWithRegionReplica(table, 2); + TEST_UTIL.getHBaseAdmin().flush(table.getName()); + + HTable meta = new HTable(conf, TableName.META_TABLE_NAME); + HRegionInfo hri = new HRegionInfo(table, SPLITS[0], SPLITS[2], false, 1500328224175L, 1); + Put put = MetaTableAccessor.makePutFromRegionInfo(hri); + meta.put(put); + + assertErrors(doFsck(conf, false), + new HBaseFsck.ErrorReporter.ERROR_CODE[] { + HBaseFsck.ErrorReporter.ERROR_CODE.EMPTY_META_CELL }); + + // fix the problem + doFsck(conf, true); + + // run hbck again to make sure we don't see any errors + assertNoErrors(doFsck(conf, false)); + } finally { + cleanupTable(table); + } + } + @Test public void testHbckWithFewerReplica() throws Exception { TableName table =