1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.regionserver.wal;
20
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertNull;
23
24 import java.io.IOException;
25
26 import org.apache.hadoop.conf.Configuration;
27 import org.apache.hadoop.fs.FileSystem;
28 import org.apache.hadoop.fs.Path;
29 import org.apache.hadoop.hbase.HBaseTestingUtility;
30 import org.apache.hadoop.hbase.HColumnDescriptor;
31 import org.apache.hadoop.hbase.HRegionInfo;
32 import org.apache.hadoop.hbase.HTableDescriptor;
33 import org.apache.hadoop.hbase.testclassification.MediumTests;
34 import org.apache.hadoop.hbase.TableName;
35 import org.apache.hadoop.hbase.client.Durability;
36 import org.apache.hadoop.hbase.client.Increment;
37 import org.apache.hadoop.hbase.client.Put;
38 import org.apache.hadoop.hbase.client.Result;
39 import org.apache.hadoop.hbase.regionserver.HRegion;
40 import org.apache.hadoop.hbase.util.Bytes;
41 import org.apache.hadoop.hbase.util.FSUtils;
42 import org.apache.hadoop.hbase.wal.DefaultWALProvider;
43 import org.apache.hadoop.hbase.wal.WAL;
44 import org.apache.hadoop.hbase.wal.WALFactory;
45 import org.apache.hadoop.hdfs.MiniDFSCluster;
46 import org.junit.AfterClass;
47 import org.junit.BeforeClass;
48 import org.junit.Test;
49 import org.junit.experimental.categories.Category;
50
51
52
53
54 @Category(MediumTests.class)
55 public class TestDurability {
56 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
57 private static FileSystem FS;
58 private static MiniDFSCluster CLUSTER;
59 private static Configuration CONF;
60 private static Path DIR;
61
62 private static byte[] FAMILY = Bytes.toBytes("family");
63 private static byte[] ROW = Bytes.toBytes("row");
64 private static byte[] COL = Bytes.toBytes("col");
65
66
67 @BeforeClass
68 public static void setUpBeforeClass() throws Exception {
69 CONF = TEST_UTIL.getConfiguration();
70 TEST_UTIL.startMiniDFSCluster(1);
71
72 CLUSTER = TEST_UTIL.getDFSCluster();
73 FS = CLUSTER.getFileSystem();
74 DIR = TEST_UTIL.getDataTestDirOnTestFS("TestDurability");
75 FSUtils.setRootDir(CONF, DIR);
76 }
77
78 @AfterClass
79 public static void tearDownAfterClass() throws Exception {
80 TEST_UTIL.shutdownMiniCluster();
81 }
82
83 @Test
84 public void testDurability() throws Exception {
85 final WALFactory wals = new WALFactory(CONF, null, "TestDurability");
86 byte[] tableName = Bytes.toBytes("TestDurability");
87 final WAL wal = wals.getWAL(tableName, null);
88 HRegion region = createHRegion(tableName, "region", wal, Durability.USE_DEFAULT);
89 HRegion deferredRegion = createHRegion(tableName, "deferredRegion", wal, Durability.ASYNC_WAL);
90
91 region.put(newPut(null));
92 verifyWALCount(wals, wal, 1);
93
94
95
96
97 deferredRegion.put(newPut(null));
98
99 wal.sync();
100 verifyWALCount(wals, wal, 2);
101
102
103 deferredRegion.put(newPut(null));
104 wal.sync();
105 verifyWALCount(wals, wal, 3);
106 region.put(newPut(null));
107 verifyWALCount(wals, wal, 4);
108
109
110 deferredRegion.put(newPut(Durability.USE_DEFAULT));
111 wal.sync();
112 verifyWALCount(wals, wal, 5);
113 region.put(newPut(Durability.USE_DEFAULT));
114 verifyWALCount(wals, wal, 6);
115
116
117 region.put(newPut(Durability.SKIP_WAL));
118 deferredRegion.put(newPut(Durability.SKIP_WAL));
119 verifyWALCount(wals, wal, 6);
120 wal.sync();
121 verifyWALCount(wals, wal, 6);
122
123
124 region.put(newPut(Durability.ASYNC_WAL));
125 deferredRegion.put(newPut(Durability.ASYNC_WAL));
126 wal.sync();
127 verifyWALCount(wals, wal, 8);
128
129
130 region.put(newPut(Durability.SYNC_WAL));
131 deferredRegion.put(newPut(Durability.SYNC_WAL));
132 verifyWALCount(wals, wal, 10);
133
134
135 region.put(newPut(Durability.FSYNC_WAL));
136 deferredRegion.put(newPut(Durability.FSYNC_WAL));
137 verifyWALCount(wals, wal, 12);
138 }
139
140 @Test
141 public void testIncrement() throws Exception {
142 byte[] row1 = Bytes.toBytes("row1");
143 byte[] col1 = Bytes.toBytes("col1");
144 byte[] col2 = Bytes.toBytes("col2");
145 byte[] col3 = Bytes.toBytes("col3");
146
147
148 final WALFactory wals = new WALFactory(CONF, null, "TestIncrement");
149 byte[] tableName = Bytes.toBytes("TestIncrement");
150 final WAL wal = wals.getWAL(tableName, null);
151 HRegion region = createHRegion(tableName, "increment", wal, Durability.USE_DEFAULT);
152
153
154 Increment inc1 = new Increment(row1);
155 inc1.addColumn(FAMILY, col1, 0);
156 Result res = region.increment(inc1);
157 assertEquals(1, res.size());
158 assertEquals(0, Bytes.toLong(res.getValue(FAMILY, col1)));
159 verifyWALCount(wals, wal, 1);
160
161
162 inc1 = new Increment(row1);
163 inc1.addColumn(FAMILY, col1, 1);
164 res = region.increment(inc1);
165 assertEquals(1, res.size());
166 assertEquals(1, Bytes.toLong(res.getValue(FAMILY, col1)));
167 verifyWALCount(wals, wal, 2);
168
169
170 inc1 = new Increment(row1);
171 inc1.addColumn(FAMILY, col1, 0);
172 res = region.increment(inc1);
173 assertEquals(1, res.size());
174 assertEquals(1, Bytes.toLong(res.getValue(FAMILY, col1)));
175 verifyWALCount(wals, wal, 2);
176
177
178
179 inc1 = new Increment(row1);
180 inc1.addColumn(FAMILY, col1, 0);
181 inc1.addColumn(FAMILY, col2, 0);
182 inc1.addColumn(FAMILY, col3, 0);
183 res = region.increment(inc1);
184 assertEquals(3, res.size());
185 assertEquals(1, Bytes.toLong(res.getValue(FAMILY, col1)));
186 assertEquals(0, Bytes.toLong(res.getValue(FAMILY, col2)));
187 assertEquals(0, Bytes.toLong(res.getValue(FAMILY, col3)));
188 verifyWALCount(wals, wal, 3);
189
190
191
192 inc1 = new Increment(row1);
193 inc1.addColumn(FAMILY, col1, 5);
194 inc1.addColumn(FAMILY, col2, 4);
195 inc1.addColumn(FAMILY, col3, 3);
196 res = region.increment(inc1);
197 assertEquals(3, res.size());
198 assertEquals(6, Bytes.toLong(res.getValue(FAMILY, col1)));
199 assertEquals(4, Bytes.toLong(res.getValue(FAMILY, col2)));
200 assertEquals(3, Bytes.toLong(res.getValue(FAMILY, col3)));
201 verifyWALCount(wals, wal, 4);
202 }
203
204
205
206
207
208 @Test
209 public void testIncrementWithReturnResultsSetToFalse() throws Exception {
210 byte[] row1 = Bytes.toBytes("row1");
211 byte[] col1 = Bytes.toBytes("col1");
212
213
214 final WALFactory wals = new WALFactory(CONF, null, "testIncrementWithReturnResultsSetToFalse");
215 byte[] tableName = Bytes.toBytes("testIncrementWithReturnResultsSetToFalse");
216 final WAL wal = wals.getWAL(tableName, null);
217 HRegion region = createHRegion(tableName, "increment", wal, Durability.USE_DEFAULT);
218
219 Increment inc1 = new Increment(row1);
220 inc1.setReturnResults(false);
221 inc1.addColumn(FAMILY, col1, 1);
222 Result res = region.increment(inc1);
223 assertNull(res);
224 }
225
226 private Put newPut(Durability durability) {
227 Put p = new Put(ROW);
228 p.add(FAMILY, COL, COL);
229 if (durability != null) {
230 p.setDurability(durability);
231 }
232 return p;
233 }
234
235 private void verifyWALCount(WALFactory wals, WAL log, int expected) throws Exception {
236 Path walPath = DefaultWALProvider.getCurrentFileName(log);
237 WAL.Reader reader = wals.createReader(FS, walPath);
238 int count = 0;
239 WAL.Entry entry = new WAL.Entry();
240 while (reader.next(entry) != null) count++;
241 reader.close();
242 assertEquals(expected, count);
243 }
244
245
246 private HRegion createHRegion (byte [] tableName, String callingMethod,
247 WAL log, Durability durability)
248 throws IOException {
249 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(tableName));
250 htd.setDurability(durability);
251 HColumnDescriptor hcd = new HColumnDescriptor(FAMILY);
252 htd.addFamily(hcd);
253 HRegionInfo info = new HRegionInfo(htd.getTableName(), null, null, false);
254 Path path = new Path(DIR + callingMethod);
255 if (FS.exists(path)) {
256 if (!FS.delete(path, true)) {
257 throw new IOException("Failed delete of " + path);
258 }
259 }
260 return HRegion.createHRegion(info, path, CONF, htd, log);
261 }
262
263 }