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