3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 package org
.apache
.hadoop
.hbase
.regionserver
;
21 import static org
.apache
.hadoop
.hbase
.HBaseTestingUtility
.COLUMNS
;
22 import static org
.junit
.Assert
.assertEquals
;
23 import static org
.junit
.Assert
.assertTrue
;
25 import java
.util
.ArrayList
;
26 import java
.util
.List
;
28 import org
.apache
.hadoop
.hbase
.Cell
;
29 import org
.apache
.hadoop
.hbase
.CellUtil
;
30 import org
.apache
.hadoop
.hbase
.HBaseTestingUtility
;
31 import org
.apache
.hadoop
.hbase
.HTableDescriptor
;
32 import org
.apache
.hadoop
.hbase
.KeepDeletedCells
;
33 import org
.apache
.hadoop
.hbase
.testclassification
.RegionServerTests
;
34 import org
.apache
.hadoop
.hbase
.testclassification
.SmallTests
;
35 import org
.apache
.hadoop
.hbase
.client
.Delete
;
36 import org
.apache
.hadoop
.hbase
.client
.Get
;
37 import org
.apache
.hadoop
.hbase
.client
.Put
;
38 import org
.apache
.hadoop
.hbase
.client
.Result
;
39 import org
.apache
.hadoop
.hbase
.filter
.TimestampsFilter
;
40 import org
.apache
.hadoop
.hbase
.util
.Bytes
;
41 import org
.apache
.hadoop
.hbase
.util
.EnvironmentEdgeManager
;
42 import org
.junit
.Rule
;
43 import org
.junit
.Test
;
44 import org
.junit
.experimental
.categories
.Category
;
45 import org
.junit
.rules
.TestName
;
48 * Test Minimum Versions feature (HBASE-4071).
50 @Category({RegionServerTests
.class, SmallTests
.class})
51 public class TestMinVersions
{
52 HBaseTestingUtility hbu
= HBaseTestingUtility
.createLocalHTU();
53 private final byte[] T0
= Bytes
.toBytes("0");
54 private final byte[] T1
= Bytes
.toBytes("1");
55 private final byte[] T2
= Bytes
.toBytes("2");
56 private final byte[] T3
= Bytes
.toBytes("3");
57 private final byte[] T4
= Bytes
.toBytes("4");
58 private final byte[] T5
= Bytes
.toBytes("5");
60 private final byte[] c0
= COLUMNS
[0];
62 @Rule public TestName name
= new TestName();
65 * Verify behavior of getClosestBefore(...)
68 public void testGetClosestBefore() throws Exception
{
69 HTableDescriptor htd
=
70 hbu
.createTableDescriptor(name
.getMethodName(), 1, 1000, 1, KeepDeletedCells
.FALSE
);
71 Region region
= hbu
.createLocalHRegion(htd
, null, null);
75 long ts
= EnvironmentEdgeManager
.currentTime() - 2000;
77 Put p
= new Put(T1
, ts
);
78 p
.addColumn(c0
, c0
, T1
);
81 p
= new Put(T1
, ts
+1);
82 p
.addColumn(c0
, c0
, T4
);
86 p
.addColumn(c0
, c0
, T3
);
89 // now make sure that getClosestBefore(...) get can
90 // rows that would be expired without minVersion.
91 // also make sure it gets the latest version
92 Result r
= hbu
.getClosestRowBefore(region
, T1
, c0
);
93 checkResult(r
, c0
, T4
);
95 r
= hbu
.getClosestRowBefore(region
, T2
, c0
);
96 checkResult(r
, c0
, T4
);
100 region
.compact(true);
102 r
= hbu
.getClosestRowBefore(region
, T1
, c0
);
103 checkResult(r
, c0
, T4
);
105 r
= hbu
.getClosestRowBefore(region
, T2
, c0
);
106 checkResult(r
, c0
, T4
);
108 HBaseTestingUtility
.closeRegionAndWAL(region
);
113 * Test mixed memstore and storefile scanning
114 * with minimum versions.
117 public void testStoreMemStore() throws Exception
{
118 // keep 3 versions minimum
119 HTableDescriptor htd
=
120 hbu
.createTableDescriptor(name
.getMethodName(), 3, 1000, 1, KeepDeletedCells
.FALSE
);
121 Region region
= hbu
.createLocalHRegion(htd
, null, null);
123 long ts
= EnvironmentEdgeManager
.currentTime() - 2000;
126 Put p
= new Put(T1
, ts
-1);
127 p
.addColumn(c0
, c0
, T2
);
130 p
= new Put(T1
, ts
-3);
131 p
.addColumn(c0
, c0
, T0
);
136 region
.compact(true);
139 p
.addColumn(c0
, c0
, T3
);
142 p
= new Put(T1
, ts
-2);
143 p
.addColumn(c0
, c0
, T1
);
146 p
= new Put(T1
, ts
-3);
147 p
.addColumn(c0
, c0
, T0
);
150 // newest version in the memstore
151 // the 2nd oldest in the store file
152 // and the 3rd, 4th oldest also in the memstore
156 Result r
= region
.get(g
); // this'll use ScanWildcardColumnTracker
157 checkResult(r
, c0
, T3
,T2
,T1
);
162 r
= region
.get(g
); // this'll use ExplicitColumnTracker
163 checkResult(r
, c0
, T3
,T2
,T1
);
165 HBaseTestingUtility
.closeRegionAndWAL(region
);
170 * Make sure the Deletes behave as expected with minimum versions
173 public void testDelete() throws Exception
{
174 HTableDescriptor htd
=
175 hbu
.createTableDescriptor(name
.getMethodName(), 3, 1000, 1, KeepDeletedCells
.FALSE
);
176 Region region
= hbu
.createLocalHRegion(htd
, null, null);
179 long ts
= EnvironmentEdgeManager
.currentTime() - 2000;
182 Put p
= new Put(T1
, ts
-2);
183 p
.addColumn(c0
, c0
, T1
);
186 p
= new Put(T1
, ts
-1);
187 p
.addColumn(c0
, c0
, T2
);
191 p
.addColumn(c0
, c0
, T3
);
194 Delete d
= new Delete(T1
, ts
-1);
199 Result r
= region
.get(g
); // this'll use ScanWildcardColumnTracker
200 checkResult(r
, c0
, T3
);
205 r
= region
.get(g
); // this'll use ExplicitColumnTracker
206 checkResult(r
, c0
, T3
);
210 region
.compact(true);
215 r
= region
.get(g
); // this'll use ScanWildcardColumnTracker
216 checkResult(r
, c0
, T3
);
221 r
= region
.get(g
); // this'll use ExplicitColumnTracker
222 checkResult(r
, c0
, T3
);
224 HBaseTestingUtility
.closeRegionAndWAL(region
);
229 * Make sure the memstor behaves correctly with minimum versions
232 public void testMemStore() throws Exception
{
233 HTableDescriptor htd
=
234 hbu
.createTableDescriptor(name
.getMethodName(), 2, 1000, 1, KeepDeletedCells
.FALSE
);
235 Region region
= hbu
.createLocalHRegion(htd
, null, null);
238 long ts
= EnvironmentEdgeManager
.currentTime() - 2000;
242 Put p
= new Put(T1
, ts
-2);
243 p
.addColumn(c0
, c0
, T2
);
247 p
= new Put(T1
, ts
-1);
248 p
.addColumn(c0
, c0
, T3
);
253 p
.addColumn(c0
, c0
, T4
);
258 region
.compact(true);
260 // now put the first version (backdated)
261 p
= new Put(T1
, ts
-3);
262 p
.addColumn(c0
, c0
, T1
);
265 // now the latest change is in the memstore,
266 // but it is not the latest version
268 Result r
= region
.get(new Get(T1
));
269 checkResult(r
, c0
, T4
);
273 r
= region
.get(g
); // this'll use ScanWildcardColumnTracker
274 checkResult(r
, c0
, T4
,T3
);
279 r
= region
.get(g
); // this'll use ExplicitColumnTracker
280 checkResult(r
, c0
, T4
,T3
);
282 p
= new Put(T1
, ts
+1);
283 p
.addColumn(c0
, c0
, T5
);
286 // now the latest version is in the memstore
290 r
= region
.get(g
); // this'll use ScanWildcardColumnTracker
291 checkResult(r
, c0
, T5
,T4
);
296 r
= region
.get(g
); // this'll use ExplicitColumnTracker
297 checkResult(r
, c0
, T5
,T4
);
299 HBaseTestingUtility
.closeRegionAndWAL(region
);
304 * Verify basic minimum versions functionality
307 public void testBaseCase() throws Exception
{
308 // 1 version minimum, 1000 versions maximum, ttl = 1s
309 HTableDescriptor htd
=
310 hbu
.createTableDescriptor(name
.getMethodName(), 2, 1000, 1, KeepDeletedCells
.FALSE
);
311 Region region
= hbu
.createLocalHRegion(htd
, null, null);
315 long ts
= EnvironmentEdgeManager
.currentTime() - 2000;
318 Put p
= new Put(T1
, ts
-3);
319 p
.addColumn(c0
, c0
, T1
);
323 p
= new Put(T1
, ts
-2);
324 p
.addColumn(c0
, c0
, T2
);
328 p
= new Put(T1
, ts
-1);
329 p
.addColumn(c0
, c0
, T3
);
334 p
.addColumn(c0
, c0
, T4
);
337 Result r
= region
.get(new Get(T1
));
338 checkResult(r
, c0
, T4
);
341 g
.setTimeRange(0L, ts
+1);
343 checkResult(r
, c0
, T4
);
345 // oldest version still exists
346 g
.setTimeRange(0L, ts
-2);
348 checkResult(r
, c0
, T1
);
350 // gets see only available versions
351 // even before compactions
354 r
= region
.get(g
); // this'll use ScanWildcardColumnTracker
355 checkResult(r
, c0
, T4
,T3
);
360 r
= region
.get(g
); // this'll use ExplicitColumnTracker
361 checkResult(r
, c0
, T4
,T3
);
366 // with HBASE-4241 a flush will eliminate the expired rows
368 g
.setTimeRange(0L, ts
-2);
370 assertTrue(r
.isEmpty());
373 region
.compact(true);
375 // after compaction the 4th version is still available
377 g
.setTimeRange(0L, ts
+1);
379 checkResult(r
, c0
, T4
);
382 g
.setTimeRange(0L, ts
);
384 checkResult(r
, c0
, T3
);
386 // but the 2nd and earlier versions are gone
387 g
.setTimeRange(0L, ts
-1);
389 assertTrue(r
.isEmpty());
391 HBaseTestingUtility
.closeRegionAndWAL(region
);
396 * Verify that basic filters still behave correctly with
397 * minimum versions enabled.
400 public void testFilters() throws Exception
{
401 HTableDescriptor htd
=
402 hbu
.createTableDescriptor(name
.getMethodName(), 2, 1000, 1, KeepDeletedCells
.FALSE
);
403 Region region
= hbu
.createLocalHRegion(htd
, null, null);
404 final byte [] c1
= COLUMNS
[1];
407 long ts
= EnvironmentEdgeManager
.currentTime() - 2000;
410 Put p
= new Put(T1
, ts
-3);
411 p
.addColumn(c0
, c0
, T0
);
412 p
.addColumn(c1
, c1
, T0
);
415 p
= new Put(T1
, ts
-2);
416 p
.addColumn(c0
, c0
, T1
);
417 p
.addColumn(c1
, c1
, T1
);
420 p
= new Put(T1
, ts
-1);
421 p
.addColumn(c0
, c0
, T2
);
422 p
.addColumn(c1
, c1
, T2
);
426 p
.addColumn(c0
, c0
, T3
);
427 p
.addColumn(c1
, c1
, T3
);
430 List
<Long
> tss
= new ArrayList
<>();
436 g
.setFilter(new TimestampsFilter(tss
));
438 Result r
= region
.get(g
);
439 checkResult(r
, c1
, T2
,T1
);
443 g
.setFilter(new TimestampsFilter(tss
));
446 checkResult(r
, c0
, T2
,T1
);
450 region
.compact(true);
454 g
.setFilter(new TimestampsFilter(tss
));
457 checkResult(r
, c1
, T2
);
461 g
.setFilter(new TimestampsFilter(tss
));
464 checkResult(r
, c0
, T2
);
466 HBaseTestingUtility
.closeRegionAndWAL(region
);
470 private void checkResult(Result r
, byte[] col
, byte[] ... vals
) {
471 assertEquals(r
.size(), vals
.length
);
472 List
<Cell
> kvs
= r
.getColumnCells(col
, col
);
473 assertEquals(kvs
.size(), vals
.length
);
474 for (int i
=0;i
<vals
.length
;i
++) {
475 assertTrue(CellUtil
.matchingValue(kvs
.get(i
), vals
[i
]));