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.regionserver;
19  
20  import java.io.IOException;
21  import java.util.Random;
22  
23  import org.apache.hadoop.fs.FileSystem;
24  import org.apache.hadoop.fs.Path;
25  import org.apache.hadoop.hbase.HBaseTestingUtility;
26  import org.apache.hadoop.hbase.HColumnDescriptor;
27  import org.apache.hadoop.hbase.HRegionInfo;
28  import org.apache.hadoop.hbase.HTableDescriptor;
29  import org.apache.hadoop.hbase.testclassification.MediumTests;
30  import org.apache.hadoop.hbase.TableName;
31  import org.apache.hadoop.hbase.client.HBaseAdmin;
32  import org.apache.hadoop.hbase.client.HTable;
33  import org.apache.hadoop.hbase.client.Put;
34  import org.apache.hadoop.hbase.client.Result;
35  import org.apache.hadoop.hbase.client.ResultScanner;
36  import org.apache.hadoop.hbase.client.Scan;
37  import org.apache.hadoop.hbase.mob.MobConstants;
38  import org.apache.hadoop.hbase.mob.MobUtils;
39  import org.apache.hadoop.hbase.util.Bytes;
40  import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
41  import org.apache.hadoop.hbase.util.FSUtils;
42  import org.apache.hadoop.hbase.util.HFileArchiveUtil;
43  import org.junit.AfterClass;
44  import org.junit.Assert;
45  import org.junit.BeforeClass;
46  import org.junit.Test;
47  import org.junit.experimental.categories.Category;
48  
49  @Category(MediumTests.class)
50  public class TestDeleteMobTable {
51  
52    private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
53    private final static byte[] FAMILY = Bytes.toBytes("family");
54    private final static byte[] QF = Bytes.toBytes("qualifier");
55    private static Random random = new Random();
56  
57    @BeforeClass
58    public static void setUpBeforeClass() throws Exception {
59      TEST_UTIL.getConfiguration().setInt("hfile.format.version", 3);
60      TEST_UTIL.getConfiguration().setInt("hbase.master.info.port", 0);
61      TEST_UTIL.getConfiguration().setBoolean("hbase.regionserver.info.port.auto", true);
62      TEST_UTIL.startMiniCluster(1);
63    }
64  
65    @AfterClass
66    public static void tearDownAfterClass() throws Exception {
67      TEST_UTIL.shutdownMiniCluster();
68    }
69  
70    /**
71     * Generate the mob value.
72     *
73     * @param size
74     *          the size of the value
75     * @return the mob value generated
76     */
77    private static byte[] generateMobValue(int size) {
78      byte[] mobVal = new byte[size];
79      random.nextBytes(mobVal);
80      return mobVal;
81    }
82  
83    @Test
84    public void testDeleteMobTable() throws Exception {
85      byte[] tableName = Bytes.toBytes("testDeleteMobTable");
86      TableName tn = TableName.valueOf(tableName);
87      HTableDescriptor htd = new HTableDescriptor(tn);
88      HColumnDescriptor hcd = new HColumnDescriptor(FAMILY);
89      hcd.setMobEnabled(true);
90      hcd.setMobThreshold(0);
91      htd.addFamily(hcd);
92      HBaseAdmin admin = null;
93      HTable table = null;
94      try {
95        admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
96        admin.createTable(htd);
97        table = new HTable(TEST_UTIL.getConfiguration(), tableName);
98        byte[] value = generateMobValue(10);
99  
100       byte[] row = Bytes.toBytes("row");
101       Put put = new Put(row);
102       put.add(FAMILY, QF, EnvironmentEdgeManager.currentTime(), value);
103       table.put(put);
104 
105       table.flushCommits();
106       admin.flush(tableName);
107 
108       // the mob file exists
109       Assert.assertEquals(1, countMobFiles(tn, hcd.getNameAsString()));
110       Assert.assertEquals(0, countArchiveMobFiles(tn, hcd.getNameAsString()));
111       String fileName = assertHasOneMobRow(table, tn, hcd.getNameAsString());
112       Assert.assertFalse(mobArchiveExist(tn, hcd.getNameAsString(), fileName));
113       Assert.assertTrue(mobTableDirExist(tn));
114       table.close();
115 
116       admin.disableTable(tn);
117       admin.deleteTable(tn);
118 
119       Assert.assertFalse(admin.tableExists(tn));
120       Assert.assertEquals(0, countMobFiles(tn, hcd.getNameAsString()));
121       Assert.assertEquals(1, countArchiveMobFiles(tn, hcd.getNameAsString()));
122       Assert.assertTrue(mobArchiveExist(tn, hcd.getNameAsString(), fileName));
123       Assert.assertFalse(mobTableDirExist(tn));
124     } finally {
125       if (admin != null) {
126         admin.close();
127       }
128     }
129   }
130 
131   @Test
132   public void testDeleteNonMobTable() throws Exception {
133     byte[] tableName = Bytes.toBytes("testDeleteNonMobTable");
134     TableName tn = TableName.valueOf(tableName);
135     HTableDescriptor htd = new HTableDescriptor(tn);
136     HColumnDescriptor hcd = new HColumnDescriptor(FAMILY);
137     htd.addFamily(hcd);
138     HBaseAdmin admin = null;
139     HTable table = null;
140     try {
141       admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
142       admin.createTable(htd);
143       table = new HTable(TEST_UTIL.getConfiguration(), tableName);
144       byte[] value = generateMobValue(10);
145 
146       byte[] row = Bytes.toBytes("row");
147       Put put = new Put(row);
148       put.add(FAMILY, QF, EnvironmentEdgeManager.currentTime(), value);
149       table.put(put);
150 
151       table.flushCommits();
152       admin.flush(tableName);
153       table.close();
154 
155       // the mob file doesn't exist
156       Assert.assertEquals(0, countMobFiles(tn, hcd.getNameAsString()));
157       Assert.assertEquals(0, countArchiveMobFiles(tn, hcd.getNameAsString()));
158       Assert.assertFalse(mobTableDirExist(tn));
159 
160       admin.disableTable(tn);
161       admin.deleteTable(tn);
162 
163       Assert.assertFalse(admin.tableExists(tn));
164       Assert.assertEquals(0, countMobFiles(tn, hcd.getNameAsString()));
165       Assert.assertEquals(0, countArchiveMobFiles(tn, hcd.getNameAsString()));
166       Assert.assertFalse(mobTableDirExist(tn));
167     } finally {
168       if (admin != null) {
169         admin.close();
170       }
171     }
172   }
173   
174   @Test
175   public void testMobFamilyDelete() throws Exception {
176     byte[] tableName = Bytes.toBytes("testMobFamilyDelete");
177     TableName tn = TableName.valueOf(tableName);
178     HTableDescriptor htd = new HTableDescriptor(tn);
179     HColumnDescriptor hcd = new HColumnDescriptor(FAMILY);
180     hcd.setMobEnabled(true);
181     hcd.setMobThreshold(0);
182     htd.addFamily(hcd);
183     htd.addFamily(new HColumnDescriptor(Bytes.toBytes("family2")));
184     HBaseAdmin admin = null;
185     HTable table = null;
186     try {
187       admin = TEST_UTIL.getHBaseAdmin();
188       admin.createTable(htd);
189       table = new HTable(TEST_UTIL.getConfiguration(), tableName);
190       byte[] value = generateMobValue(10);
191       byte[] row = Bytes.toBytes("row");
192       Put put = new Put(row);
193       put.addColumn(FAMILY, QF, EnvironmentEdgeManager.currentTime(), value);
194       table.put(put);
195       admin.flush(tn);
196       // the mob file exists
197       Assert.assertEquals(1, countMobFiles(tn, hcd.getNameAsString()));
198       Assert.assertEquals(0, countArchiveMobFiles(tn, hcd.getNameAsString()));
199       String fileName = assertHasOneMobRow(table, tn, hcd.getNameAsString());
200       Assert.assertFalse(mobArchiveExist(tn, hcd.getNameAsString(), fileName));
201       Assert.assertTrue(mobTableDirExist(tn));
202       admin.deleteColumn(tn, FAMILY);
203       Assert.assertEquals(0, countMobFiles(tn, hcd.getNameAsString()));
204       Assert.assertEquals(1, countArchiveMobFiles(tn, hcd.getNameAsString()));
205       Assert.assertTrue(mobArchiveExist(tn, hcd.getNameAsString(), fileName));
206       Assert.assertFalse(mobColumnFamilyDirExist(tn));
207     } finally {
208       table.close();
209       if (admin != null) {
210         admin.close();
211       }
212       TEST_UTIL.deleteTable(tableName);
213     }
214   }
215 
216   private int countMobFiles(TableName tn, String familyName) throws IOException {
217     FileSystem fs = TEST_UTIL.getTestFileSystem();
218     Path mobFileDir = MobUtils.getMobFamilyPath(TEST_UTIL.getConfiguration(), tn, familyName);
219     if (fs.exists(mobFileDir)) {
220       return fs.listStatus(mobFileDir).length;
221     } else {
222       return 0;
223     }
224   }
225 
226   private int countArchiveMobFiles(TableName tn, String familyName)
227       throws IOException {
228     FileSystem fs = TEST_UTIL.getTestFileSystem();
229     Path storePath = HFileArchiveUtil.getStoreArchivePath(TEST_UTIL.getConfiguration(), tn,
230         MobUtils.getMobRegionInfo(tn).getEncodedName(), familyName);
231     if (fs.exists(storePath)) {
232       return fs.listStatus(storePath).length;
233     } else {
234       return 0;
235     }
236   }
237 
238   private boolean mobTableDirExist(TableName tn) throws IOException {
239     FileSystem fs = TEST_UTIL.getTestFileSystem();
240     Path tableDir = FSUtils.getTableDir(MobUtils.getMobHome(TEST_UTIL.getConfiguration()), tn);
241     return fs.exists(tableDir);
242   }
243   
244   private boolean mobColumnFamilyDirExist(TableName tn) throws IOException {
245     FileSystem fs = TEST_UTIL.getTestFileSystem();
246     Path tableDir = FSUtils.getTableDir(MobUtils.getMobHome(TEST_UTIL.getConfiguration()), tn);
247     HRegionInfo mobRegionInfo = MobUtils.getMobRegionInfo(tn);
248     Path mobFamilyDir = new Path(tableDir, new Path(mobRegionInfo.getEncodedName(), Bytes.toString(FAMILY)));
249     return fs.exists(mobFamilyDir);
250   }
251 
252   private boolean mobArchiveExist(TableName tn, String familyName, String fileName)
253       throws IOException {
254     FileSystem fs = TEST_UTIL.getTestFileSystem();
255     Path storePath = HFileArchiveUtil.getStoreArchivePath(TEST_UTIL.getConfiguration(), tn,
256         MobUtils.getMobRegionInfo(tn).getEncodedName(), familyName);
257     return fs.exists(new Path(storePath, fileName));
258   }
259 
260   private String assertHasOneMobRow(HTable table, TableName tn, String familyName)
261       throws IOException {
262     Scan scan = new Scan();
263     scan.setAttribute(MobConstants.MOB_SCAN_RAW, Bytes.toBytes(Boolean.TRUE));
264     ResultScanner rs = table.getScanner(scan);
265     Result r = rs.next();
266     Assert.assertNotNull(r);
267     byte[] value = r.getValue(FAMILY, QF);
268     String fileName = Bytes.toString(value, Bytes.SIZEOF_INT, value.length - Bytes.SIZEOF_INT);
269     Path filePath = new Path(
270         MobUtils.getMobFamilyPath(TEST_UTIL.getConfiguration(), tn, familyName), fileName);
271     FileSystem fs = TEST_UTIL.getTestFileSystem();
272     Assert.assertTrue(fs.exists(filePath));
273     r = rs.next();
274     Assert.assertNull(r);
275     return fileName;
276   }
277 }