1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.client;
19
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.fail;
22
23 import java.io.IOException;
24 import java.util.HashSet;
25 import java.util.Set;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.hadoop.fs.Path;
30 import org.apache.hadoop.hbase.TableName;
31 import org.apache.hadoop.hbase.HBaseTestingUtility;
32 import org.apache.hadoop.hbase.HColumnDescriptor;
33 import org.apache.hadoop.hbase.HConstants;
34 import org.apache.hadoop.hbase.HTableDescriptor;
35 import org.apache.hadoop.hbase.LargeTests;
36 import org.apache.hadoop.hbase.master.MasterFileSystem;
37 import org.apache.hadoop.hbase.master.snapshot.SnapshotManager;
38 import org.apache.hadoop.hbase.regionserver.NoSuchColumnFamilyException;
39 import org.apache.hadoop.hbase.snapshot.SnapshotTestingUtils;
40 import org.apache.hadoop.hbase.util.Bytes;
41 import org.apache.hadoop.hbase.util.FSUtils;
42 import org.junit.After;
43 import org.junit.AfterClass;
44 import org.junit.Before;
45 import org.junit.BeforeClass;
46 import org.junit.Test;
47 import org.junit.experimental.categories.Category;
48
49
50
51
52 @Category(LargeTests.class)
53 public class TestRestoreSnapshotFromClient {
54 final Log LOG = LogFactory.getLog(getClass());
55
56 private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
57
58 private final byte[] FAMILY = Bytes.toBytes("cf");
59
60 private byte[] emptySnapshot;
61 private byte[] snapshotName0;
62 private byte[] snapshotName1;
63 private byte[] snapshotName2;
64 private int snapshot0Rows;
65 private int snapshot1Rows;
66 private TableName tableName;
67 private HBaseAdmin admin;
68
69 @BeforeClass
70 public static void setUpBeforeClass() throws Exception {
71 TEST_UTIL.getConfiguration().setBoolean(SnapshotManager.HBASE_SNAPSHOT_ENABLED, true);
72 TEST_UTIL.getConfiguration().setBoolean("hbase.online.schema.update.enable", true);
73 TEST_UTIL.getConfiguration().setInt("hbase.hstore.compactionThreshold", 10);
74 TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
75 TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
76 TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 6);
77 TEST_UTIL.getConfiguration().setBoolean(
78 "hbase.master.enabletable.roundrobin", true);
79 TEST_UTIL.startMiniCluster(3);
80 }
81
82 @AfterClass
83 public static void tearDownAfterClass() throws Exception {
84 TEST_UTIL.shutdownMiniCluster();
85 }
86
87
88
89
90
91
92 @Before
93 public void setup() throws Exception {
94 this.admin = TEST_UTIL.getHBaseAdmin();
95
96 long tid = System.currentTimeMillis();
97 tableName =
98 TableName.valueOf("testtb-" + tid);
99 emptySnapshot = Bytes.toBytes("emptySnaptb-" + tid);
100 snapshotName0 = Bytes.toBytes("snaptb0-" + tid);
101 snapshotName1 = Bytes.toBytes("snaptb1-" + tid);
102 snapshotName2 = Bytes.toBytes("snaptb2-" + tid);
103
104
105 SnapshotTestingUtils.createTable(TEST_UTIL, tableName, FAMILY);
106 admin.disableTable(tableName);
107
108
109 admin.snapshot(emptySnapshot, tableName);
110
111 HTable table = new HTable(TEST_UTIL.getConfiguration(), tableName);
112 try {
113
114 admin.enableTable(tableName);
115 SnapshotTestingUtils.loadData(TEST_UTIL, table, 500, FAMILY);
116 snapshot0Rows = TEST_UTIL.countRows(table);
117 admin.disableTable(tableName);
118
119
120 admin.snapshot(snapshotName0, tableName);
121
122
123 admin.enableTable(tableName);
124 SnapshotTestingUtils.loadData(TEST_UTIL, table, 500, FAMILY);
125 snapshot1Rows = TEST_UTIL.countRows(table);
126 admin.disableTable(tableName);
127
128
129 admin.snapshot(snapshotName1, tableName);
130
131
132 admin.enableTable(tableName);
133 } finally {
134 table.close();
135 }
136 }
137
138 @After
139 public void tearDown() throws Exception {
140 TEST_UTIL.deleteTable(tableName);
141 SnapshotTestingUtils.deleteAllSnapshots(TEST_UTIL.getHBaseAdmin());
142 SnapshotTestingUtils.deleteArchiveDirectory(TEST_UTIL);
143 }
144
145 @Test
146 public void testRestoreSnapshot() throws IOException {
147 SnapshotTestingUtils.verifyRowCount(TEST_UTIL, tableName, snapshot1Rows);
148
149
150 admin.disableTable(tableName);
151 admin.restoreSnapshot(snapshotName0);
152 admin.enableTable(tableName);
153 SnapshotTestingUtils.verifyRowCount(TEST_UTIL, tableName, snapshot0Rows);
154
155
156 admin.disableTable(tableName);
157 admin.restoreSnapshot(emptySnapshot);
158 admin.enableTable(tableName);
159 SnapshotTestingUtils.verifyRowCount(TEST_UTIL, tableName, 0);
160
161
162 admin.disableTable(tableName);
163 admin.restoreSnapshot(snapshotName1);
164 admin.enableTable(tableName);
165 SnapshotTestingUtils.verifyRowCount(TEST_UTIL, tableName, snapshot1Rows);
166 }
167
168 @Test
169 public void testRestoreSchemaChange() throws Exception {
170 byte[] TEST_FAMILY2 = Bytes.toBytes("cf2");
171
172 HTable table = new HTable(TEST_UTIL.getConfiguration(), tableName);
173
174
175 admin.disableTable(tableName);
176 admin.addColumn(tableName, new HColumnDescriptor(TEST_FAMILY2));
177 admin.enableTable(tableName);
178 assertEquals(2, table.getTableDescriptor().getFamilies().size());
179 HTableDescriptor htd = admin.getTableDescriptor(tableName);
180 assertEquals(2, htd.getFamilies().size());
181 SnapshotTestingUtils.loadData(TEST_UTIL, table, 500, TEST_FAMILY2);
182 long snapshot2Rows = snapshot1Rows + 500;
183 assertEquals(snapshot2Rows, TEST_UTIL.countRows(table));
184 assertEquals(500, TEST_UTIL.countRows(table, TEST_FAMILY2));
185 Set<String> fsFamilies = getFamiliesFromFS(tableName);
186 assertEquals(2, fsFamilies.size());
187 table.close();
188
189
190 admin.disableTable(tableName);
191 admin.snapshot(snapshotName2, tableName);
192
193
194 admin.restoreSnapshot(snapshotName0);
195 admin.enableTable(tableName);
196 assertEquals(1, table.getTableDescriptor().getFamilies().size());
197 try {
198 TEST_UTIL.countRows(table, TEST_FAMILY2);
199 fail("family '" + Bytes.toString(TEST_FAMILY2) + "' should not exists");
200 } catch (NoSuchColumnFamilyException e) {
201
202 }
203 assertEquals(snapshot0Rows, TEST_UTIL.countRows(table));
204 htd = admin.getTableDescriptor(tableName);
205 assertEquals(1, htd.getFamilies().size());
206 fsFamilies = getFamiliesFromFS(tableName);
207 assertEquals(1, fsFamilies.size());
208 table.close();
209
210
211 admin.disableTable(tableName);
212 admin.restoreSnapshot(snapshotName2);
213 admin.enableTable(tableName);
214 htd = admin.getTableDescriptor(tableName);
215 assertEquals(2, htd.getFamilies().size());
216 assertEquals(2, table.getTableDescriptor().getFamilies().size());
217 assertEquals(500, TEST_UTIL.countRows(table, TEST_FAMILY2));
218 assertEquals(snapshot2Rows, TEST_UTIL.countRows(table));
219 fsFamilies = getFamiliesFromFS(tableName);
220 assertEquals(2, fsFamilies.size());
221 table.close();
222 }
223
224 @Test
225 public void testRestoreSnapshotOfCloned() throws IOException, InterruptedException {
226 TableName clonedTableName =
227 TableName.valueOf("clonedtb-" + System.currentTimeMillis());
228 admin.cloneSnapshot(snapshotName0, clonedTableName);
229 SnapshotTestingUtils.verifyRowCount(TEST_UTIL, clonedTableName, snapshot0Rows);
230 admin.disableTable(clonedTableName);
231 admin.snapshot(snapshotName2, clonedTableName);
232 TEST_UTIL.deleteTable(clonedTableName);
233 waitCleanerRun();
234
235 admin.cloneSnapshot(snapshotName2, clonedTableName);
236 SnapshotTestingUtils.verifyRowCount(TEST_UTIL, clonedTableName, snapshot0Rows);
237 TEST_UTIL.deleteTable(clonedTableName);
238 }
239
240
241
242
243 private void waitCleanerRun() throws InterruptedException {
244 TEST_UTIL.getMiniHBaseCluster().getMaster().getHFileCleaner().choreForTesting();
245 }
246
247 private Set<String> getFamiliesFromFS(final TableName tableName) throws IOException {
248 MasterFileSystem mfs = TEST_UTIL.getMiniHBaseCluster().getMaster().getMasterFileSystem();
249 Set<String> families = new HashSet<String>();
250 Path tableDir = FSUtils.getTableDir(mfs.getRootDir(), tableName);
251 for (Path regionDir: FSUtils.getRegionDirs(mfs.getFileSystem(), tableDir)) {
252 for (Path familyDir: FSUtils.getFamilyDirs(mfs.getFileSystem(), regionDir)) {
253 families.add(familyDir.getName());
254 }
255 }
256 return families;
257 }
258 }