1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.master;
20
21 import static org.apache.hadoop.hbase.util.HFileArchiveTestingUtil.assertArchiveEqualToOriginal;
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertFalse;
24 import static org.junit.Assert.assertTrue;
25 import static org.mockito.Mockito.doReturn;
26 import static org.mockito.Mockito.spy;
27
28 import java.io.IOException;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.SortedMap;
32 import java.util.TreeMap;
33
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36 import org.apache.hadoop.conf.Configuration;
37 import org.apache.hadoop.fs.FSDataOutputStream;
38 import org.apache.hadoop.fs.FileStatus;
39 import org.apache.hadoop.fs.FileSystem;
40 import org.apache.hadoop.fs.Path;
41 import org.apache.hadoop.hbase.ChoreService;
42 import org.apache.hadoop.hbase.CoordinatedStateManager;
43 import org.apache.hadoop.hbase.HBaseTestingUtility;
44 import org.apache.hadoop.hbase.HColumnDescriptor;
45 import org.apache.hadoop.hbase.HConstants;
46 import org.apache.hadoop.hbase.HRegionInfo;
47 import org.apache.hadoop.hbase.HTableDescriptor;
48 import org.apache.hadoop.hbase.MetaMockingUtil;
49 import org.apache.hadoop.hbase.NamespaceDescriptor;
50 import org.apache.hadoop.hbase.NotAllMetaRegionsOnlineException;
51 import org.apache.hadoop.hbase.ProcedureInfo;
52 import org.apache.hadoop.hbase.Server;
53 import org.apache.hadoop.hbase.ServerName;
54 import org.apache.hadoop.hbase.testclassification.SmallTests;
55 import org.apache.hadoop.hbase.TableDescriptors;
56 import org.apache.hadoop.hbase.TableName;
57 import org.apache.hadoop.hbase.client.ClusterConnection;
58 import org.apache.hadoop.hbase.client.HConnectionTestingUtility;
59 import org.apache.hadoop.hbase.client.Result;
60 import org.apache.hadoop.hbase.coordination.BaseCoordinatedStateManager;
61 import org.apache.hadoop.hbase.coordination.SplitLogManagerCoordination;
62 import org.apache.hadoop.hbase.coordination.SplitLogManagerCoordination.SplitLogManagerDetails;
63 import org.apache.hadoop.hbase.executor.ExecutorService;
64 import org.apache.hadoop.hbase.io.Reference;
65 import org.apache.hadoop.hbase.master.CatalogJanitor.SplitParentFirstComparator;
66 import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;
67 import org.apache.hadoop.hbase.master.snapshot.SnapshotManager;
68 import org.apache.hadoop.hbase.procedure.MasterProcedureManagerHost;
69 import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
70 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
71 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos;
72 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
73 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MultiRequest;
74 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MultiResponse;
75 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutateRequest;
76 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutateResponse;
77 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.RegionAction;
78 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.RegionActionResult;
79 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrException;
80 import org.apache.hadoop.hbase.quotas.MasterQuotaManager;
81 import org.apache.hadoop.hbase.regionserver.HStore;
82 import org.apache.hadoop.hbase.security.User;
83 import org.apache.hadoop.hbase.util.Bytes;
84 import org.apache.hadoop.hbase.util.FSUtils;
85 import org.apache.hadoop.hbase.util.HFileArchiveUtil;
86 import org.apache.hadoop.hbase.util.Triple;
87 import org.apache.hadoop.hbase.zookeeper.MetaTableLocator;
88 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
89 import org.junit.Test;
90 import org.junit.experimental.categories.Category;
91 import org.mockito.Mockito;
92 import org.mockito.invocation.InvocationOnMock;
93 import org.mockito.stubbing.Answer;
94
95 import com.google.protobuf.RpcController;
96 import com.google.protobuf.Service;
97 import com.google.protobuf.ServiceException;
98
99 @Category(SmallTests.class)
100 public class TestCatalogJanitor {
101 private static final Log LOG = LogFactory.getLog(TestCatalogJanitor.class);
102
103
104
105
106
107 class MockServer implements Server {
108 private final ClusterConnection connection;
109 private final Configuration c;
110
111 MockServer(final HBaseTestingUtility htu)
112 throws NotAllMetaRegionsOnlineException, IOException, InterruptedException {
113 this.c = htu.getConfiguration();
114 ClientProtos.ClientService.BlockingInterface ri =
115 Mockito.mock(ClientProtos.ClientService.BlockingInterface.class);
116 MutateResponse.Builder builder = MutateResponse.newBuilder();
117 builder.setProcessed(true);
118 try {
119 Mockito.when(ri.mutate(
120 (RpcController)Mockito.any(), (MutateRequest)Mockito.any())).
121 thenReturn(builder.build());
122 } catch (ServiceException se) {
123 throw ProtobufUtil.getRemoteException(se);
124 }
125 try {
126 Mockito.when(ri.multi(
127 (RpcController)Mockito.any(), (MultiRequest)Mockito.any())).
128 thenAnswer(new Answer<MultiResponse>() {
129 @Override
130 public MultiResponse answer(InvocationOnMock invocation) throws Throwable {
131 return buildMultiResponse( (MultiRequest)invocation.getArguments()[1]);
132 }
133 });
134 } catch (ServiceException se) {
135 throw ProtobufUtil.getRemoteException(se);
136 }
137
138
139
140 this.connection =
141 HConnectionTestingUtility.getMockedConnectionAndDecorate(this.c,
142 Mockito.mock(AdminProtos.AdminService.BlockingInterface.class), ri,
143 ServerName.valueOf("example.org,12345,6789"),
144 HRegionInfo.FIRST_META_REGIONINFO);
145
146 FileSystem fs = FileSystem.get(this.c);
147 Path rootdir = FSUtils.getRootDir(this.c);
148 FSUtils.setRootDir(this.c, rootdir);
149 AdminProtos.AdminService.BlockingInterface hri =
150 Mockito.mock(AdminProtos.AdminService.BlockingInterface.class);
151 }
152
153 @Override
154 public ClusterConnection getConnection() {
155 return this.connection;
156 }
157
158 @Override
159 public MetaTableLocator getMetaTableLocator() {
160 return null;
161 }
162
163 @Override
164 public Configuration getConfiguration() {
165 return this.c;
166 }
167
168 @Override
169 public ServerName getServerName() {
170 return ServerName.valueOf("mockserver.example.org", 1234, -1L);
171 }
172
173 @Override
174 public ZooKeeperWatcher getZooKeeper() {
175 return null;
176 }
177
178 @Override
179 public CoordinatedStateManager getCoordinatedStateManager() {
180 BaseCoordinatedStateManager m = Mockito.mock(BaseCoordinatedStateManager.class);
181 SplitLogManagerCoordination c = Mockito.mock(SplitLogManagerCoordination.class);
182 Mockito.when(m.getSplitLogManagerCoordination()).thenReturn(c);
183 SplitLogManagerDetails d = Mockito.mock(SplitLogManagerDetails.class);
184 Mockito.when(c.getDetails()).thenReturn(d);
185 return m;
186 }
187
188 @Override
189 public void abort(String why, Throwable e) {
190
191 }
192
193 @Override
194 public boolean isAborted() {
195 return false;
196 }
197
198 @Override
199 public boolean isStopped() {
200 return false;
201 }
202
203 @Override
204 public void stop(String why) {
205 }
206
207 @Override
208 public ChoreService getChoreService() {
209 return null;
210 }
211 }
212
213
214
215
216 class MockMasterServices implements MasterServices {
217 private final MasterFileSystem mfs;
218 private final AssignmentManager asm;
219 private final ServerManager sm;
220
221 MockMasterServices(final Server server) throws IOException {
222 this.mfs = new MasterFileSystem(server, this);
223 this.asm = Mockito.mock(AssignmentManager.class);
224 this.sm = Mockito.mock(ServerManager.class);
225 }
226
227 @Override
228 public void checkTableModifiable(TableName tableName) throws IOException {
229
230 }
231
232 @Override
233 public long createTable(
234 final HTableDescriptor desc,
235 final byte[][] splitKeys,
236 final long nonceGroup,
237 final long nonce) throws IOException {
238
239 return -1;
240 }
241
242 @Override
243 public long createSystemTable(final HTableDescriptor hTableDescriptor) throws IOException {
244 return -1;
245 }
246
247 @Override
248 public SnapshotManager getSnapshotManager() {
249 return null;
250 }
251
252 @Override
253 public MasterProcedureManagerHost getMasterProcedureManagerHost() {
254 return null;
255 }
256
257 @Override
258 public AssignmentManager getAssignmentManager() {
259 return this.asm;
260 }
261
262 @Override
263 public ExecutorService getExecutorService() {
264 return null;
265 }
266
267 @Override
268 public ChoreService getChoreService() {
269 return null;
270 }
271
272 @Override
273 public MasterFileSystem getMasterFileSystem() {
274 return this.mfs;
275 }
276
277 @Override
278 public MasterCoprocessorHost getMasterCoprocessorHost() {
279 return null;
280 }
281
282 @Override
283 public MasterQuotaManager getMasterQuotaManager() {
284 return null;
285 }
286
287 @Override
288 public ProcedureExecutor<MasterProcedureEnv> getMasterProcedureExecutor() {
289 return null;
290 }
291
292 @Override
293 public ServerManager getServerManager() {
294 return sm;
295 }
296
297 @Override
298 public ZooKeeperWatcher getZooKeeper() {
299 return null;
300 }
301
302 @Override
303 public CoordinatedStateManager getCoordinatedStateManager() {
304 return null;
305 }
306
307 @Override
308 public MetaTableLocator getMetaTableLocator() {
309 return null;
310 }
311
312 @Override
313 public ClusterConnection getConnection() {
314 return null;
315 }
316
317 @Override
318 public Configuration getConfiguration() {
319 return mfs.conf;
320 }
321
322 @Override
323 public ServerName getServerName() {
324 return null;
325 }
326
327 @Override
328 public void abort(String why, Throwable e) {
329
330 }
331
332 @Override
333 public boolean isAborted() {
334 return false;
335 }
336
337 private boolean stopped = false;
338
339 @Override
340 public void stop(String why) {
341 stopped = true;
342 }
343
344 @Override
345 public boolean isStopped() {
346 return stopped;
347 }
348
349 @Override
350 public TableDescriptors getTableDescriptors() {
351 return new TableDescriptors() {
352 @Override
353 public HTableDescriptor remove(TableName tablename) throws IOException {
354
355 return null;
356 }
357
358 @Override
359 public Map<String, HTableDescriptor> getAll() throws IOException {
360
361 return null;
362 }
363
364 @Override
365 public HTableDescriptor get(TableName tablename)
366 throws IOException {
367 return createHTableDescriptor();
368 }
369
370 @Override
371 public Map<String, HTableDescriptor> getByNamespace(String name) throws IOException {
372 return null;
373 }
374
375 @Override
376 public void add(HTableDescriptor htd) throws IOException {
377
378
379 }
380 @Override
381 public void setCacheOn() throws IOException {
382 }
383
384 @Override
385 public void setCacheOff() throws IOException {
386 }
387 };
388 }
389
390 @Override
391 public boolean isServerCrashProcessingEnabled() {
392 return true;
393 }
394
395 @Override
396 public boolean registerService(Service instance) {
397 return false;
398 }
399
400 @Override
401 public void createNamespace(
402 final NamespaceDescriptor descriptor,
403 final long nonceGroup,
404 final long nonce) throws IOException {
405
406 }
407
408 @Override
409 public void createNamespaceSync(
410 final NamespaceDescriptor descriptor,
411 final long nonceGroup,
412 final long nonce,
413 final boolean executeCoprocessor) throws IOException {
414
415 }
416
417 @Override
418 public void modifyNamespace(
419 final NamespaceDescriptor descriptor,
420 final long nonceGroup,
421 final long nonce) throws IOException {
422
423 }
424
425 @Override
426 public void deleteNamespace(
427 final String name,
428 final long nonceGroup,
429 final long nonce) throws IOException {
430
431 }
432
433 @Override
434 public NamespaceDescriptor getNamespaceDescriptor(String name) throws IOException {
435 return null;
436 }
437
438 @Override
439 public List<NamespaceDescriptor> listNamespaceDescriptors() throws IOException {
440 return null;
441 }
442
443 @Override
444 public boolean abortProcedure(final long procId, final boolean mayInterruptIfRunning)
445 throws IOException {
446 return false;
447 }
448
449 @Override
450 public List<ProcedureInfo> listProcedures() throws IOException {
451 return null;
452 }
453
454 @Override
455 public List<HTableDescriptor> listTableDescriptorsByNamespace(String name) throws IOException {
456 return null;
457 }
458
459 @Override
460 public List<TableName> listTableNamesByNamespace(String name) throws IOException {
461 return null;
462 }
463
464 @Override
465 public long deleteTable(
466 final TableName tableName,
467 final long nonceGroup,
468 final long nonce) throws IOException {
469 return -1;
470 }
471
472 public void truncateTable(
473 final TableName tableName,
474 final boolean preserveSplits,
475 final long nonceGroup,
476 final long nonce) throws IOException {
477 }
478
479 @Override
480 public void modifyTable(
481 final TableName tableName,
482 final HTableDescriptor descriptor,
483 final long nonceGroup,
484 final long nonce) throws IOException {
485 }
486
487 @Override
488 public long enableTable(
489 final TableName tableName,
490 final long nonceGroup,
491 final long nonce) throws IOException {
492 return -1;
493 }
494 public LoadBalancer getLoadBalancer() {
495 return null;
496 }
497
498 @Override
499 public long disableTable(
500 TableName tableName,
501 final long nonceGroup,
502 final long nonce) throws IOException {
503 return -1;
504 }
505
506 @Override
507 public void addColumn(
508 final TableName tableName,
509 final HColumnDescriptor columnDescriptor,
510 final long nonceGroup,
511 final long nonce) throws IOException { }
512
513 @Override
514 public void modifyColumn(
515 final TableName tableName,
516 final HColumnDescriptor descriptor,
517 final long nonceGroup,
518 final long nonce) throws IOException { }
519
520 @Override
521 public void deleteColumn(
522 final TableName tableName,
523 final byte[] columnName,
524 final long nonceGroup,
525 final long nonce) throws IOException { }
526
527 @Override
528 public TableLockManager getTableLockManager() {
529 return null;
530 }
531
532 @Override
533 public TableNamespaceManager getTableNamespaceManager() {
534 return null;
535 }
536
537 @Override
538 public void dispatchMergingRegions(HRegionInfo region_a, HRegionInfo region_b,
539 boolean forcible, User user) throws IOException {
540 }
541
542 @Override
543 public boolean isInitialized() {
544
545 return false;
546 }
547
548 @Override
549 public boolean isInMaintenanceMode() {
550 return false;
551 }
552
553 @Override
554 public long getLastMajorCompactionTimestamp(TableName table) throws IOException {
555
556 return 0;
557 }
558
559 @Override
560 public long getLastMajorCompactionTimestampForRegion(byte[] regionName) throws IOException {
561
562 return 0;
563 }
564
565 @Override
566 public String getRegionServerVersion(ServerName sn) {
567 return null;
568 }
569
570 @Override
571 public void checkIfShouldMoveSystemRegionAsync() {
572 }
573 }
574
575 @Test
576 public void testCleanParent() throws IOException, InterruptedException {
577 HBaseTestingUtility htu = new HBaseTestingUtility();
578 setRootDirAndCleanIt(htu, "testCleanParent");
579 Server server = new MockServer(htu);
580 try {
581 MasterServices services = new MockMasterServices(server);
582 CatalogJanitor janitor = new CatalogJanitor(server, services);
583
584 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("table"));
585 htd.addFamily(new HColumnDescriptor("f"));
586 HRegionInfo parent =
587 new HRegionInfo(htd.getTableName(), Bytes.toBytes("aaa"),
588 Bytes.toBytes("eee"));
589 HRegionInfo splita =
590 new HRegionInfo(htd.getTableName(), Bytes.toBytes("aaa"),
591 Bytes.toBytes("ccc"));
592 HRegionInfo splitb =
593 new HRegionInfo(htd.getTableName(), Bytes.toBytes("ccc"),
594 Bytes.toBytes("eee"));
595
596
597 Result r = createResult(parent, splita, splitb);
598
599 Path rootdir = services.getMasterFileSystem().getRootDir();
600 Path tabledir =
601 FSUtils.getTableDir(rootdir, htd.getTableName());
602 Path storedir = HStore.getStoreHomedir(tabledir, splita,
603 htd.getColumnFamilies()[0].getName());
604 Reference ref = Reference.createTopReference(Bytes.toBytes("ccc"));
605 long now = System.currentTimeMillis();
606
607 Path p = new Path(storedir, Long.toString(now) + "." + parent.getEncodedName());
608 FileSystem fs = services.getMasterFileSystem().getFileSystem();
609 Path path = ref.write(fs, p);
610 assertTrue(fs.exists(path));
611 assertFalse(janitor.cleanParent(parent, r));
612
613 assertTrue(fs.delete(p, true));
614 assertTrue(janitor.cleanParent(parent, r));
615 } finally {
616 server.stop("shutdown");
617 }
618 }
619
620
621
622
623
624
625 @Test
626 public void testParentCleanedEvenIfDaughterGoneFirst()
627 throws IOException, InterruptedException {
628 parentWithSpecifiedEndKeyCleanedEvenIfDaughterGoneFirst(
629 "testParentCleanedEvenIfDaughterGoneFirst", Bytes.toBytes("eee"));
630 }
631
632
633
634
635
636
637 @Test
638 public void testLastParentCleanedEvenIfDaughterGoneFirst()
639 throws IOException, InterruptedException {
640 parentWithSpecifiedEndKeyCleanedEvenIfDaughterGoneFirst(
641 "testLastParentCleanedEvenIfDaughterGoneFirst", new byte[0]);
642 }
643
644
645
646
647
648
649
650
651
652 private void parentWithSpecifiedEndKeyCleanedEvenIfDaughterGoneFirst(
653 final String rootDir, final byte[] lastEndKey)
654 throws IOException, InterruptedException {
655 HBaseTestingUtility htu = new HBaseTestingUtility();
656 setRootDirAndCleanIt(htu, rootDir);
657 Server server = new MockServer(htu);
658 MasterServices services = new MockMasterServices(server);
659 CatalogJanitor janitor = new CatalogJanitor(server, services);
660 final HTableDescriptor htd = createHTableDescriptor();
661
662
663
664
665 HRegionInfo parent = new HRegionInfo(htd.getTableName(), Bytes.toBytes("aaa"),
666 lastEndKey);
667
668
669 Thread.sleep(1001);
670
671
672 HRegionInfo splita = new HRegionInfo(htd.getTableName(), Bytes.toBytes("aaa"),
673 Bytes.toBytes("ccc"));
674 Thread.sleep(1001);
675
676 HRegionInfo splitaa = new HRegionInfo(htd.getTableName(), Bytes.toBytes("aaa"),
677 Bytes.toBytes("bbb"));
678 HRegionInfo splitab = new HRegionInfo(htd.getTableName(), Bytes.toBytes("bbb"),
679 Bytes.toBytes("ccc"));
680
681
682 HRegionInfo splitb = new HRegionInfo(htd.getTableName(), Bytes.toBytes("ccc"),
683 lastEndKey);
684 Thread.sleep(1001);
685
686 HRegionInfo splitba = new HRegionInfo(htd.getTableName(), Bytes.toBytes("ccc"),
687 Bytes.toBytes("ddd"));
688 HRegionInfo splitbb = new HRegionInfo(htd.getTableName(), Bytes.toBytes("ddd"),
689 lastEndKey);
690
691
692
693 SortedMap<HRegionInfo, Result> regions =
694 new TreeMap<HRegionInfo, Result>(new CatalogJanitor.SplitParentFirstComparator());
695
696 regions.put(parent, createResult(parent, splita, splitb));
697 regions.put(splitb, createResult(splitb, splitba, splitbb));
698 regions.put(splita, createResult(splita, splitaa, splitab));
699
700 int index = 0;
701 for (Map.Entry<HRegionInfo, Result> e: regions.entrySet()) {
702 if (index == 0) {
703 assertTrue(e.getKey().getEncodedName().equals(parent.getEncodedName()));
704 } else if (index == 1) {
705 assertTrue(e.getKey().getEncodedName().equals(splita.getEncodedName()));
706 } else if (index == 2) {
707 assertTrue(e.getKey().getEncodedName().equals(splitb.getEncodedName()));
708 }
709 index++;
710 }
711
712
713
714 Path splitaRef =
715 createReferences(services, htd, parent, splita, Bytes.toBytes("ccc"), false);
716
717 assertFalse(janitor.cleanParent(parent, regions.get(parent)));
718
719
720
721 assertTrue(janitor.cleanParent(splitb, regions.get(splitb)));
722
723
724
725
726
727 FileSystem fs = FileSystem.get(htu.getConfiguration());
728 assertTrue(fs.delete(splitaRef, true));
729
730 Path splitaaRef =
731 createReferences(services, htd, splita, splitaa, Bytes.toBytes("bbb"), false);
732 Path splitabRef =
733 createReferences(services, htd, splita, splitab, Bytes.toBytes("bbb"), true);
734
735
736 assertFalse(janitor.cleanParent(splita, regions.get(splita)));
737
738
739 assertTrue(fs.delete(splitaaRef, true));
740 assertTrue(fs.delete(splitabRef, true));
741 assertTrue(janitor.cleanParent(splita, regions.get(splita)));
742
743
744 assertTrue(janitor.cleanParent(parent, regions.get(parent)));
745
746 services.stop("test finished");
747 janitor.cancel(true);
748 }
749
750
751
752
753
754
755 @Test
756 public void testScanDoesNotCleanRegionsWithExistingParents() throws Exception {
757 HBaseTestingUtility htu = new HBaseTestingUtility();
758 setRootDirAndCleanIt(htu, "testScanDoesNotCleanRegionsWithExistingParents");
759 Server server = new MockServer(htu);
760 MasterServices services = new MockMasterServices(server);
761
762 final HTableDescriptor htd = createHTableDescriptor();
763
764
765
766
767 HRegionInfo parent = new HRegionInfo(htd.getTableName(), Bytes.toBytes("aaa"),
768 new byte[0], true);
769
770
771 Thread.sleep(1001);
772
773
774 HRegionInfo splita = new HRegionInfo(htd.getTableName(), Bytes.toBytes("aaa"),
775 Bytes.toBytes("ccc"), true);
776 Thread.sleep(1001);
777
778 HRegionInfo splitaa = new HRegionInfo(htd.getTableName(), Bytes.toBytes("aaa"),
779 Bytes.toBytes("bbb"), false);
780 HRegionInfo splitab = new HRegionInfo(htd.getTableName(), Bytes.toBytes("bbb"),
781 Bytes.toBytes("ccc"), false);
782
783
784 HRegionInfo splitb = new HRegionInfo(htd.getTableName(), Bytes.toBytes("ccc"),
785 new byte[0]);
786 Thread.sleep(1001);
787
788 final Map<HRegionInfo, Result> splitParents =
789 new TreeMap<HRegionInfo, Result>(new SplitParentFirstComparator());
790 splitParents.put(parent, createResult(parent, splita, splitb));
791 splita.setOffline(true);
792 splitParents.put(splita, createResult(splita, splitaa,splitab));
793
794 final Map<HRegionInfo, Result> mergedRegions = new TreeMap<HRegionInfo, Result>();
795 CatalogJanitor janitor = spy(new CatalogJanitor(server, services));
796 doReturn(new Triple<Integer, Map<HRegionInfo, Result>, Map<HRegionInfo, Result>>(
797 10, mergedRegions, splitParents)).when(janitor)
798 .getMergedRegionsAndSplitParents();
799
800
801 Path splitaRef =
802 createReferences(services, htd, parent, splita, Bytes.toBytes("ccc"), false);
803
804
805 assertEquals(0, janitor.scan());
806
807
808 FileSystem fs = FileSystem.get(htu.getConfiguration());
809 assertTrue(fs.delete(splitaRef, true));
810
811
812 assertEquals(2, janitor.scan());
813
814 services.stop("test finished");
815 janitor.cancel(true);
816 }
817
818
819
820
821
822 @Test
823 public void testSplitParentFirstComparator() {
824 SplitParentFirstComparator comp = new SplitParentFirstComparator();
825 final HTableDescriptor htd = createHTableDescriptor();
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846 HRegionInfo rootRegion = new HRegionInfo(htd.getTableName(),
847 HConstants.EMPTY_START_ROW,
848 HConstants.EMPTY_END_ROW, true);
849 HRegionInfo firstRegion = new HRegionInfo(htd.getTableName(),
850 HConstants.EMPTY_START_ROW,
851 Bytes.toBytes("bbb"), true);
852 HRegionInfo lastRegion = new HRegionInfo(htd.getTableName(),
853 Bytes.toBytes("bbb"),
854 HConstants.EMPTY_END_ROW, true);
855
856 assertTrue(comp.compare(rootRegion, rootRegion) == 0);
857 assertTrue(comp.compare(firstRegion, firstRegion) == 0);
858 assertTrue(comp.compare(lastRegion, lastRegion) == 0);
859 assertTrue(comp.compare(rootRegion, firstRegion) < 0);
860 assertTrue(comp.compare(rootRegion, lastRegion) < 0);
861 assertTrue(comp.compare(firstRegion, lastRegion) < 0);
862
863
864 HRegionInfo firstRegiona = new HRegionInfo(htd.getTableName(),
865 HConstants.EMPTY_START_ROW,
866 Bytes.toBytes("aaa"), true);
867 HRegionInfo firstRegionb = new HRegionInfo(htd.getTableName(),
868 Bytes.toBytes("aaa"),
869 Bytes.toBytes("bbb"), true);
870
871 HRegionInfo lastRegiona = new HRegionInfo(htd.getTableName(),
872 Bytes.toBytes("bbb"),
873 Bytes.toBytes("ddd"), true);
874 HRegionInfo lastRegionb = new HRegionInfo(htd.getTableName(),
875 Bytes.toBytes("ddd"),
876 HConstants.EMPTY_END_ROW, true);
877
878 assertTrue(comp.compare(firstRegiona, firstRegiona) == 0);
879 assertTrue(comp.compare(firstRegionb, firstRegionb) == 0);
880 assertTrue(comp.compare(rootRegion, firstRegiona) < 0);
881 assertTrue(comp.compare(rootRegion, firstRegionb) < 0);
882 assertTrue(comp.compare(firstRegion, firstRegiona) < 0);
883 assertTrue(comp.compare(firstRegion, firstRegionb) < 0);
884 assertTrue(comp.compare(firstRegiona, firstRegionb) < 0);
885
886 assertTrue(comp.compare(lastRegiona, lastRegiona) == 0);
887 assertTrue(comp.compare(lastRegionb, lastRegionb) == 0);
888 assertTrue(comp.compare(rootRegion, lastRegiona) < 0);
889 assertTrue(comp.compare(rootRegion, lastRegionb) < 0);
890 assertTrue(comp.compare(lastRegion, lastRegiona) < 0);
891 assertTrue(comp.compare(lastRegion, lastRegionb) < 0);
892 assertTrue(comp.compare(lastRegiona, lastRegionb) < 0);
893
894 assertTrue(comp.compare(firstRegiona, lastRegiona) < 0);
895 assertTrue(comp.compare(firstRegiona, lastRegionb) < 0);
896 assertTrue(comp.compare(firstRegionb, lastRegiona) < 0);
897 assertTrue(comp.compare(firstRegionb, lastRegionb) < 0);
898
899 HRegionInfo lastRegionaa = new HRegionInfo(htd.getTableName(),
900 Bytes.toBytes("bbb"),
901 Bytes.toBytes("ccc"), false);
902 HRegionInfo lastRegionab = new HRegionInfo(htd.getTableName(),
903 Bytes.toBytes("ccc"),
904 Bytes.toBytes("ddd"), false);
905
906 assertTrue(comp.compare(lastRegiona, lastRegionaa) < 0);
907 assertTrue(comp.compare(lastRegiona, lastRegionab) < 0);
908 assertTrue(comp.compare(lastRegionaa, lastRegionab) < 0);
909
910 }
911
912 @Test
913 public void testArchiveOldRegion() throws Exception {
914 String table = "table";
915 HBaseTestingUtility htu = new HBaseTestingUtility();
916 setRootDirAndCleanIt(htu, "testCleanParent");
917 Server server = new MockServer(htu);
918 MasterServices services = new MockMasterServices(server);
919
920
921 CatalogJanitor janitor = new CatalogJanitor(server, services);
922
923
924 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(table));
925 htd.addFamily(new HColumnDescriptor("f"));
926 HRegionInfo parent = new HRegionInfo(htd.getTableName(),
927 Bytes.toBytes("aaa"), Bytes.toBytes("eee"));
928 HRegionInfo splita = new HRegionInfo(htd.getTableName(),
929 Bytes.toBytes("aaa"), Bytes.toBytes("ccc"));
930 HRegionInfo splitb = new HRegionInfo(htd.getTableName(),
931 Bytes.toBytes("ccc"),
932 Bytes.toBytes("eee"));
933
934
935
936 Result parentMetaRow = createResult(parent, splita, splitb);
937 FileSystem fs = FileSystem.get(htu.getConfiguration());
938 Path rootdir = services.getMasterFileSystem().getRootDir();
939
940
941
942 FSUtils.setRootDir(fs.getConf(), rootdir);
943 Path tabledir = FSUtils.getTableDir(rootdir, htd.getTableName());
944 Path storedir = HStore.getStoreHomedir(tabledir, parent, htd.getColumnFamilies()[0].getName());
945 Path storeArchive = HFileArchiveUtil.getStoreArchivePath(services.getConfiguration(), parent,
946 tabledir, htd.getColumnFamilies()[0].getName());
947 LOG.debug("Table dir:" + tabledir);
948 LOG.debug("Store dir:" + storedir);
949 LOG.debug("Store archive dir:" + storeArchive);
950
951
952 FileStatus[] mockFiles = addMockStoreFiles(2, services, storedir);
953
954 FileStatus[] storeFiles = fs.listStatus(storedir);
955 int index = 0;
956 for (FileStatus file : storeFiles) {
957 LOG.debug("Have store file:" + file.getPath());
958 assertEquals("Got unexpected store file", mockFiles[index].getPath(),
959 storeFiles[index].getPath());
960 index++;
961 }
962
963
964 assertTrue(janitor.cleanParent(parent, parentMetaRow));
965 LOG.debug("Finished cleanup of parent region");
966
967
968 FileStatus[] archivedStoreFiles = fs.listStatus(storeArchive);
969 logFiles("archived files", storeFiles);
970 logFiles("archived files", archivedStoreFiles);
971
972 assertArchiveEqualToOriginal(storeFiles, archivedStoreFiles, fs);
973
974
975 FSUtils.delete(fs, rootdir, true);
976 services.stop("Test finished");
977 server.stop("Test finished");
978 janitor.cancel(true);
979 }
980
981
982
983
984
985 private void logFiles(String description, FileStatus[] storeFiles) {
986 LOG.debug("Current " + description + ": ");
987 for (FileStatus file : storeFiles) {
988 LOG.debug(file.getPath());
989 }
990 }
991
992
993
994
995
996 @Test
997 public void testDuplicateHFileResolution() throws Exception {
998 String table = "table";
999 HBaseTestingUtility htu = new HBaseTestingUtility();
1000 setRootDirAndCleanIt(htu, "testCleanParent");
1001 Server server = new MockServer(htu);
1002 MasterServices services = new MockMasterServices(server);
1003
1004
1005
1006 CatalogJanitor janitor = new CatalogJanitor(server, services);
1007
1008
1009 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(table));
1010 htd.addFamily(new HColumnDescriptor("f"));
1011 HRegionInfo parent = new HRegionInfo(htd.getTableName(),
1012 Bytes.toBytes("aaa"), Bytes.toBytes("eee"));
1013 HRegionInfo splita = new HRegionInfo(htd.getTableName(),
1014 Bytes.toBytes("aaa"), Bytes.toBytes("ccc"));
1015 HRegionInfo splitb = new HRegionInfo(htd.getTableName(),
1016 Bytes.toBytes("ccc"), Bytes.toBytes("eee"));
1017
1018
1019 Result r = createResult(parent, splita, splitb);
1020
1021 FileSystem fs = FileSystem.get(htu.getConfiguration());
1022
1023 Path rootdir = services.getMasterFileSystem().getRootDir();
1024
1025
1026
1027 FSUtils.setRootDir(fs.getConf(), rootdir);
1028 Path tabledir = FSUtils.getTableDir(rootdir, parent.getTable());
1029 Path storedir = HStore.getStoreHomedir(tabledir, parent, htd.getColumnFamilies()[0].getName());
1030 System.out.println("Old root:" + rootdir);
1031 System.out.println("Old table:" + tabledir);
1032 System.out.println("Old store:" + storedir);
1033
1034 Path storeArchive = HFileArchiveUtil.getStoreArchivePath(services.getConfiguration(), parent,
1035 tabledir, htd.getColumnFamilies()[0].getName());
1036 System.out.println("Old archive:" + storeArchive);
1037
1038
1039 addMockStoreFiles(2, services, storedir);
1040
1041 FileStatus[] storeFiles = fs.listStatus(storedir);
1042
1043 assertTrue(janitor.cleanParent(parent, r));
1044
1045
1046 FileStatus[] archivedStoreFiles = fs.listStatus(storeArchive);
1047 assertArchiveEqualToOriginal(storeFiles, archivedStoreFiles, fs);
1048
1049
1050
1051 addMockStoreFiles(2, services, storedir);
1052
1053
1054 assertTrue(janitor.cleanParent(parent, r));
1055
1056
1057 archivedStoreFiles = fs.listStatus(storeArchive);
1058 assertArchiveEqualToOriginal(storeFiles, archivedStoreFiles, fs, true);
1059
1060
1061 services.stop("Test finished");
1062 server.stop("shutdown");
1063 janitor.cancel(true);
1064 }
1065
1066 private FileStatus[] addMockStoreFiles(int count, MasterServices services, Path storedir)
1067 throws IOException {
1068
1069 FileSystem fs = services.getMasterFileSystem().getFileSystem();
1070 fs.mkdirs(storedir);
1071
1072 for (int i = 0; i < count; i++) {
1073 Path storeFile = new Path(storedir, "_store" + i);
1074 FSDataOutputStream dos = fs.create(storeFile, true);
1075 dos.writeBytes("Some data: " + i);
1076 dos.close();
1077 }
1078 LOG.debug("Adding " + count + " store files to the storedir:" + storedir);
1079
1080 FileStatus[] storeFiles = fs.listStatus(storedir);
1081 assertEquals("Didn't have expected store files", count, storeFiles.length);
1082 return storeFiles;
1083 }
1084
1085 private String setRootDirAndCleanIt(final HBaseTestingUtility htu,
1086 final String subdir)
1087 throws IOException {
1088 Path testdir = htu.getDataTestDir(subdir);
1089 FileSystem fs = FileSystem.get(htu.getConfiguration());
1090 if (fs.exists(testdir)) assertTrue(fs.delete(testdir, true));
1091 FSUtils.setRootDir(htu.getConfiguration(), testdir);
1092 return FSUtils.getRootDir(htu.getConfiguration()).toString();
1093 }
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105 private Path createReferences(final MasterServices services,
1106 final HTableDescriptor htd, final HRegionInfo parent,
1107 final HRegionInfo daughter, final byte [] midkey, final boolean top)
1108 throws IOException {
1109 Path rootdir = services.getMasterFileSystem().getRootDir();
1110 Path tabledir = FSUtils.getTableDir(rootdir, parent.getTable());
1111 Path storedir = HStore.getStoreHomedir(tabledir, daughter,
1112 htd.getColumnFamilies()[0].getName());
1113 Reference ref =
1114 top? Reference.createTopReference(midkey): Reference.createBottomReference(midkey);
1115 long now = System.currentTimeMillis();
1116
1117 Path p = new Path(storedir, Long.toString(now) + "." + parent.getEncodedName());
1118 FileSystem fs = services.getMasterFileSystem().getFileSystem();
1119 ref.write(fs, p);
1120 return p;
1121 }
1122
1123 private Result createResult(final HRegionInfo parent, final HRegionInfo a,
1124 final HRegionInfo b)
1125 throws IOException {
1126 return MetaMockingUtil.getMetaTableRowResult(parent, null, a, b);
1127 }
1128
1129 private HTableDescriptor createHTableDescriptor() {
1130 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("t"));
1131 htd.addFamily(new HColumnDescriptor("f"));
1132 return htd;
1133 }
1134
1135 private MultiResponse buildMultiResponse(MultiRequest req) {
1136 MultiResponse.Builder builder = MultiResponse.newBuilder();
1137 RegionActionResult.Builder regionActionResultBuilder =
1138 RegionActionResult.newBuilder();
1139 ResultOrException.Builder roeBuilder = ResultOrException.newBuilder();
1140 for (RegionAction regionAction: req.getRegionActionList()) {
1141 regionActionResultBuilder.clear();
1142 for (ClientProtos.Action action: regionAction.getActionList()) {
1143 roeBuilder.clear();
1144 roeBuilder.setResult(ClientProtos.Result.getDefaultInstance());
1145 roeBuilder.setIndex(action.getIndex());
1146 regionActionResultBuilder.addResultOrException(roeBuilder.build());
1147 }
1148 builder.addRegionActionResult(regionActionResultBuilder.build());
1149 }
1150 return builder.build();
1151 }
1152
1153 }
1154