1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.regionserver;
21
22 import java.io.FileNotFoundException;
23 import java.io.IOException;
24 import java.io.InterruptedIOException;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.UUID;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.apache.hadoop.hbase.classification.InterfaceAudience;
34 import org.apache.hadoop.conf.Configuration;
35 import org.apache.hadoop.fs.FSDataInputStream;
36 import org.apache.hadoop.fs.FSDataOutputStream;
37 import org.apache.hadoop.fs.FileStatus;
38 import org.apache.hadoop.fs.FileSystem;
39 import org.apache.hadoop.fs.FileUtil;
40 import org.apache.hadoop.fs.Path;
41 import org.apache.hadoop.fs.permission.FsPermission;
42 import org.apache.hadoop.hbase.HColumnDescriptor;
43 import org.apache.hadoop.hbase.HConstants;
44 import org.apache.hadoop.hbase.HRegionInfo;
45 import org.apache.hadoop.hbase.HTableDescriptor;
46 import org.apache.hadoop.hbase.KeyValue;
47 import org.apache.hadoop.hbase.KeyValueUtil;
48 import org.apache.hadoop.hbase.backup.HFileArchiver;
49 import org.apache.hadoop.hbase.fs.HFileSystem;
50 import org.apache.hadoop.hbase.io.Reference;
51 import org.apache.hadoop.hbase.util.Bytes;
52 import org.apache.hadoop.hbase.util.FSHDFSUtils;
53 import org.apache.hadoop.hbase.util.FSUtils;
54 import org.apache.hadoop.hbase.util.ServerRegionReplicaUtil;
55
56
57
58
59
60 @InterfaceAudience.Private
61 public class HRegionFileSystem {
62 public static final Log LOG = LogFactory.getLog(HRegionFileSystem.class);
63
64
65 public final static String REGION_INFO_FILE = ".regioninfo";
66
67
68 public static final String REGION_MERGES_DIR = ".merges";
69
70
71 public static final String REGION_SPLITS_DIR = ".splits";
72
73
74 private static final String REGION_TEMP_DIR = ".tmp";
75
76 private final HRegionInfo regionInfo;
77
78 private final HRegionInfo regionInfoForFs;
79 private final Configuration conf;
80 private final Path tableDir;
81 private final FileSystem fs;
82
83
84
85
86
87 private final int hdfsClientRetriesNumber;
88 private final int baseSleepBeforeRetries;
89 private static final int DEFAULT_HDFS_CLIENT_RETRIES_NUMBER = 10;
90 private static final int DEFAULT_BASE_SLEEP_BEFORE_RETRIES = 1000;
91
92
93
94
95
96
97
98
99 HRegionFileSystem(final Configuration conf, final FileSystem fs, final Path tableDir,
100 final HRegionInfo regionInfo) {
101 this.fs = fs;
102 this.conf = conf;
103 this.tableDir = tableDir;
104 this.regionInfo = regionInfo;
105 this.regionInfoForFs = ServerRegionReplicaUtil.getRegionInfoForFs(regionInfo);
106 this.hdfsClientRetriesNumber = conf.getInt("hdfs.client.retries.number",
107 DEFAULT_HDFS_CLIENT_RETRIES_NUMBER);
108 this.baseSleepBeforeRetries = conf.getInt("hdfs.client.sleep.before.retries",
109 DEFAULT_BASE_SLEEP_BEFORE_RETRIES);
110 }
111
112
113 public FileSystem getFileSystem() {
114 return this.fs;
115 }
116
117
118 public HRegionInfo getRegionInfo() {
119 return this.regionInfo;
120 }
121
122 public HRegionInfo getRegionInfoForFS() {
123 return this.regionInfoForFs;
124 }
125
126
127 public Path getTableDir() {
128 return this.tableDir;
129 }
130
131
132 public Path getRegionDir() {
133 return new Path(this.tableDir, this.regionInfoForFs.getEncodedName());
134 }
135
136
137
138
139
140 Path getTempDir() {
141 return new Path(getRegionDir(), REGION_TEMP_DIR);
142 }
143
144
145
146
147 void cleanupTempDir() throws IOException {
148 deleteDir(getTempDir());
149 }
150
151
152
153
154
155
156
157
158
159 public Path getStoreDir(final String familyName) {
160 return new Path(this.getRegionDir(), familyName);
161 }
162
163
164
165
166
167
168
169 Path createStoreDir(final String familyName) throws IOException {
170 Path storeDir = getStoreDir(familyName);
171 if(!fs.exists(storeDir) && !createDir(storeDir))
172 throw new IOException("Failed creating "+storeDir);
173 return storeDir;
174 }
175
176
177
178
179
180
181
182 public Collection<StoreFileInfo> getStoreFiles(final byte[] familyName) throws IOException {
183 return getStoreFiles(Bytes.toString(familyName));
184 }
185
186 public Collection<StoreFileInfo> getStoreFiles(final String familyName) throws IOException {
187 return getStoreFiles(familyName, true);
188 }
189
190
191
192
193
194
195
196 public Collection<StoreFileInfo> getStoreFiles(final String familyName, final boolean validate)
197 throws IOException {
198 Path familyDir = getStoreDir(familyName);
199 FileStatus[] files = FSUtils.listStatus(this.fs, familyDir);
200 if (files == null) {
201 LOG.debug("No StoreFiles for: " + familyDir);
202 return null;
203 }
204
205 ArrayList<StoreFileInfo> storeFiles = new ArrayList<StoreFileInfo>(files.length);
206 for (FileStatus status: files) {
207 if (validate && !StoreFileInfo.isValid(status)) {
208 LOG.warn("Invalid StoreFile: " + status.getPath());
209 continue;
210 }
211 StoreFileInfo info = ServerRegionReplicaUtil.getStoreFileInfo(conf, fs, regionInfo,
212 regionInfoForFs, familyName, status.getPath());
213 storeFiles.add(info);
214
215 }
216 return storeFiles;
217 }
218
219
220
221
222
223
224
225
226 Path getStoreFilePath(final String familyName, final String fileName) {
227 Path familyDir = getStoreDir(familyName);
228 return new Path(familyDir, fileName).makeQualified(this.fs);
229 }
230
231
232
233
234
235
236
237
238 StoreFileInfo getStoreFileInfo(final String familyName, final String fileName)
239 throws IOException {
240 Path familyDir = getStoreDir(familyName);
241 return ServerRegionReplicaUtil.getStoreFileInfo(conf, fs, regionInfo,
242 regionInfoForFs, familyName, new Path(familyDir, fileName));
243 }
244
245
246
247
248
249
250
251 public boolean hasReferences(final String familyName) throws IOException {
252 FileStatus[] files = FSUtils.listStatus(fs, getStoreDir(familyName));
253 if (files != null) {
254 for(FileStatus stat: files) {
255 if(stat.isDirectory()) {
256 continue;
257 }
258 if(StoreFileInfo.isReference(stat.getPath())) {
259 return true;
260 }
261 }
262 }
263 return false;
264 }
265
266
267
268
269
270
271
272 public boolean hasReferences(final HTableDescriptor htd) throws IOException {
273 for (HColumnDescriptor family : htd.getFamilies()) {
274 if (hasReferences(family.getNameAsString())) {
275 return true;
276 }
277 }
278 return false;
279 }
280
281
282
283
284
285 public Collection<String> getFamilies() throws IOException {
286 FileStatus[] fds = FSUtils.listStatus(fs, getRegionDir(), new FSUtils.FamilyDirFilter(fs));
287 if (fds == null) return null;
288
289 ArrayList<String> families = new ArrayList<String>(fds.length);
290 for (FileStatus status: fds) {
291 families.add(status.getPath().getName());
292 }
293
294 return families;
295 }
296
297
298
299
300
301
302 public void deleteFamily(final String familyName) throws IOException {
303
304 HFileArchiver.archiveFamily(fs, conf, regionInfoForFs, tableDir, Bytes.toBytes(familyName));
305
306
307 Path familyDir = getStoreDir(familyName);
308 if(fs.exists(familyDir) && !deleteDir(familyDir))
309 throw new IOException("Could not delete family " + familyName
310 + " from FileSystem for region " + regionInfoForFs.getRegionNameAsString() + "("
311 + regionInfoForFs.getEncodedName() + ")");
312 }
313
314
315
316
317
318
319 private static String generateUniqueName(final String suffix) {
320 String name = UUID.randomUUID().toString().replaceAll("-", "");
321 if (suffix != null) name += suffix;
322 return name;
323 }
324
325
326
327
328
329
330
331
332
333
334
335
336 public Path createTempName() {
337 return createTempName(null);
338 }
339
340
341
342
343
344
345
346
347
348
349
350
351
352 public Path createTempName(final String suffix) {
353 return new Path(getTempDir(), generateUniqueName(suffix));
354 }
355
356
357
358
359
360
361
362
363 public Path commitStoreFile(final String familyName, final Path buildPath) throws IOException {
364 return commitStoreFile(familyName, buildPath, -1, false);
365 }
366
367
368
369
370
371
372
373
374
375
376 private Path commitStoreFile(final String familyName, final Path buildPath,
377 final long seqNum, final boolean generateNewName) throws IOException {
378 Path storeDir = getStoreDir(familyName);
379 if(!fs.exists(storeDir) && !createDir(storeDir))
380 throw new IOException("Failed creating " + storeDir);
381
382 String name = buildPath.getName();
383 if (generateNewName) {
384 name = generateUniqueName((seqNum < 0) ? null : "_SeqId_" + seqNum + "_");
385 }
386 Path dstPath = new Path(storeDir, name);
387 if (!fs.exists(buildPath)) {
388 throw new FileNotFoundException(buildPath.toString());
389 }
390 LOG.debug("Committing store file " + buildPath + " as " + dstPath);
391
392 if (!rename(buildPath, dstPath)) {
393 throw new IOException("Failed rename of " + buildPath + " to " + dstPath);
394 }
395 return dstPath;
396 }
397
398
399
400
401
402
403
404 void commitStoreFiles(final Map<byte[], List<StoreFile>> storeFiles) throws IOException {
405 for (Map.Entry<byte[], List<StoreFile>> es: storeFiles.entrySet()) {
406 String familyName = Bytes.toString(es.getKey());
407 for (StoreFile sf: es.getValue()) {
408 commitStoreFile(familyName, sf.getPath());
409 }
410 }
411 }
412
413
414
415
416
417
418
419 public void removeStoreFile(final String familyName, final Path filePath)
420 throws IOException {
421 HFileArchiver.archiveStoreFile(this.conf, this.fs, this.regionInfoForFs,
422 this.tableDir, Bytes.toBytes(familyName), filePath);
423 }
424
425
426
427
428
429
430
431 public void removeStoreFiles(final String familyName, final Collection<StoreFile> storeFiles)
432 throws IOException {
433 HFileArchiver.archiveStoreFiles(this.conf, this.fs, this.regionInfoForFs,
434 this.tableDir, Bytes.toBytes(familyName), storeFiles);
435 }
436
437
438
439
440
441
442
443
444
445
446
447
448 Path bulkLoadStoreFile(final String familyName, Path srcPath, long seqNum)
449 throws IOException {
450
451 FileSystem srcFs = srcPath.getFileSystem(conf);
452 FileSystem desFs = fs instanceof HFileSystem ? ((HFileSystem)fs).getBackingFs() : fs;
453
454
455
456
457 if (!FSHDFSUtils.isSameHdfs(conf, srcFs, desFs)) {
458 LOG.info("Bulk-load file " + srcPath + " is on different filesystem than " +
459 "the destination store. Copying file over to destination filesystem.");
460 Path tmpPath = createTempName();
461 FileUtil.copy(srcFs, srcPath, fs, tmpPath, false, conf);
462 LOG.info("Copied " + srcPath + " to temporary path on destination filesystem: " + tmpPath);
463 srcPath = tmpPath;
464 }
465
466 return commitStoreFile(familyName, srcPath, seqNum, true);
467 }
468
469
470
471
472
473 Path getSplitsDir() {
474 return new Path(getRegionDir(), REGION_SPLITS_DIR);
475 }
476
477 Path getSplitsDir(final HRegionInfo hri) {
478 return new Path(getSplitsDir(), hri.getEncodedName());
479 }
480
481
482
483
484 void cleanupSplitsDir() throws IOException {
485 deleteDir(getSplitsDir());
486 }
487
488
489
490
491
492
493
494 void cleanupAnySplitDetritus() throws IOException {
495 Path splitdir = this.getSplitsDir();
496 if (!fs.exists(splitdir)) return;
497
498
499
500
501
502
503
504 FileStatus[] daughters = FSUtils.listStatus(fs, splitdir, new FSUtils.DirFilter(fs));
505 if (daughters != null) {
506 for (FileStatus daughter: daughters) {
507 Path daughterDir = new Path(getTableDir(), daughter.getPath().getName());
508 if (fs.exists(daughterDir) && !deleteDir(daughterDir)) {
509 throw new IOException("Failed delete of " + daughterDir);
510 }
511 }
512 }
513 cleanupSplitsDir();
514 LOG.info("Cleaned up old failed split transaction detritus: " + splitdir);
515 }
516
517
518
519
520
521
522 void cleanupDaughterRegion(final HRegionInfo regionInfo) throws IOException {
523 Path regionDir = new Path(this.tableDir, regionInfo.getEncodedName());
524 if (this.fs.exists(regionDir) && !deleteDir(regionDir)) {
525 throw new IOException("Failed delete of " + regionDir);
526 }
527 }
528
529
530
531
532
533
534
535
536 Path commitDaughterRegion(final HRegionInfo regionInfo)
537 throws IOException {
538 Path regionDir = new Path(this.tableDir, regionInfo.getEncodedName());
539 Path daughterTmpDir = this.getSplitsDir(regionInfo);
540
541 if (fs.exists(daughterTmpDir)) {
542
543
544 Path regionInfoFile = new Path(daughterTmpDir, REGION_INFO_FILE);
545 byte[] regionInfoContent = getRegionInfoFileContent(regionInfo);
546 writeRegionInfoFileContent(conf, fs, regionInfoFile, regionInfoContent);
547
548
549 if (!rename(daughterTmpDir, regionDir)) {
550 throw new IOException("Unable to rename " + daughterTmpDir + " to " + regionDir);
551 }
552 }
553
554 return regionDir;
555 }
556
557
558
559
560 void createSplitsDir() throws IOException {
561 Path splitdir = getSplitsDir();
562 if (fs.exists(splitdir)) {
563 LOG.info("The " + splitdir + " directory exists. Hence deleting it to recreate it");
564 if (!deleteDir(splitdir)) {
565 throw new IOException("Failed deletion of " + splitdir
566 + " before creating them again.");
567 }
568 }
569
570 if (!createDir(splitdir)) {
571 throw new IOException("Failed create of " + splitdir);
572 }
573 }
574
575
576
577
578
579
580
581
582
583
584
585
586
587 Path splitStoreFile(final HRegionInfo hri, final String familyName, final StoreFile f,
588 final byte[] splitRow, final boolean top, RegionSplitPolicy splitPolicy) throws IOException {
589
590 if (splitPolicy == null || !splitPolicy.skipStoreFileRangeCheck(familyName)) {
591
592
593 try {
594 if (top) {
595
596 KeyValue splitKey = KeyValueUtil.createFirstOnRow(splitRow);
597 byte[] lastKey = f.getLastKey();
598
599 if (lastKey == null) {
600 return null;
601 }
602 if (f.getComparator().compareFlatKey(splitKey.getBuffer(),
603 splitKey.getKeyOffset(), splitKey.getKeyLength(), lastKey, 0, lastKey.length) > 0) {
604 return null;
605 }
606 } else {
607
608 KeyValue splitKey = KeyValueUtil.createLastOnRow(splitRow);
609 byte[] firstKey = f.getFirstKey();
610
611 if (firstKey == null) {
612 return null;
613 }
614 if (f.getComparator().compareFlatKey(splitKey.getBuffer(),
615 splitKey.getKeyOffset(), splitKey.getKeyLength(), firstKey, 0, firstKey.length) < 0) {
616 return null;
617 }
618 }
619 } finally {
620 f.closeReader(true);
621 }
622 }
623
624 Path splitDir = new Path(getSplitsDir(hri), familyName);
625
626 Reference r =
627 top ? Reference.createTopReference(splitRow): Reference.createBottomReference(splitRow);
628
629
630
631
632 String parentRegionName = regionInfoForFs.getEncodedName();
633
634
635 Path p = new Path(splitDir, f.getPath().getName() + "." + parentRegionName);
636 return r.write(fs, p);
637 }
638
639
640
641
642
643 Path getMergesDir() {
644 return new Path(getRegionDir(), REGION_MERGES_DIR);
645 }
646
647 Path getMergesDir(final HRegionInfo hri) {
648 return new Path(getMergesDir(), hri.getEncodedName());
649 }
650
651
652
653
654 void cleanupMergesDir() throws IOException {
655 deleteDir(getMergesDir());
656 }
657
658
659
660
661
662
663 void cleanupMergedRegion(final HRegionInfo mergedRegion) throws IOException {
664 Path regionDir = new Path(this.tableDir, mergedRegion.getEncodedName());
665 if (this.fs.exists(regionDir) && !this.fs.delete(regionDir, true)) {
666 throw new IOException("Failed delete of " + regionDir);
667 }
668 }
669
670
671
672
673
674
675 void createMergesDir() throws IOException {
676 Path mergesdir = getMergesDir();
677 if (fs.exists(mergesdir)) {
678 LOG.info("The " + mergesdir
679 + " directory exists. Hence deleting it to recreate it");
680 if (!fs.delete(mergesdir, true)) {
681 throw new IOException("Failed deletion of " + mergesdir
682 + " before creating them again.");
683 }
684 }
685 if (!fs.mkdirs(mergesdir))
686 throw new IOException("Failed create of " + mergesdir);
687 }
688
689
690
691
692
693
694
695
696
697
698
699 Path mergeStoreFile(final HRegionInfo mergedRegion, final String familyName,
700 final StoreFile f, final Path mergedDir)
701 throws IOException {
702 Path referenceDir = new Path(new Path(mergedDir,
703 mergedRegion.getEncodedName()), familyName);
704
705 Reference r = Reference.createTopReference(regionInfoForFs.getStartKey());
706
707
708
709
710 String mergingRegionName = regionInfoForFs.getEncodedName();
711
712
713 Path p = new Path(referenceDir, f.getPath().getName() + "."
714 + mergingRegionName);
715 return r.write(fs, p);
716 }
717
718
719
720
721
722
723
724 void commitMergedRegion(final HRegionInfo mergedRegionInfo) throws IOException {
725 Path regionDir = new Path(this.tableDir, mergedRegionInfo.getEncodedName());
726 Path mergedRegionTmpDir = this.getMergesDir(mergedRegionInfo);
727
728 if (mergedRegionTmpDir != null && fs.exists(mergedRegionTmpDir)) {
729 if (!fs.rename(mergedRegionTmpDir, regionDir)) {
730 throw new IOException("Unable to rename " + mergedRegionTmpDir + " to "
731 + regionDir);
732 }
733 }
734 }
735
736
737
738
739
740
741
742
743
744 void logFileSystemState(final Log LOG) throws IOException {
745 FSUtils.logFileSystemState(fs, this.getRegionDir(), LOG);
746 }
747
748
749
750
751
752
753 private static byte[] getRegionInfoFileContent(final HRegionInfo hri) throws IOException {
754 return hri.toDelimitedByteArray();
755 }
756
757
758
759
760
761
762
763
764 public static HRegionInfo loadRegionInfoFileContent(final FileSystem fs, final Path regionDir)
765 throws IOException {
766 FSDataInputStream in = fs.open(new Path(regionDir, REGION_INFO_FILE));
767 try {
768 return HRegionInfo.parseFrom(in);
769 } finally {
770 in.close();
771 }
772 }
773
774
775
776
777 private static void writeRegionInfoFileContent(final Configuration conf, final FileSystem fs,
778 final Path regionInfoFile, final byte[] content) throws IOException {
779
780 FsPermission perms = FSUtils.getFilePermissions(fs, conf, HConstants.DATA_FILE_UMASK_KEY);
781
782 FSDataOutputStream out = FSUtils.create(fs, regionInfoFile, perms, null);
783 try {
784 out.write(content);
785 } finally {
786 out.close();
787 }
788 }
789
790
791
792
793
794 void checkRegionInfoOnFilesystem() throws IOException {
795
796
797
798
799
800 byte[] content = getRegionInfoFileContent(regionInfoForFs);
801 try {
802 Path regionInfoFile = new Path(getRegionDir(), REGION_INFO_FILE);
803
804 FileStatus status = fs.getFileStatus(regionInfoFile);
805 if (status != null && status.getLen() == content.length) {
806
807
808 return;
809 }
810
811 LOG.info("Rewriting .regioninfo file at: " + regionInfoFile);
812 if (!fs.delete(regionInfoFile, false)) {
813 throw new IOException("Unable to remove existing " + regionInfoFile);
814 }
815 } catch (FileNotFoundException e) {
816 LOG.warn(REGION_INFO_FILE + " file not found for region: " + regionInfoForFs.getEncodedName() +
817 " on table " + regionInfo.getTable());
818 }
819
820
821 writeRegionInfoOnFilesystem(content, true);
822 }
823
824
825
826
827
828 private void writeRegionInfoOnFilesystem(boolean useTempDir) throws IOException {
829 byte[] content = getRegionInfoFileContent(regionInfoForFs);
830 writeRegionInfoOnFilesystem(content, useTempDir);
831 }
832
833
834
835
836
837
838 private void writeRegionInfoOnFilesystem(final byte[] regionInfoContent,
839 final boolean useTempDir) throws IOException {
840 Path regionInfoFile = new Path(getRegionDir(), REGION_INFO_FILE);
841 if (useTempDir) {
842
843
844
845
846
847
848 Path tmpPath = new Path(getTempDir(), REGION_INFO_FILE);
849
850
851
852
853
854 if (FSUtils.isExists(fs, tmpPath)) {
855 FSUtils.delete(fs, tmpPath, true);
856 }
857
858
859 writeRegionInfoFileContent(conf, fs, tmpPath, regionInfoContent);
860
861
862 if (fs.exists(tmpPath) && !rename(tmpPath, regionInfoFile)) {
863 throw new IOException("Unable to rename " + tmpPath + " to " + regionInfoFile);
864 }
865 } else {
866
867 writeRegionInfoFileContent(conf, fs, regionInfoFile, regionInfoContent);
868 }
869 }
870
871
872
873
874
875
876
877
878
879 public static HRegionFileSystem createRegionOnFileSystem(final Configuration conf,
880 final FileSystem fs, final Path tableDir, final HRegionInfo regionInfo) throws IOException {
881 HRegionFileSystem regionFs = new HRegionFileSystem(conf, fs, tableDir, regionInfo);
882 Path regionDir = regionFs.getRegionDir();
883
884 if (fs.exists(regionDir)) {
885 LOG.warn("Trying to create a region that already exists on disk: " + regionDir);
886 throw new IOException("The specified region already exists on disk: " + regionDir);
887 }
888
889
890 if (!createDirOnFileSystem(fs, conf, regionDir)) {
891 LOG.warn("Unable to create the region directory: " + regionDir);
892 throw new IOException("Unable to create region directory: " + regionDir);
893 }
894
895
896 regionFs.writeRegionInfoOnFilesystem(false);
897 return regionFs;
898 }
899
900
901
902
903
904
905
906
907
908
909 public static HRegionFileSystem openRegionFromFileSystem(final Configuration conf,
910 final FileSystem fs, final Path tableDir, final HRegionInfo regionInfo, boolean readOnly)
911 throws IOException {
912 HRegionFileSystem regionFs = new HRegionFileSystem(conf, fs, tableDir, regionInfo);
913 Path regionDir = regionFs.getRegionDir();
914
915 if (!fs.exists(regionDir)) {
916 LOG.warn("Trying to open a region that do not exists on disk: " + regionDir);
917 throw new IOException("The specified region do not exists on disk: " + regionDir);
918 }
919
920 if (!readOnly) {
921
922 regionFs.cleanupTempDir();
923 regionFs.cleanupSplitsDir();
924 regionFs.cleanupMergesDir();
925
926
927 regionFs.checkRegionInfoOnFilesystem();
928 }
929
930 return regionFs;
931 }
932
933
934
935
936
937
938
939
940
941 public static void deleteRegionFromFileSystem(final Configuration conf,
942 final FileSystem fs, final Path tableDir, final HRegionInfo regionInfo) throws IOException {
943 HRegionFileSystem regionFs = new HRegionFileSystem(conf, fs, tableDir, regionInfo);
944 Path regionDir = regionFs.getRegionDir();
945
946 if (!fs.exists(regionDir)) {
947 LOG.warn("Trying to delete a region that do not exists on disk: " + regionDir);
948 return;
949 }
950
951 if (LOG.isDebugEnabled()) {
952 LOG.debug("DELETING region " + regionDir);
953 }
954
955
956 Path rootDir = FSUtils.getRootDir(conf);
957 HFileArchiver.archiveRegion(fs, rootDir, tableDir, regionDir);
958
959
960 if (!fs.delete(regionDir, true)) {
961 LOG.warn("Failed delete of " + regionDir);
962 }
963 }
964
965
966
967
968
969
970
971
972 boolean createDir(Path dir) throws IOException {
973 int i = 0;
974 IOException lastIOE = null;
975 do {
976 try {
977 return fs.mkdirs(dir);
978 } catch (IOException ioe) {
979 lastIOE = ioe;
980 if (fs.exists(dir)) return true;
981 try {
982 sleepBeforeRetry("Create Directory", i+1);
983 } catch (InterruptedException e) {
984 throw (InterruptedIOException)new InterruptedIOException().initCause(e);
985 }
986 }
987 } while (++i <= hdfsClientRetriesNumber);
988 throw new IOException("Exception in createDir", lastIOE);
989 }
990
991
992
993
994
995
996
997
998 boolean rename(Path srcpath, Path dstPath) throws IOException {
999 IOException lastIOE = null;
1000 int i = 0;
1001 do {
1002 try {
1003 return fs.rename(srcpath, dstPath);
1004 } catch (IOException ioe) {
1005 lastIOE = ioe;
1006 if (!fs.exists(srcpath) && fs.exists(dstPath)) return true;
1007
1008 try {
1009 sleepBeforeRetry("Rename Directory", i+1);
1010 } catch (InterruptedException e) {
1011 throw (InterruptedIOException)new InterruptedIOException().initCause(e);
1012 }
1013 }
1014 } while (++i <= hdfsClientRetriesNumber);
1015
1016 throw new IOException("Exception in rename", lastIOE);
1017 }
1018
1019
1020
1021
1022
1023
1024
1025 boolean deleteDir(Path dir) throws IOException {
1026 IOException lastIOE = null;
1027 int i = 0;
1028 do {
1029 try {
1030 return fs.delete(dir, true);
1031 } catch (IOException ioe) {
1032 lastIOE = ioe;
1033 if (!fs.exists(dir)) return true;
1034
1035 try {
1036 sleepBeforeRetry("Delete Directory", i+1);
1037 } catch (InterruptedException e) {
1038 throw (InterruptedIOException)new InterruptedIOException().initCause(e);
1039 }
1040 }
1041 } while (++i <= hdfsClientRetriesNumber);
1042
1043 throw new IOException("Exception in DeleteDir", lastIOE);
1044 }
1045
1046
1047
1048
1049 private void sleepBeforeRetry(String msg, int sleepMultiplier) throws InterruptedException {
1050 sleepBeforeRetry(msg, sleepMultiplier, baseSleepBeforeRetries, hdfsClientRetriesNumber);
1051 }
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063 private static boolean createDirOnFileSystem(FileSystem fs, Configuration conf, Path dir)
1064 throws IOException {
1065 int i = 0;
1066 IOException lastIOE = null;
1067 int hdfsClientRetriesNumber = conf.getInt("hdfs.client.retries.number",
1068 DEFAULT_HDFS_CLIENT_RETRIES_NUMBER);
1069 int baseSleepBeforeRetries = conf.getInt("hdfs.client.sleep.before.retries",
1070 DEFAULT_BASE_SLEEP_BEFORE_RETRIES);
1071 do {
1072 try {
1073 return fs.mkdirs(dir);
1074 } catch (IOException ioe) {
1075 lastIOE = ioe;
1076 if (fs.exists(dir)) return true;
1077 try {
1078 sleepBeforeRetry("Create Directory", i+1, baseSleepBeforeRetries, hdfsClientRetriesNumber);
1079 } catch (InterruptedException e) {
1080 throw (InterruptedIOException)new InterruptedIOException().initCause(e);
1081 }
1082 }
1083 } while (++i <= hdfsClientRetriesNumber);
1084
1085 throw new IOException("Exception in createDir", lastIOE);
1086 }
1087
1088
1089
1090
1091
1092 private static void sleepBeforeRetry(String msg, int sleepMultiplier, int baseSleepBeforeRetries,
1093 int hdfsClientRetriesNumber) throws InterruptedException {
1094 if (sleepMultiplier > hdfsClientRetriesNumber) {
1095 LOG.debug(msg + ", retries exhausted");
1096 return;
1097 }
1098 LOG.debug(msg + ", sleeping " + baseSleepBeforeRetries + " times " + sleepMultiplier);
1099 Thread.sleep((long)baseSleepBeforeRetries * sleepMultiplier);
1100 }
1101 }