001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.regionserver.wal; 019 020import static org.junit.Assert.assertFalse; 021import static org.junit.Assert.assertNull; 022import static org.junit.Assert.assertTrue; 023 024import java.io.IOException; 025import org.apache.hadoop.conf.Configuration; 026import org.apache.hadoop.fs.FileSystem; 027import org.apache.hadoop.fs.Path; 028import org.apache.hadoop.hbase.HBaseTestingUtil; 029import org.apache.hadoop.hbase.TableName; 030import org.apache.hadoop.hbase.client.Durability; 031import org.apache.hadoop.hbase.client.Put; 032import org.apache.hadoop.hbase.regionserver.ChunkCreator; 033import org.apache.hadoop.hbase.regionserver.HRegion; 034import org.apache.hadoop.hbase.regionserver.MemStoreLAB; 035import org.apache.hadoop.hbase.util.Bytes; 036import org.apache.hadoop.hbase.wal.WAL; 037import org.junit.After; 038import org.junit.Before; 039import org.junit.Rule; 040import org.junit.Test; 041import org.junit.rules.TestName; 042 043/** 044 * Tests for WAL write durability - hflush vs hsync 045 */ 046public abstract class WALDurabilityTestBase<T extends WAL> { 047 048 private static final String COLUMN_FAMILY = "MyCF"; 049 private static final byte[] COLUMN_FAMILY_BYTES = Bytes.toBytes(COLUMN_FAMILY); 050 051 private final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil(); 052 private Configuration conf; 053 private String dir; 054 @Rule 055 public TestName name = new TestName(); 056 057 // Test names 058 protected TableName tableName; 059 060 @Before 061 public void setUp() throws IOException { 062 conf = TEST_UTIL.getConfiguration(); 063 dir = TEST_UTIL.getDataTestDir("TestHRegion").toString(); 064 tableName = TableName.valueOf(name.getMethodName()); 065 } 066 067 @After 068 public void tearDown() throws IOException { 069 TEST_UTIL.cleanupTestDir(); 070 } 071 072 protected final T getWAL(FileSystem fs, Path root, String logDir, Configuration conf) 073 throws IOException { 074 fs.mkdirs(new Path(root, logDir)); 075 return getWAL0(fs, root, logDir, conf); 076 } 077 078 protected abstract T getWAL0(FileSystem fs, Path root, String logDir, Configuration conf) 079 throws IOException; 080 081 protected abstract void resetSyncFlag(T wal); 082 083 protected abstract Boolean getSyncFlag(T wal); 084 085 protected abstract Boolean getWriterSyncFlag(T wal); 086 087 @Test 088 public void testWALDurability() throws IOException { 089 byte[] bytes = Bytes.toBytes(getName()); 090 Put put = new Put(bytes); 091 put.addColumn(COLUMN_FAMILY_BYTES, Bytes.toBytes("1"), bytes); 092 093 // global hbase.wal.hsync false, no override in put call - hflush 094 conf.set(HRegion.WAL_HSYNC_CONF_KEY, "false"); 095 FileSystem fs = FileSystem.get(conf); 096 Path rootDir = new Path(dir + getName()); 097 T wal = getWAL(fs, rootDir, getName(), conf); 098 HRegion region = initHRegion(tableName, null, null, conf, wal); 099 try { 100 resetSyncFlag(wal); 101 assertNull(getSyncFlag(wal)); 102 assertNull(getWriterSyncFlag(wal)); 103 region.put(put); 104 assertFalse(getSyncFlag(wal)); 105 assertFalse(getWriterSyncFlag(wal)); 106 107 // global hbase.wal.hsync false, durability set in put call - fsync 108 put.setDurability(Durability.FSYNC_WAL); 109 resetSyncFlag(wal); 110 assertNull(getSyncFlag(wal)); 111 assertNull(getWriterSyncFlag(wal)); 112 region.put(put); 113 assertTrue(getSyncFlag(wal)); 114 assertTrue(getWriterSyncFlag(wal)); 115 } finally { 116 HBaseTestingUtil.closeRegionAndWAL(region); 117 } 118 119 // global hbase.wal.hsync true, no override in put call 120 conf.set(HRegion.WAL_HSYNC_CONF_KEY, "true"); 121 fs = FileSystem.get(conf); 122 wal = getWAL(fs, rootDir, getName(), conf); 123 region = initHRegion(tableName, null, null, conf, wal); 124 125 try { 126 resetSyncFlag(wal); 127 assertNull(getSyncFlag(wal)); 128 assertNull(getWriterSyncFlag(wal)); 129 region.put(put); 130 assertTrue(getSyncFlag(wal)); 131 assertTrue(getWriterSyncFlag(wal)); 132 133 // global hbase.wal.hsync true, durability set in put call - fsync 134 put.setDurability(Durability.FSYNC_WAL); 135 resetSyncFlag(wal); 136 assertNull(getSyncFlag(wal)); 137 assertNull(getWriterSyncFlag(wal)); 138 region.put(put); 139 assertTrue(getSyncFlag(wal)); 140 assertTrue(getWriterSyncFlag(wal)); 141 142 // global hbase.wal.hsync true, durability set in put call - sync 143 put = new Put(bytes); 144 put.addColumn(COLUMN_FAMILY_BYTES, Bytes.toBytes("1"), bytes); 145 put.setDurability(Durability.SYNC_WAL); 146 resetSyncFlag(wal); 147 assertNull(getSyncFlag(wal)); 148 assertNull(getWriterSyncFlag(wal)); 149 region.put(put); 150 assertFalse(getSyncFlag(wal)); 151 assertFalse(getWriterSyncFlag(wal)); 152 } finally { 153 HBaseTestingUtil.closeRegionAndWAL(region); 154 } 155 } 156 157 private String getName() { 158 return name.getMethodName(); 159 } 160 161 /** 162 * @return A region on which you must call {@link HBaseTestingUtil#closeRegionAndWAL(HRegion)} 163 * when done. 164 */ 165 public static HRegion initHRegion(TableName tableName, byte[] startKey, byte[] stopKey, 166 Configuration conf, WAL wal) throws IOException { 167 ChunkCreator.initialize(MemStoreLAB.CHUNK_SIZE_DEFAULT, false, 0, 0, 0, null, 168 MemStoreLAB.INDEX_CHUNK_SIZE_PERCENTAGE_DEFAULT); 169 return TEST_UTIL.createLocalHRegion(tableName, startKey, stopKey, conf, false, 170 Durability.USE_DEFAULT, wal, COLUMN_FAMILY_BYTES); 171 } 172}