1919
2020import  static  org .junit .Assert .assertArrayEquals ;
2121import  static  org .junit .Assert .assertEquals ;
22+ import  static  org .junit .Assert .assertFalse ;
2223import  static  org .junit .Assert .assertTrue ;
2324
2425import  java .io .IOException ;
2829import  java .util .Random ;
2930import  java .util .Set ;
3031import  java .util .TreeSet ;
31- import  java .util .concurrent .TimeUnit ;
3232import  java .util .stream .Collectors ;
33- 
3433import  org .apache .commons .io .IOUtils ;
3534import  org .apache .hadoop .conf .Configuration ;
3635import  org .apache .hadoop .hbase .ChoreService ;
4544import  org .apache .hadoop .hbase .TableName ;
4645import  org .apache .hadoop .hbase .client .Admin ;
4746import  org .apache .hadoop .hbase .client .ColumnFamilyDescriptorBuilder ;
48- import  org .apache .hadoop .hbase .client .CompactionState ;
4947import  org .apache .hadoop .hbase .client .Connection ;
5048import  org .apache .hadoop .hbase .client .ConnectionFactory ;
5149import  org .apache .hadoop .hbase .client .Get ;
6058import  org .apache .hadoop .hbase .util .Bytes ;
6159import  org .apache .hadoop .hbase .util .Pair ;
6260import  org .apache .hadoop .hbase .util .PairOfSameType ;
63- import  org .apache .hadoop .hbase .util .RetryCounter ;
6461import  org .apache .hadoop .hbase .util .StoppableImplementation ;
6562import  org .apache .hadoop .hbase .util .Threads ;
66- import  org .apache .hbase .thirdparty .com .google .common .collect .Iterators ;
67- import  org .apache .hbase .thirdparty .com .google .common .collect .Maps ;
6863import  org .junit .AfterClass ;
69- import  org .junit .Assert ;
7064import  org .junit .BeforeClass ;
7165import  org .junit .ClassRule ;
7266import  org .junit .Rule ;
7670import  org .slf4j .Logger ;
7771import  org .slf4j .LoggerFactory ;
7872
73+ import  org .apache .hbase .thirdparty .com .google .common .collect .Iterators ;
74+ import  org .apache .hbase .thirdparty .com .google .common .collect .Maps ;
75+ import  org .apache .hbase .thirdparty .com .google .common .io .Closeables ;
76+ 
7977@ Category (LargeTests .class )
8078public  class  TestEndToEndSplitTransaction  {
8179
8280  @ ClassRule 
8381  public  static  final  HBaseClassTestRule  CLASS_RULE  =
84-        HBaseClassTestRule .forClass (TestEndToEndSplitTransaction .class );
82+     HBaseClassTestRule .forClass (TestEndToEndSplitTransaction .class );
8583
8684  private  static  final  Logger  LOG  = LoggerFactory .getLogger (TestEndToEndSplitTransaction .class );
8785  private  static  final  HBaseTestingUtility  TEST_UTIL  = new  HBaseTestingUtility ();
@@ -93,81 +91,74 @@ public class TestEndToEndSplitTransaction {
9391  @ BeforeClass 
9492  public  static  void  beforeAllTests () throws  Exception  {
9593    TEST_UTIL .getConfiguration ().setInt (HConstants .HBASE_CLIENT_RETRIES_NUMBER , 5 );
96-     TEST_UTIL .startMiniCluster ();
94+     TEST_UTIL .startMiniCluster (1 );
9795  }
9896
9997  @ AfterClass 
10098  public  static  void  afterAllTests () throws  Exception  {
10199    TEST_UTIL .shutdownMiniCluster ();
102100  }
103101
104- 
105-   /* 
102+   /** 
106103   * This is the test for : HBASE-20940 This test will split the region and try to open an reference 
107104   * over store file. Once store file has any reference, it makes sure that region can't be split 
108-    * @throws Exception 
109105   */ 
110106  @ Test 
111107  public  void  testCanSplitJustAfterASplit () throws  Exception  {
112108    LOG .info ("Starting testCanSplitJustAfterASplit" );
113109    byte [] fam  = Bytes .toBytes ("cf_split" );
114110
111+     CompactSplit  compactSplit  =
112+       TEST_UTIL .getMiniHBaseCluster ().getRegionServer (0 ).getCompactSplitThread ();
115113    TableName  tableName  = TableName .valueOf ("CanSplitTable" );
116114    Table  source  = TEST_UTIL .getConnection ().getTable (tableName );
117115    Admin  admin  = TEST_UTIL .getAdmin ();
116+     // set a large min compaction file count to avoid compaction just after splitting. 
117+     TableDescriptor  htd  = TableDescriptorBuilder .newBuilder (tableName )
118+       .setColumnFamily (ColumnFamilyDescriptorBuilder .of (fam )).build ();
118119    Map <String , StoreFileReader > scanner  = Maps .newHashMap ();
119- 
120120    try  {
121-       TableDescriptor  htd  = TableDescriptorBuilder .newBuilder (tableName )
122-           .setColumnFamily (ColumnFamilyDescriptorBuilder .of (fam )).build ();
123- 
124121      admin .createTable (htd );
125122      TEST_UTIL .loadTable (source , fam );
126-       List < HRegion >  regions  =  TEST_UTIL . getHBaseCluster (). getRegions ( tableName );
127-       regions .get (0 ).forceSplit (null );
123+       compactSplit . setCompactionsEnabled ( false );
124+       TEST_UTIL . getHBaseCluster (). getRegions ( tableName ) .get (0 ).forceSplit (null );
128125      admin .split (tableName );
126+       TEST_UTIL .waitFor (60000 , () -> TEST_UTIL .getHBaseCluster ().getRegions (tableName ).size () == 2 );
129127
130-       while  (regions .size () <= 1 ) {
131-         regions  = TEST_UTIL .getHBaseCluster ().getRegions (tableName );
132-         regions .stream ()
133-             .forEach (r  -> r .getStores ().get (0 ).getStorefiles ().stream ()
134-                 .filter (
135-                   s  -> s .isReference () && !scanner .containsKey (r .getRegionInfo ().getEncodedName ()))
136-                 .forEach (sf  -> {
137-                   StoreFileReader  reader  = ((HStoreFile ) sf ).getReader ();
138-                   reader .getStoreFileScanner (true , false , false , 0 , 0 , false );
139-                   scanner .put (r .getRegionInfo ().getEncodedName (), reader );
140-                   LOG .info ("Got reference to file = "  + sf .getPath () + ",for region = " 
141-                       + r .getRegionInfo ().getEncodedName ());
142-                 }));
143-       }
144- 
145-       Assert .assertTrue ("Regions did not split properly" , regions .size () > 1 );
146-       Assert .assertTrue ("Could not get reference any of the store file" , scanner .size () > 1 );
147- 
148-       RetryCounter  retrier  = new  RetryCounter (30 , 1 , TimeUnit .SECONDS );
149-       while  (CompactionState .NONE  != admin .getCompactionState (tableName ) && retrier .shouldRetry ()) {
150-         retrier .sleepUntilNextRetry ();
128+       List <HRegion > regions  = TEST_UTIL .getHBaseCluster ().getRegions (tableName );
129+       regions .stream ()
130+         .forEach (r  -> r .getStores ().get (0 ).getStorefiles ().stream ()
131+           .filter (s  -> s .isReference () && !scanner .containsKey (r .getRegionInfo ().getEncodedName ()))
132+           .forEach (sf  -> {
133+             StoreFileReader  reader  = ((HStoreFile ) sf ).getReader ();
134+             reader .getStoreFileScanner (true , false , false , 0 , 0 , false );
135+             scanner .put (r .getRegionInfo ().getEncodedName (), reader );
136+             LOG .info ("Got reference to file = "  + sf .getPath () + ",for region = "  +
137+               r .getRegionInfo ().getEncodedName ());
138+           }));
139+       assertTrue ("Regions did not split properly" , regions .size () > 1 );
140+       assertTrue ("Could not get reference any of the store file" , scanner .size () > 1 );
141+       compactSplit .setCompactionsEnabled (true );
142+       for  (HRegion  region  : regions ) {
143+         region .compact (true );
151144      }
152145
153-       Assert .assertEquals ("Compaction did not complete in 30 secs" , CompactionState .NONE ,
154-         admin .getCompactionState (tableName ));
155- 
156146      regions .stream ()
157-            .filter (region  -> scanner .containsKey (region .getRegionInfo ().getEncodedName ()))
158-            .forEach (r  -> Assert . assertTrue ("Contains an open file reference which can be split" ,
159-             ! r .getStores ().get (0 ).canSplit ()));
147+         .filter (region  -> scanner .containsKey (region .getRegionInfo ().getEncodedName ()))
148+         .forEach (r  -> assertFalse ("Contains an open file reference which can be split" ,
149+           r .getStores ().get (0 ).canSplit ()));
160150    } finally  {
161-       scanner .values ().stream (). forEach (s  -> {
151+       scanner .values ().forEach (s  -> {
162152        try  {
163153          s .close (true );
164154        } catch  (IOException  ioe ) {
165155          LOG .error ("Failed while closing store file" , ioe );
166156        }
167157      });
168158      scanner .clear ();
169-       if  (source  != null ) {
170-         source .close ();
159+       Closeables .close (source , true );
160+       if  (!compactSplit .isCompactionsEnabled ()) {
161+         compactSplit .setCompactionsEnabled (true );
171162      }
172163      TEST_UTIL .deleteTableIfAny (tableName );
173164    }
@@ -182,8 +173,8 @@ public void testFromClientSideWhileSplitting() throws Throwable {
182173    final  TableName  tableName  = TableName .valueOf (name .getMethodName ());
183174    final  byte [] FAMILY  = Bytes .toBytes ("family" );
184175
185-     //SplitTransaction will update the meta table by offlining the parent region, and adding info 
186-     //for daughters. 
176+     //  SplitTransaction will update the meta table by offlining the parent region, and adding info 
177+     //  for daughters. 
187178    Table  table  = TEST_UTIL .createTable (tableName , FAMILY );
188179
189180    Stoppable  stopper  = new  StoppableImplementation ();
@@ -194,7 +185,7 @@ public void testFromClientSideWhileSplitting() throws Throwable {
194185    choreService .scheduleChore (regionChecker );
195186    regionSplitter .start ();
196187
197-     //wait until the splitter is finished 
188+     //  wait until the splitter is finished 
198189    regionSplitter .join ();
199190    stopper .stop (null );
200191
@@ -206,7 +197,7 @@ public void testFromClientSideWhileSplitting() throws Throwable {
206197      throw  new  AssertionError ("regionSplitter" , regionSplitter .ex );
207198    }
208199
209-     //one final check 
200+     //  one final check 
210201    regionChecker .verify ();
211202  }
212203
@@ -222,7 +213,7 @@ static class RegionSplitter extends Thread {
222213    RegionSplitter (Table  table ) throws  IOException  {
223214      this .table  = table ;
224215      this .tableName  = table .getName ();
225-       this .family  = table .getTableDescriptor ().getFamiliesKeys (). iterator (). next ();
216+       this .family  = table .getDescriptor ().getColumnFamilies ()[ 0 ]. getName ();
226217      admin  = TEST_UTIL .getAdmin ();
227218      rs  = TEST_UTIL .getMiniHBaseCluster ().getRegionServer (0 );
228219      connection  = TEST_UTIL .getConnection ();
@@ -276,7 +267,7 @@ public void run() {
276267
277268    void  addData (int  start ) throws  IOException  {
278269      List <Put > puts  = new  ArrayList <>();
279-       for  (int  i = start ; i < start  + 100 ; i ++) {
270+       for  (int  i  =  start ; i   < start  + 100 ; i ++) {
280271        Put  put  = new  Put (Bytes .toBytes (i ));
281272        put .addColumn (family , family , Bytes .toBytes (i ));
282273        puts .add (put );
@@ -306,26 +297,26 @@ static class RegionChecker extends ScheduledChore {
306297    void  verifyRegionsUsingMetaTableAccessor () throws  Exception  {
307298      List <RegionInfo > regionList  = MetaTableAccessor .getTableRegions (connection , tableName , true );
308299      verifyTableRegions (regionList .stream ()
309-            .collect (Collectors .toCollection (() -> new  TreeSet <>(RegionInfo .COMPARATOR ))));
300+         .collect (Collectors .toCollection (() -> new  TreeSet <>(RegionInfo .COMPARATOR ))));
310301      regionList  = MetaTableAccessor .getAllRegions (connection , true );
311302      verifyTableRegions (regionList .stream ()
312-            .collect (Collectors .toCollection (() -> new  TreeSet <>(RegionInfo .COMPARATOR ))));
303+         .collect (Collectors .toCollection (() -> new  TreeSet <>(RegionInfo .COMPARATOR ))));
313304    }
314305
315306    /** verify region boundaries obtained from HTable.getStartEndKeys() */ 
316307    void  verifyRegionsUsingHTable () throws  IOException  {
317308      Table  table  = null ;
318309      try  {
319-         //HTable.getStartEndKeys() 
310+         //  HTable.getStartEndKeys() 
320311        table  = connection .getTable (tableName );
321312
322-         try (RegionLocator  rl  = connection .getRegionLocator (tableName )) {
313+         try   (RegionLocator  rl  = connection .getRegionLocator (tableName )) {
323314          Pair <byte [][], byte [][]> keys  = rl .getStartEndKeys ();
324315          verifyStartEndKeys (keys );
325316
326317          Set <RegionInfo > regions  = new  TreeSet <>(RegionInfo .COMPARATOR );
327318          for  (HRegionLocation  loc  : rl .getAllRegionLocations ()) {
328-             regions .add (loc .getRegionInfo ());
319+             regions .add (loc .getRegion ());
329320          }
330321          verifyTableRegions (regions );
331322        }
@@ -346,7 +337,7 @@ void verifyTableRegions(Set<RegionInfo> regions) {
346337      byte [][] startKeys  = new  byte [regions .size ()][];
347338      byte [][] endKeys  = new  byte [regions .size ()][];
348339
349-       int  i = 0 ;
340+       int  i  =  0 ;
350341      for  (RegionInfo  region  : regions ) {
351342        startKeys [i ] = region .getStartKey ();
352343        endKeys [i ] = region .getEndKey ();
@@ -363,20 +354,20 @@ void verifyStartEndKeys(Pair<byte[][], byte[][]> keys) {
363354      assertEquals (startKeys .length , endKeys .length );
364355      assertTrue ("Found 0 regions for the table" , startKeys .length  > 0 );
365356
366-       assertArrayEquals ("Start key for the first region is not byte[0]" ,
367-            HConstants . EMPTY_START_ROW ,  startKeys [0 ]);
357+       assertArrayEquals ("Start key for the first region is not byte[0]" ,  HConstants . EMPTY_START_ROW , 
358+         startKeys [0 ]);
368359      byte [] prevEndKey  = HConstants .EMPTY_START_ROW ;
369360
370361      // ensure that we do not have any gaps 
371-       for  (int  i = 0 ; i < startKeys .length ; i ++) {
362+       for  (int  i  =  0 ; i  <  startKeys .length ; i ++) {
372363        assertArrayEquals (
373-              "Hole in hbase:meta is detected. prevEndKey="  + Bytes .toStringBinary (prevEndKey )
374-                 +  " ,regionStartKey="  + Bytes .toStringBinary (startKeys [i ]),  prevEndKey ,
375-              startKeys [i ]);
364+           "Hole in hbase:meta is detected. prevEndKey="  + Bytes .toStringBinary (prevEndKey ) + 
365+             " ,regionStartKey="  + Bytes .toStringBinary (startKeys [i ]),
366+           prevEndKey ,  startKeys [i ]);
376367        prevEndKey  = endKeys [i ];
377368      }
378369      assertArrayEquals ("End key for the last region is not byte[0]" , HConstants .EMPTY_END_ROW ,
379-            endKeys [endKeys .length  - 1 ]);
370+         endKeys [endKeys .length  - 1 ]);
380371    }
381372
382373    @ Override 
@@ -428,10 +419,9 @@ public static void compactAndBlockUntilDone(Admin admin, HRegionServer rs, byte[
428419   * Blocks until the region split is complete in hbase:meta and region server opens the daughters 
429420   */ 
430421  public  static  void  blockUntilRegionSplit (Configuration  conf , long  timeout ,
431-       final  byte [] regionName , boolean  waitForDaughters )
432-       throws  IOException , InterruptedException  {
422+       final  byte [] regionName , boolean  waitForDaughters ) throws  IOException , InterruptedException  {
433423    long  start  = System .currentTimeMillis ();
434-     log ("blocking until region is split:"  +   Bytes .toStringBinary (regionName ));
424+     log ("blocking until region is split:"  + Bytes .toStringBinary (regionName ));
435425    RegionInfo  daughterA  = null , daughterB  = null ;
436426    try  (Connection  conn  = ConnectionFactory .createConnection (conf );
437427        Table  metaTable  = conn .getTable (TableName .META_TABLE_NAME )) {
@@ -459,7 +449,7 @@ public static void blockUntilRegionSplit(Configuration conf, long timeout,
459449          Bytes .toString (regionName ) + ", region="  + region );
460450      }
461451
462-       //if we are here, this means the region split is complete or timed out 
452+       //  if we are here, this means the region split is complete or timed out 
463453      if  (waitForDaughters ) {
464454        long  rem  = timeout  - (System .currentTimeMillis () - start );
465455        blockUntilRegionIsInMeta (conn , rem , daughterA );
@@ -504,7 +494,7 @@ public static void blockUntilRegionIsInMeta(Connection conn, long timeout, Regio
504494    long  start  = System .currentTimeMillis ();
505495    while  (System .currentTimeMillis () - start  < timeout ) {
506496      HRegionLocation  loc  = MetaTableAccessor .getRegionLocation (conn , hri );
507-       if  (loc  != null  && !loc .getRegionInfo ().isOffline ()) {
497+       if  (loc  != null  && !loc .getRegion ().isOffline ()) {
508498        log ("found region in META: "  + hri .getRegionNameAsString ());
509499        break ;
510500      }
0 commit comments