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