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 private 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(f.getCacheConf() != null ? f.getCacheConf().shouldEvictOnClose() : 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(conf, 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
802
803
804
805 try {
806 FileStatus status = fs.getFileStatus(getRegionDir());
807 } catch (FileNotFoundException e) {
808 LOG.warn(getRegionDir() + " doesn't exist for region: " + regionInfoForFs.getEncodedName() +
809 " on table " + regionInfo.getTable());
810 }
811
812 try {
813 Path regionInfoFile = new Path(getRegionDir(), REGION_INFO_FILE);
814 FileStatus status = fs.getFileStatus(regionInfoFile);
815 if (status != null && status.getLen() == content.length) {
816
817
818 return;
819 }
820
821 LOG.info("Rewriting .regioninfo file at: " + regionInfoFile);
822 if (!fs.delete(regionInfoFile, false)) {
823 throw new IOException("Unable to remove existing " + regionInfoFile);
824 }
825 } catch (FileNotFoundException e) {
826 LOG.warn(REGION_INFO_FILE + " file not found for region: " + regionInfoForFs.getEncodedName() +
827 " on table " + regionInfo.getTable());
828 }
829
830
831 writeRegionInfoOnFilesystem(content, true);
832 }
833
834
835
836
837
838 private void writeRegionInfoOnFilesystem(boolean useTempDir) throws IOException {
839 byte[] content = getRegionInfoFileContent(regionInfoForFs);
840 writeRegionInfoOnFilesystem(content, useTempDir);
841 }
842
843
844
845
846
847
848 private void writeRegionInfoOnFilesystem(final byte[] regionInfoContent,
849 final boolean useTempDir) throws IOException {
850 Path regionInfoFile = new Path(getRegionDir(), REGION_INFO_FILE);
851 if (useTempDir) {
852
853
854
855
856
857
858 Path tmpPath = new Path(getTempDir(), REGION_INFO_FILE);
859
860
861
862
863
864 if (FSUtils.isExists(fs, tmpPath)) {
865 FSUtils.delete(fs, tmpPath, true);
866 }
867
868
869 writeRegionInfoFileContent(conf, fs, tmpPath, regionInfoContent);
870
871
872 if (fs.exists(tmpPath) && !rename(tmpPath, regionInfoFile)) {
873 throw new IOException("Unable to rename " + tmpPath + " to " + regionInfoFile);
874 }
875 } else {
876
877 writeRegionInfoFileContent(conf, fs, regionInfoFile, regionInfoContent);
878 }
879 }
880
881
882
883
884
885
886
887
888
889 public static HRegionFileSystem createRegionOnFileSystem(final Configuration conf,
890 final FileSystem fs, final Path tableDir, final HRegionInfo regionInfo) throws IOException {
891 HRegionFileSystem regionFs = new HRegionFileSystem(conf, fs, tableDir, regionInfo);
892 Path regionDir = regionFs.getRegionDir();
893
894 if (fs.exists(regionDir)) {
895 LOG.warn("Trying to create a region that already exists on disk: " + regionDir);
896 throw new IOException("The specified region already exists on disk: " + regionDir);
897 }
898
899
900 if (!createDirOnFileSystem(fs, conf, regionDir)) {
901 LOG.warn("Unable to create the region directory: " + regionDir);
902 throw new IOException("Unable to create region directory: " + regionDir);
903 }
904
905
906
907 if (regionInfo.getReplicaId() == HRegionInfo.DEFAULT_REPLICA_ID) {
908 regionFs.writeRegionInfoOnFilesystem(false);
909 } else {
910 if (LOG.isDebugEnabled())
911 LOG.debug("Skipping creation of .regioninfo file for " + regionInfo);
912 }
913 return regionFs;
914 }
915
916
917
918
919
920
921
922
923
924
925 public static HRegionFileSystem openRegionFromFileSystem(final Configuration conf,
926 final FileSystem fs, final Path tableDir, final HRegionInfo regionInfo, boolean readOnly)
927 throws IOException {
928 HRegionFileSystem regionFs = new HRegionFileSystem(conf, fs, tableDir, regionInfo);
929 Path regionDir = regionFs.getRegionDir();
930
931 if (!fs.exists(regionDir)) {
932 LOG.warn("Trying to open a region that do not exists on disk: " + regionDir);
933 throw new IOException("The specified region do not exists on disk: " + regionDir);
934 }
935
936 if (!readOnly) {
937
938 regionFs.cleanupTempDir();
939 regionFs.cleanupSplitsDir();
940 regionFs.cleanupMergesDir();
941
942
943
944 if (regionInfo.getReplicaId() == HRegionInfo.DEFAULT_REPLICA_ID) {
945 regionFs.checkRegionInfoOnFilesystem();
946 } else {
947 if (LOG.isDebugEnabled()) {
948 LOG.debug("Skipping creation of .regioninfo file for " + regionInfo);
949 }
950 }
951 }
952
953 return regionFs;
954 }
955
956
957
958
959
960
961
962
963
964 public static void deleteRegionFromFileSystem(final Configuration conf,
965 final FileSystem fs, final Path tableDir, final HRegionInfo regionInfo) throws IOException {
966 HRegionFileSystem regionFs = new HRegionFileSystem(conf, fs, tableDir, regionInfo);
967 Path regionDir = regionFs.getRegionDir();
968
969 if (!fs.exists(regionDir)) {
970 LOG.warn("Trying to delete a region that do not exists on disk: " + regionDir);
971 return;
972 }
973
974 if (LOG.isDebugEnabled()) {
975 LOG.debug("DELETING region " + regionDir);
976 }
977
978
979 Path rootDir = FSUtils.getRootDir(conf);
980 HFileArchiver.archiveRegion(fs, rootDir, tableDir, regionDir);
981
982
983 if (!fs.delete(regionDir, true)) {
984 LOG.warn("Failed delete of " + regionDir);
985 }
986 }
987
988
989
990
991
992
993
994
995 boolean createDir(Path dir) throws IOException {
996 int i = 0;
997 IOException lastIOE = null;
998 do {
999 try {
1000 return fs.mkdirs(dir);
1001 } catch (IOException ioe) {
1002 lastIOE = ioe;
1003 if (fs.exists(dir)) return true;
1004 try {
1005 sleepBeforeRetry("Create Directory", i+1);
1006 } catch (InterruptedException e) {
1007 throw (InterruptedIOException)new InterruptedIOException().initCause(e);
1008 }
1009 }
1010 } while (++i <= hdfsClientRetriesNumber);
1011 throw new IOException("Exception in createDir", lastIOE);
1012 }
1013
1014
1015
1016
1017
1018
1019
1020
1021 boolean rename(Path srcpath, Path dstPath) throws IOException {
1022 IOException lastIOE = null;
1023 int i = 0;
1024 do {
1025 try {
1026 return fs.rename(srcpath, dstPath);
1027 } catch (IOException ioe) {
1028 lastIOE = ioe;
1029 if (!fs.exists(srcpath) && fs.exists(dstPath)) return true;
1030
1031 try {
1032 sleepBeforeRetry("Rename Directory", i+1);
1033 } catch (InterruptedException e) {
1034 throw (InterruptedIOException)new InterruptedIOException().initCause(e);
1035 }
1036 }
1037 } while (++i <= hdfsClientRetriesNumber);
1038
1039 throw new IOException("Exception in rename", lastIOE);
1040 }
1041
1042
1043
1044
1045
1046
1047
1048 boolean deleteDir(Path dir) throws IOException {
1049 IOException lastIOE = null;
1050 int i = 0;
1051 do {
1052 try {
1053 return fs.delete(dir, true);
1054 } catch (IOException ioe) {
1055 lastIOE = ioe;
1056 if (!fs.exists(dir)) return true;
1057
1058 try {
1059 sleepBeforeRetry("Delete Directory", i+1);
1060 } catch (InterruptedException e) {
1061 throw (InterruptedIOException)new InterruptedIOException().initCause(e);
1062 }
1063 }
1064 } while (++i <= hdfsClientRetriesNumber);
1065
1066 throw new IOException("Exception in DeleteDir", lastIOE);
1067 }
1068
1069
1070
1071
1072 private void sleepBeforeRetry(String msg, int sleepMultiplier) throws InterruptedException {
1073 sleepBeforeRetry(msg, sleepMultiplier, baseSleepBeforeRetries, hdfsClientRetriesNumber);
1074 }
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086 private static boolean createDirOnFileSystem(FileSystem fs, Configuration conf, Path dir)
1087 throws IOException {
1088 int i = 0;
1089 IOException lastIOE = null;
1090 int hdfsClientRetriesNumber = conf.getInt("hdfs.client.retries.number",
1091 DEFAULT_HDFS_CLIENT_RETRIES_NUMBER);
1092 int baseSleepBeforeRetries = conf.getInt("hdfs.client.sleep.before.retries",
1093 DEFAULT_BASE_SLEEP_BEFORE_RETRIES);
1094 do {
1095 try {
1096 return fs.mkdirs(dir);
1097 } catch (IOException ioe) {
1098 lastIOE = ioe;
1099 if (fs.exists(dir)) return true;
1100 try {
1101 sleepBeforeRetry("Create Directory", i+1, baseSleepBeforeRetries, hdfsClientRetriesNumber);
1102 } catch (InterruptedException e) {
1103 throw (InterruptedIOException)new InterruptedIOException().initCause(e);
1104 }
1105 }
1106 } while (++i <= hdfsClientRetriesNumber);
1107
1108 throw new IOException("Exception in createDir", lastIOE);
1109 }
1110
1111
1112
1113
1114
1115 private static void sleepBeforeRetry(String msg, int sleepMultiplier, int baseSleepBeforeRetries,
1116 int hdfsClientRetriesNumber) throws InterruptedException {
1117 if (sleepMultiplier > hdfsClientRetriesNumber) {
1118 LOG.debug(msg + ", retries exhausted");
1119 return;
1120 }
1121 LOG.debug(msg + ", sleeping " + baseSleepBeforeRetries + " times " + sleepMultiplier);
1122 Thread.sleep((long)baseSleepBeforeRetries * sleepMultiplier);
1123 }
1124 }