1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.util;
20
21 import static org.junit.Assert.assertTrue;
22
23 import java.io.IOException;
24 import java.util.List;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.hadoop.conf.Configuration;
29 import org.apache.hadoop.fs.FileSystem;
30 import org.apache.hadoop.fs.Path;
31 import org.apache.hadoop.hbase.*;
32 import org.apache.hadoop.hbase.client.Admin;
33 import org.apache.hadoop.hbase.client.Connection;
34 import org.apache.hadoop.hbase.client.HBaseAdmin;
35 import org.apache.hadoop.hbase.client.HConnectionManager;
36 import org.apache.hadoop.hbase.client.Put;
37 import org.apache.hadoop.hbase.client.Durability;
38 import org.apache.hadoop.hbase.regionserver.HRegion;
39 import org.apache.hadoop.hbase.testclassification.MediumTests;
40 import org.junit.Test;
41 import org.junit.experimental.categories.Category;
42
43
44
45
46 @Category(MediumTests.class)
47 public class TestMergeTable {
48 private static final Log LOG = LogFactory.getLog(TestMergeTable.class);
49 private final HBaseTestingUtility UTIL = new HBaseTestingUtility();
50 private static final byte [] COLUMN_NAME = Bytes.toBytes("contents");
51 private static final byte [] VALUE;
52 static {
53
54 String partialValue = String.valueOf(System.currentTimeMillis());
55 StringBuilder val = new StringBuilder();
56 while (val.length() < 1024) {
57 val.append(partialValue);
58 }
59 VALUE = Bytes.toBytes(val.toString());
60 }
61
62
63
64
65
66
67
68
69 @Test (timeout=300000) public void testMergeTable() throws Exception {
70
71 HTableDescriptor desc = new HTableDescriptor(org.apache.hadoop.hbase.TableName.valueOf(Bytes.toBytes("test")));
72 desc.addFamily(new HColumnDescriptor(COLUMN_NAME));
73
74
75 UTIL.getConfiguration().setLong(HConstants.HREGION_MAX_FILESIZE, 64L * 1024L * 1024L);
76
77 UTIL.getConfiguration().setInt("hbase.regionserver.regionSplitLimit", 0);
78
79 UTIL.startMiniDFSCluster(1);
80
81 Path rootdir = UTIL.createRootDir();
82 FileSystem fs = FileSystem.get(UTIL.getConfiguration());
83 if (fs.exists(rootdir)) {
84 if (fs.delete(rootdir, true)) {
85 LOG.info("Cleaned up existing " + rootdir);
86 }
87 }
88
89
90
91
92
93
94
95 byte [] row_70001 = Bytes.toBytes("row_70001");
96 byte [] row_80001 = Bytes.toBytes("row_80001");
97
98
99
100 new FSTableDescriptors(UTIL.getConfiguration(), fs, rootdir).createTableDescriptor(desc);
101 HRegion [] regions = {
102 createRegion(desc, null, row_70001, 1, 70000, rootdir),
103 createRegion(desc, row_70001, row_80001, 70001, 10000, rootdir),
104 createRegion(desc, row_80001, null, 80001, 11000, rootdir)
105 };
106
107
108
109 setupMeta(rootdir, regions);
110 try {
111 LOG.info("Starting mini zk cluster");
112 UTIL.startMiniZKCluster();
113 LOG.info("Starting mini hbase cluster");
114 UTIL.startMiniHBaseCluster(1, 1);
115 Configuration c = new Configuration(UTIL.getConfiguration());
116 Connection connection = HConnectionManager.getConnection(c);
117
118 List<HRegionInfo> originalTableRegions =
119 MetaTableAccessor.getTableRegions(UTIL.getZooKeeperWatcher(), connection,
120 desc.getTableName());
121 LOG.info("originalTableRegions size=" + originalTableRegions.size() +
122 "; " + originalTableRegions);
123 Admin admin = new HBaseAdmin(c);
124 admin.disableTable(desc.getTableName());
125 HMerge.merge(c, FileSystem.get(c), desc.getTableName());
126 List<HRegionInfo> postMergeTableRegions =
127 MetaTableAccessor.getTableRegions(UTIL.getZooKeeperWatcher(), connection,
128 desc.getTableName());
129 LOG.info("postMergeTableRegions size=" + postMergeTableRegions.size() +
130 "; " + postMergeTableRegions);
131 assertTrue("originalTableRegions=" + originalTableRegions.size() +
132 ", postMergeTableRegions=" + postMergeTableRegions.size(),
133 postMergeTableRegions.size() < originalTableRegions.size());
134 LOG.info("Done with merge");
135 } finally {
136 UTIL.shutdownMiniCluster();
137 LOG.info("After cluster shutdown");
138 }
139 }
140
141 private HRegion createRegion(final HTableDescriptor desc,
142 byte [] startKey, byte [] endKey, int firstRow, int nrows, Path rootdir)
143 throws IOException {
144 HRegionInfo hri = new HRegionInfo(desc.getTableName(), startKey, endKey);
145 HRegion region = HRegion.createHRegion(hri, rootdir, UTIL.getConfiguration(), desc);
146 LOG.info("Created region " + region.getRegionInfo().getRegionNameAsString());
147 for(int i = firstRow; i < firstRow + nrows; i++) {
148 Put put = new Put(Bytes.toBytes("row_" + String.format("%1$05d", i)));
149 put.setDurability(Durability.SKIP_WAL);
150 put.add(COLUMN_NAME, null, VALUE);
151 region.put(put);
152 if (i % 10000 == 0) {
153 LOG.info("Flushing write #" + i);
154 region.flush(true);
155 }
156 }
157 HRegion.closeHRegion(region);
158 return region;
159 }
160
161 protected void setupMeta(Path rootdir, final HRegion [] regions)
162 throws IOException {
163 HRegion meta =
164 HRegion.createHRegion(HRegionInfo.FIRST_META_REGIONINFO, rootdir,
165 UTIL.getConfiguration(), UTIL.getMetaTableDescriptor());
166 for (HRegion r: regions) {
167 HRegion.addRegionToMETA(meta, r);
168 }
169 HRegion.closeHRegion(meta);
170 }
171
172 }
173