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