View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.client;
19  
20  import java.io.IOException;
21  import java.io.InterruptedIOException;
22  
23  import org.apache.hadoop.hbase.HBaseTestingUtility;
24  import org.apache.hadoop.hbase.HColumnDescriptor;
25  import org.apache.hadoop.hbase.HConstants;
26  import org.apache.hadoop.hbase.HTableDescriptor;
27  import org.apache.hadoop.hbase.TableName;
28  import org.apache.hadoop.hbase.coprocessor.BaseRegionObserver;
29  import org.apache.hadoop.hbase.coprocessor.ObserverContext;
30  import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
31  import org.apache.hadoop.hbase.master.cleaner.TimeToLiveHFileCleaner;
32  import org.apache.hadoop.hbase.mob.MobConstants;
33  import org.apache.hadoop.hbase.snapshot.MobSnapshotTestingUtils;
34  import org.apache.hadoop.hbase.snapshot.SnapshotTestingUtils;
35  import org.apache.hadoop.hbase.testclassification.LargeTests;
36  import org.apache.hadoop.hbase.util.Bytes;
37  import static org.junit.Assert.assertEquals;
38  import org.junit.BeforeClass;
39  import org.junit.Test;
40  import org.junit.experimental.categories.Category;
41  
42  /**
43   * Test clone snapshots from the client
44   */
45  @Category({LargeTests.class})
46  public class TestMobCloneSnapshotFromClient extends TestCloneSnapshotFromClient {
47  
48    private static boolean delayFlush = false;
49  
50    protected static void setupConfiguration() {
51      TestCloneSnapshotFromClient.setupConfiguration();
52      TEST_UTIL.getConfiguration().setLong(TimeToLiveHFileCleaner.TTL_CONF_KEY, 0);
53      TEST_UTIL.getConfiguration().setInt(MobConstants.MOB_FILE_CACHE_SIZE_KEY, 0);
54    }
55  
56    @BeforeClass
57    public static void setUpBeforeClass() throws Exception {
58      setupConfiguration();
59      TEST_UTIL.startMiniCluster(3);
60    }
61  
62    @Override
63    protected void createTableAndSnapshots() throws Exception {
64      // create Table and disable it
65      createMobTable(TEST_UTIL, tableName, SnapshotTestingUtils.getSplitKeys(), getNumReplicas(),
66        FAMILY);
67      delayFlush = false;
68      admin.disableTable(tableName);
69  
70      // take an empty snapshot
71      admin.snapshot(emptySnapshot, tableName);
72  
73      Connection c = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration());
74      Table table = c.getTable(tableName);
75      try {
76        // enable table and insert data
77        admin.enableTable(tableName);
78        SnapshotTestingUtils.loadData(TEST_UTIL, tableName, 20, FAMILY);
79        snapshot0Rows = MobSnapshotTestingUtils.countMobRows(table);
80        admin.disableTable(tableName);
81  
82        // take a snapshot
83        admin.snapshot(snapshotName0, tableName);
84  
85        // enable table and insert more data
86        admin.enableTable(tableName);
87        SnapshotTestingUtils.loadData(TEST_UTIL, tableName, 20, FAMILY);
88        snapshot1Rows = MobSnapshotTestingUtils.countMobRows(table);
89        admin.disableTable(tableName);
90  
91        // take a snapshot of the updated table
92        admin.snapshot(snapshotName1, tableName);
93  
94        // re-enable table
95        admin.enableTable(tableName);
96      } finally {
97        table.close();
98      }
99    }
100 
101   @Test
102   @Override
103   public void testCloneLinksAfterDelete() throws IOException, InterruptedException {
104     // delay the flush to make sure
105     delayFlush = true;
106     SnapshotTestingUtils.loadData(TEST_UTIL, tableName, 20, FAMILY);
107     long tid = System.currentTimeMillis();
108     byte[] snapshotName3 = Bytes.toBytes("snaptb3-" + tid);
109     TableName clonedTableName3 = TableName.valueOf("clonedtb3-" + System.currentTimeMillis());
110     admin.snapshot(snapshotName3, tableName);
111     delayFlush = false;
112     int snapshot3Rows = -1;
113     try (Table table = TEST_UTIL.getConnection().getTable(tableName)) {
114       snapshot3Rows = TEST_UTIL.countRows(table);
115     }
116     admin.cloneSnapshot(snapshotName3, clonedTableName3);
117     admin.deleteSnapshot(snapshotName3);
118     super.testCloneLinksAfterDelete();
119     verifyRowCount(TEST_UTIL, clonedTableName3, snapshot3Rows);
120     admin.disableTable(clonedTableName3);
121     admin.deleteTable(clonedTableName3);
122   }
123 
124   @Override
125   protected void verifyRowCount(final HBaseTestingUtility util, final TableName tableName,
126       long expectedRows) throws IOException {
127     MobSnapshotTestingUtils.verifyMobRowCount(util, tableName, expectedRows);
128   }
129 
130   /**
131    * This coprocessor is used to delay the flush.
132    */
133   public static class DelayFlushCoprocessor extends BaseRegionObserver {
134     @Override
135     public void preFlush(ObserverContext<RegionCoprocessorEnvironment> e) throws IOException {
136       if (delayFlush) {
137         try {
138           if (Bytes.compareTo(e.getEnvironment().getRegionInfo().getStartKey(),
139             HConstants.EMPTY_START_ROW) != 0) {
140             Thread.sleep(100);
141           }
142         } catch (InterruptedException e1) {
143           throw new InterruptedIOException(e1.getMessage());
144         }
145       }
146       super.preFlush(e);
147     }
148   }
149 
150   private void createMobTable(final HBaseTestingUtility util, final TableName tableName,
151     final byte[][] splitKeys, int regionReplication, final byte[]... families) throws IOException,
152     InterruptedException {
153     HTableDescriptor htd = new HTableDescriptor(tableName);
154     htd.setRegionReplication(regionReplication);
155     htd.addCoprocessor(DelayFlushCoprocessor.class.getName());
156     for (byte[] family : families) {
157       HColumnDescriptor hcd = new HColumnDescriptor(family);
158       hcd.setMobEnabled(true);
159       hcd.setMobThreshold(0L);
160       htd.addFamily(hcd);
161     }
162     util.getHBaseAdmin().createTable(htd, splitKeys);
163     SnapshotTestingUtils.waitForTableToBeOnline(util, tableName);
164     assertEquals((splitKeys.length + 1) * regionReplication,
165       util.getHBaseAdmin().getTableRegions(tableName).size());
166   }
167 }