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