001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.util.compaction;
019
020import static org.junit.Assert.assertEquals;
021import static org.junit.Assert.assertTrue;
022
023import java.io.IOException;
024
025import org.apache.hadoop.hbase.HBaseClassTestRule;
026import org.apache.hadoop.hbase.HBaseTestingUtility;
027import org.apache.hadoop.hbase.TableName;
028import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
029import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
030import org.apache.hadoop.hbase.client.Connection;
031import org.apache.hadoop.hbase.client.Table;
032import org.apache.hadoop.hbase.client.TableDescriptor;
033import org.apache.hadoop.hbase.testclassification.MediumTests;
034import org.apache.hadoop.hbase.testclassification.MiscTests;
035import org.junit.After;
036import org.junit.Before;
037import org.junit.ClassRule;
038import org.junit.Rule;
039import org.junit.Test;
040import org.junit.experimental.categories.Category;
041import org.junit.rules.TestName;
042
043@Category({ MiscTests.class, MediumTests.class })
044public class TestMajorCompactorTTL extends TestMajorCompactor {
045  @ClassRule
046  public static final HBaseClassTestRule CLASS_RULE =
047      HBaseClassTestRule.forClass(TestMajorCompactorTTL.class);
048
049  @Rule
050  public TestName name = new TestName();
051
052  @Before
053  @Override
054  public void setUp() throws Exception {
055    utility = new HBaseTestingUtility();
056    utility.getConfiguration().setInt("hbase.hfile.compaction.discharger.interval", 10);
057    utility.startMiniCluster();
058    admin = utility.getAdmin();
059  }
060
061  @After
062  @Override
063  public void tearDown() throws Exception {
064    utility.shutdownMiniCluster();
065  }
066
067  @Test
068  public void testCompactingATable() throws Exception {
069    TableName tableName = createTable(name.getMethodName());
070
071    // Delay a bit, so we can set the table TTL to 5 seconds
072    Thread.sleep(10 * 1000);
073
074    int numberOfRegions = admin.getRegions(tableName).size();
075    int numHFiles = utility.getNumHFiles(tableName, FAMILY);
076    // we should have a table with more store files than we would before we major compacted.
077    assertTrue(numberOfRegions < numHFiles);
078    modifyTTL(tableName);
079
080    MajorCompactorTTL compactor = new MajorCompactorTTL(utility.getConfiguration(),
081        admin.getDescriptor(tableName), 1, 200);
082    compactor.initializeWorkQueues();
083    compactor.compactAllRegions();
084    compactor.shutdown();
085
086    // verify that the store has been completely major compacted.
087    numberOfRegions = admin.getRegions(tableName).size();
088    numHFiles = utility.getNumHFiles(tableName, FAMILY);
089    assertEquals(numberOfRegions, numHFiles);
090  }
091
092  protected void modifyTTL(TableName tableName) throws IOException, InterruptedException {
093    // Set the TTL to 5 secs, so all the files just written above will get cleaned up on compact.
094    admin.disableTable(tableName);
095    utility.waitTableDisabled(tableName.getName());
096    TableDescriptor descriptor = admin.getDescriptor(tableName);
097    ColumnFamilyDescriptor colDesc = descriptor.getColumnFamily(FAMILY);
098    ColumnFamilyDescriptorBuilder cFDB = ColumnFamilyDescriptorBuilder.newBuilder(colDesc);
099    cFDB.setTimeToLive(5);
100    admin.modifyColumnFamily(tableName, cFDB.build());
101    admin.enableTable(tableName);
102    utility.waitTableEnabled(tableName);
103  }
104
105  protected TableName createTable(String name) throws IOException, InterruptedException {
106    TableName tableName = TableName.valueOf(name);
107    utility.createMultiRegionTable(tableName, FAMILY, 5);
108    utility.waitTableAvailable(tableName);
109    Connection connection = utility.getConnection();
110    Table table = connection.getTable(tableName);
111    // write data and flush multiple store files:
112    for (int i = 0; i < 5; i++) {
113      utility.loadRandomRows(table, FAMILY, 50, 100);
114      utility.flush(tableName);
115    }
116    table.close();
117    return tableName;
118  }
119}