|
21 | 21 | import com.google.common.annotations.VisibleForTesting;
|
22 | 22 | import com.google.common.base.Optional;
|
23 | 23 | import com.google.common.base.Preconditions;
|
| 24 | +import com.google.common.collect.Iterables; |
24 | 25 | import com.google.common.collect.Lists;
|
25 | 26 | import com.google.common.collect.Maps;
|
| 27 | +import com.google.common.collect.Sets; |
26 | 28 | import com.google.common.io.Closeables;
|
27 | 29 | import com.google.protobuf.ByteString;
|
28 | 30 | import com.google.protobuf.Descriptors;
|
@@ -4173,7 +4175,7 @@ private void removeNonExistentColumnFamilyForReplay(
|
4173 | 4175 | if (nonExistentList != null) {
|
4174 | 4176 | for (byte[] family : nonExistentList) {
|
4175 | 4177 | // Perhaps schema was changed between crash and replay
|
4176 |
| - LOG.info("No family for " + Bytes.toString(family) + " omit from reply."); |
| 4178 | + LOG.info("No family for " + Bytes.toString(family) + " omit from replay."); |
4177 | 4179 | familyMap.remove(family);
|
4178 | 4180 | }
|
4179 | 4181 | }
|
@@ -4286,62 +4288,76 @@ protected long replayRecoveredEditsIfAny(Map<byte[], Long> maxSeqIdInStores,
|
4286 | 4288 | minSeqIdForTheRegion = maxSeqIdInStore;
|
4287 | 4289 | }
|
4288 | 4290 | }
|
4289 |
| - long seqid = minSeqIdForTheRegion; |
| 4291 | + long seqId = minSeqIdForTheRegion; |
4290 | 4292 |
|
4291 | 4293 | FileSystem walFS = getWalFileSystem();
|
4292 |
| - Path regionDir = getWALRegionDir(); |
4293 | 4294 | FileSystem rootFS = getFilesystem();
|
4294 |
| - Path defaultRegionDir = getRegionDir(FSUtils.getRootDir(conf), getRegionInfo()); |
| 4295 | + Path regionDir = FSUtils.getRegionDirFromRootDir(FSUtils.getRootDir(conf), getRegionInfo()); |
| 4296 | + Path regionWALDir = getWALRegionDir(); |
| 4297 | + Path wrongRegionWALDir = FSUtils.getWrongWALRegionDir(conf, getRegionInfo().getTable(), |
| 4298 | + getRegionInfo().getEncodedName()); |
4295 | 4299 |
|
| 4300 | + // We made a mistake in HBASE-20734 so we need to do this dirty hack... |
| 4301 | + NavigableSet<Path> filesUnderWrongRegionWALDir = |
| 4302 | + WALSplitter.getSplitEditFilesSorted(walFS, wrongRegionWALDir); |
| 4303 | + seqId = Math.max(seqId, replayRecoveredEditsForPaths(minSeqIdForTheRegion, walFS, |
| 4304 | + filesUnderWrongRegionWALDir, reporter, regionDir)); |
4296 | 4305 | // This is to ensure backwards compatability with HBASE-20723 where recovered edits can appear
|
4297 | 4306 | // under the root dir even if walDir is set.
|
4298 |
| - NavigableSet<Path> filesUnderRootDir = null; |
4299 |
| - if (!regionDir.equals(defaultRegionDir)) { |
4300 |
| - filesUnderRootDir = |
4301 |
| - WALSplitter.getSplitEditFilesSorted(rootFS, defaultRegionDir); |
4302 |
| - seqid = Math.max(seqid, |
4303 |
| - replayRecoveredEditsForPaths(minSeqIdForTheRegion, rootFS, filesUnderRootDir, reporter, |
4304 |
| - defaultRegionDir)); |
4305 |
| - } |
4306 |
| - NavigableSet<Path> files = WALSplitter.getSplitEditFilesSorted(walFS, regionDir); |
4307 |
| - seqid = Math.max(seqid, replayRecoveredEditsForPaths(minSeqIdForTheRegion, walFS, |
4308 |
| - files, reporter, regionDir)); |
4309 |
| - |
4310 |
| - if (seqid > minSeqIdForTheRegion) { |
| 4307 | + NavigableSet<Path> filesUnderRootDir = Sets.newTreeSet(); |
| 4308 | + if (!regionWALDir.equals(regionDir)) { |
| 4309 | + filesUnderRootDir = WALSplitter.getSplitEditFilesSorted(rootFS, regionDir); |
| 4310 | + seqId = Math.max(seqId, replayRecoveredEditsForPaths(minSeqIdForTheRegion, rootFS, |
| 4311 | + filesUnderRootDir, reporter, regionDir)); |
| 4312 | + } |
| 4313 | + NavigableSet<Path> files = WALSplitter.getSplitEditFilesSorted(walFS, regionWALDir); |
| 4314 | + seqId = Math.max(seqId, replayRecoveredEditsForPaths(minSeqIdForTheRegion, walFS, |
| 4315 | + files, reporter, regionWALDir)); |
| 4316 | + if (seqId > minSeqIdForTheRegion) { |
4311 | 4317 | // Then we added some edits to memory. Flush and cleanup split edit files.
|
4312 |
| - internalFlushcache(null, seqid, stores.values(), status, false); |
| 4318 | + internalFlushcache(null, seqId, stores.values(), status, false); |
4313 | 4319 | }
|
4314 |
| - // Now delete the content of recovered edits. We're done w/ them. |
4315 |
| - if (files.size() > 0 && this.conf.getBoolean("hbase.region.archive.recovered.edits", false)) { |
| 4320 | + // Now delete the content of recovered edits. We're done w/ them. |
| 4321 | + if (conf.getBoolean("hbase.region.archive.recovered.edits", false)) { |
4316 | 4322 | // For debugging data loss issues!
|
4317 | 4323 | // If this flag is set, make use of the hfile archiving by making recovered.edits a fake
|
4318 | 4324 | // column family. Have to fake out file type too by casting our recovered.edits as storefiles
|
4319 |
| - String fakeFamilyName = WALSplitter.getRegionDirRecoveredEditsDir(regionDir).getName(); |
4320 |
| - Set<StoreFile> fakeStoreFiles = new HashSet<>(files.size()); |
4321 |
| - for (Path file: files) { |
4322 |
| - fakeStoreFiles.add( |
4323 |
| - new StoreFile(walFS, file, this.conf, null, null)); |
| 4325 | + String fakeFamilyName = WALSplitter.getRegionDirRecoveredEditsDir(regionWALDir).getName(); |
| 4326 | + Set<StoreFile> fakeStoreFiles = new HashSet<>(); |
| 4327 | + for (Path file: Iterables.concat(files, filesUnderWrongRegionWALDir)) { |
| 4328 | + fakeStoreFiles.add(new StoreFile(walFS, file, conf, null, null)); |
| 4329 | + } |
| 4330 | + for (Path file: filesUnderRootDir) { |
| 4331 | + fakeStoreFiles.add(new StoreFile(rootFS, file, conf, null, null)); |
4324 | 4332 | }
|
4325 | 4333 | getRegionWALFileSystem().removeStoreFiles(fakeFamilyName, fakeStoreFiles);
|
4326 | 4334 | } else {
|
4327 |
| - if (filesUnderRootDir != null) { |
4328 |
| - for (Path file : filesUnderRootDir) { |
4329 |
| - if (!rootFS.delete(file, false)) { |
4330 |
| - LOG.error("Failed delete of {} under root directory." + file); |
4331 |
| - } else { |
4332 |
| - LOG.debug("Deleted recovered.edits root directory file=" + file); |
4333 |
| - } |
| 4335 | + for (Path file : filesUnderRootDir) { |
| 4336 | + if (!rootFS.delete(file, false)) { |
| 4337 | + LOG.error("Failed delete of " + file + " from under the root directory"); |
| 4338 | + } else { |
| 4339 | + LOG.debug("Deleted recovered.edits under root directory, file=" + file); |
4334 | 4340 | }
|
4335 | 4341 | }
|
4336 |
| - for (Path file: files) { |
| 4342 | + for (Path file : Iterables.concat(files, filesUnderWrongRegionWALDir)) { |
4337 | 4343 | if (!walFS.delete(file, false)) {
|
4338 | 4344 | LOG.error("Failed delete of " + file);
|
4339 | 4345 | } else {
|
4340 | 4346 | LOG.debug("Deleted recovered.edits file=" + file);
|
4341 | 4347 | }
|
4342 | 4348 | }
|
4343 | 4349 | }
|
4344 |
| - return seqid; |
| 4350 | + |
| 4351 | + // We have replayed all the recovered edits. Let's delete the wrong directories introduced |
| 4352 | + // in HBASE-20734, see HBASE-22617 for more details. |
| 4353 | + FileSystem walFs = getWalFileSystem(); |
| 4354 | + if (walFs.exists(wrongRegionWALDir)) { |
| 4355 | + if (!walFs.delete(wrongRegionWALDir, true)) { |
| 4356 | + LOG.warn("Unable to delete " + wrongRegionWALDir); |
| 4357 | + } |
| 4358 | + } |
| 4359 | + |
| 4360 | + return seqId; |
4345 | 4361 | }
|
4346 | 4362 |
|
4347 | 4363 | private long replayRecoveredEditsForPaths(long minSeqIdForTheRegion, FileSystem fs,
|
@@ -7206,34 +7222,6 @@ public static void addRegionToMETA(final HRegion meta, final HRegion r) throws I
|
7206 | 7222 | meta.put(row, HConstants.CATALOG_FAMILY, cells);
|
7207 | 7223 | }
|
7208 | 7224 |
|
7209 |
| - /** |
7210 |
| - * Computes the Path of the HRegion |
7211 |
| - * |
7212 |
| - * @param tabledir qualified path for table |
7213 |
| - * @param name ENCODED region name |
7214 |
| - * @return Path of HRegion directory |
7215 |
| - * @deprecated For tests only; to be removed. |
7216 |
| - */ |
7217 |
| - @Deprecated |
7218 |
| - public static Path getRegionDir(final Path tabledir, final String name) { |
7219 |
| - return new Path(tabledir, name); |
7220 |
| - } |
7221 |
| - |
7222 |
| - /** |
7223 |
| - * Computes the Path of the HRegion |
7224 |
| - * |
7225 |
| - * @param rootdir qualified path of HBase root directory |
7226 |
| - * @param info HRegionInfo for the region |
7227 |
| - * @return qualified path of region directory |
7228 |
| - * @deprecated For tests only; to be removed. |
7229 |
| - */ |
7230 |
| - @Deprecated |
7231 |
| - @VisibleForTesting |
7232 |
| - public static Path getRegionDir(final Path rootdir, final HRegionInfo info) { |
7233 |
| - return new Path( |
7234 |
| - FSUtils.getTableDir(rootdir, info.getTable()), info.getEncodedName()); |
7235 |
| - } |
7236 |
| - |
7237 | 7225 | /**
|
7238 | 7226 | * Determines if the specified row is within the row range specified by the
|
7239 | 7227 | * specified HRegionInfo
|
|
0 commit comments