1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.snapshot;
19
20 import java.io.IOException;
21
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24 import org.apache.hadoop.hbase.HBaseTestingUtility;
25 import org.apache.hadoop.hbase.HConstants;
26 import org.apache.hadoop.hbase.testclassification.LargeTests;
27 import org.apache.hadoop.hbase.TableName;
28 import org.apache.hadoop.hbase.client.HBaseAdmin;
29 import org.apache.hadoop.hbase.client.HTable;
30 import org.apache.hadoop.hbase.master.MasterFileSystem;
31 import org.apache.hadoop.hbase.master.snapshot.SnapshotManager;
32 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
33 import org.apache.hadoop.hbase.regionserver.snapshot.RegionServerSnapshotManager;
34 import org.apache.hadoop.hbase.util.Bytes;
35 import org.apache.hadoop.hbase.util.FSUtils;
36 import org.junit.After;
37 import org.junit.AfterClass;
38 import org.junit.Before;
39 import org.junit.BeforeClass;
40 import org.junit.Test;
41 import org.junit.experimental.categories.Category;
42
43
44
45
46
47
48
49 @Category(LargeTests.class)
50 public class TestRestoreFlushSnapshotFromClient {
51 final Log LOG = LogFactory.getLog(getClass());
52
53 private final static HBaseTestingUtility UTIL = new HBaseTestingUtility();
54
55 private final byte[] FAMILY = Bytes.toBytes("cf");
56
57 private byte[] snapshotName0;
58 private byte[] snapshotName1;
59 private byte[] snapshotName2;
60 private int snapshot0Rows;
61 private int snapshot1Rows;
62 private TableName tableName;
63 private HBaseAdmin admin;
64
65 @BeforeClass
66 public static void setUpBeforeClass() throws Exception {
67 UTIL.getConfiguration().setBoolean("hbase.online.schema.update.enable", true);
68 UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
69 UTIL.getConfiguration().setInt("hbase.client.pause", 250);
70 UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 6);
71 UTIL.getConfiguration().setBoolean(
72 "hbase.master.enabletable.roundrobin", true);
73
74
75 UTIL.getConfiguration().setBoolean(SnapshotManager.HBASE_SNAPSHOT_ENABLED, true);
76 UTIL.getConfiguration().setLong(RegionServerSnapshotManager.SNAPSHOT_TIMEOUT_MILLIS_KEY,
77 RegionServerSnapshotManager.SNAPSHOT_TIMEOUT_MILLIS_DEFAULT * 2);
78
79 UTIL.startMiniCluster(3);
80 }
81
82 @AfterClass
83 public static void tearDownAfterClass() throws Exception {
84 UTIL.shutdownMiniCluster();
85 }
86
87
88
89
90
91
92 @Before
93 public void setup() throws Exception {
94 this.admin = UTIL.getHBaseAdmin();
95
96 long tid = System.currentTimeMillis();
97 tableName = TableName.valueOf("testtb-" + tid);
98 snapshotName0 = Bytes.toBytes("snaptb0-" + tid);
99 snapshotName1 = Bytes.toBytes("snaptb1-" + tid);
100 snapshotName2 = Bytes.toBytes("snaptb2-" + tid);
101
102
103 SnapshotTestingUtils.createTable(UTIL, tableName, FAMILY);
104 HTable table = new HTable(UTIL.getConfiguration(), tableName);
105 SnapshotTestingUtils.loadData(UTIL, table, 500, FAMILY);
106 snapshot0Rows = UTIL.countRows(table);
107 LOG.info("=== before snapshot with 500 rows");
108 logFSTree();
109
110
111 admin.snapshot(Bytes.toString(snapshotName0), tableName,
112 SnapshotDescription.Type.FLUSH);
113
114 LOG.info("=== after snapshot with 500 rows");
115 logFSTree();
116
117
118 SnapshotTestingUtils.loadData(UTIL, table, 500, FAMILY);
119 snapshot1Rows = UTIL.countRows(table);
120 LOG.info("=== before snapshot with 1000 rows");
121 logFSTree();
122
123
124 admin.snapshot(Bytes.toString(snapshotName1), tableName,
125 SnapshotDescription.Type.FLUSH);
126 LOG.info("=== after snapshot with 1000 rows");
127 logFSTree();
128 table.close();
129 }
130
131 @After
132 public void tearDown() throws Exception {
133 SnapshotTestingUtils.deleteAllSnapshots(UTIL.getHBaseAdmin());
134 SnapshotTestingUtils.deleteArchiveDirectory(UTIL);
135 }
136
137 @Test
138 public void testTakeFlushSnapshot() throws IOException {
139
140 }
141
142 @Test
143 public void testRestoreSnapshot() throws IOException {
144 SnapshotTestingUtils.verifyRowCount(UTIL, tableName, snapshot1Rows);
145
146
147 admin.disableTable(tableName);
148 admin.restoreSnapshot(snapshotName0);
149 logFSTree();
150 admin.enableTable(tableName);
151 LOG.info("=== after restore with 500 row snapshot");
152 logFSTree();
153 SnapshotTestingUtils.verifyRowCount(UTIL, tableName, snapshot0Rows);
154
155
156 admin.disableTable(tableName);
157 admin.restoreSnapshot(snapshotName1);
158 admin.enableTable(tableName);
159 SnapshotTestingUtils.verifyRowCount(UTIL, tableName, snapshot1Rows);
160 }
161
162 @Test(expected=SnapshotDoesNotExistException.class)
163 public void testCloneNonExistentSnapshot() throws IOException, InterruptedException {
164 String snapshotName = "random-snapshot-" + System.currentTimeMillis();
165 String tableName = "random-table-" + System.currentTimeMillis();
166 admin.cloneSnapshot(snapshotName, tableName);
167 }
168
169 @Test
170 public void testCloneSnapshot() throws IOException, InterruptedException {
171 TableName clonedTableName = TableName.valueOf("clonedtb-" + System.currentTimeMillis());
172 testCloneSnapshot(clonedTableName, snapshotName0, snapshot0Rows);
173 testCloneSnapshot(clonedTableName, snapshotName1, snapshot1Rows);
174 }
175
176 private void testCloneSnapshot(final TableName tableName, final byte[] snapshotName,
177 int snapshotRows) throws IOException, InterruptedException {
178
179 admin.cloneSnapshot(snapshotName, tableName);
180 SnapshotTestingUtils.verifyRowCount(UTIL, tableName, snapshotRows);
181
182 UTIL.deleteTable(tableName);
183 }
184
185 @Test
186 public void testRestoreSnapshotOfCloned() throws IOException, InterruptedException {
187 TableName clonedTableName = TableName.valueOf("clonedtb-" + System.currentTimeMillis());
188 admin.cloneSnapshot(snapshotName0, clonedTableName);
189 SnapshotTestingUtils.verifyRowCount(UTIL, clonedTableName, snapshot0Rows);
190 admin.snapshot(Bytes.toString(snapshotName2), clonedTableName, SnapshotDescription.Type.FLUSH);
191 UTIL.deleteTable(clonedTableName);
192
193 admin.cloneSnapshot(snapshotName2, clonedTableName);
194 SnapshotTestingUtils.verifyRowCount(UTIL, clonedTableName, snapshot0Rows);
195 UTIL.deleteTable(clonedTableName);
196 }
197
198
199
200
201 private void logFSTree() throws IOException {
202 MasterFileSystem mfs = UTIL.getMiniHBaseCluster().getMaster().getMasterFileSystem();
203 FSUtils.logFileSystemState(mfs.getFileSystem(), mfs.getRootDir(), LOG);
204 }
205 }