1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.regionserver.wal;
19
20 import static org.junit.Assert.assertTrue;
21 import static org.junit.Assert.assertFalse;
22
23 import java.util.List;
24 import java.util.ArrayList;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.hadoop.fs.Path;
29 import org.apache.hadoop.hbase.HBaseTestingUtility;
30 import org.apache.hadoop.hbase.HRegionInfo;
31 import org.apache.hadoop.hbase.HTableDescriptor;
32 import org.apache.hadoop.hbase.testclassification.MediumTests;
33 import org.apache.hadoop.hbase.client.HTable;
34 import org.apache.hadoop.hbase.client.Put;
35 import org.apache.hadoop.hbase.regionserver.HRegionServer;
36 import org.apache.hadoop.hbase.util.Bytes;
37 import org.junit.AfterClass;
38 import org.junit.BeforeClass;
39 import org.junit.Test;
40 import org.junit.experimental.categories.Category;
41
42
43
44
45 @Category(MediumTests.class)
46 public class TestLogRollPeriod {
47 private static final Log LOG = LogFactory.getLog(TestLogRolling.class);
48
49 private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
50
51 private final static long LOG_ROLL_PERIOD = 4000;
52
53 @BeforeClass
54 public static void setUpBeforeClass() throws Exception {
55
56 TEST_UTIL.getConfiguration().setInt("hbase.regionsever.info.port", -1);
57
58 TEST_UTIL.getConfiguration().setLong("hbase.regionserver.logroll.period", LOG_ROLL_PERIOD);
59
60 TEST_UTIL.startMiniCluster();
61 }
62
63 @AfterClass
64 public static void tearDownAfterClass() throws Exception {
65 TEST_UTIL.shutdownMiniCluster();
66 }
67
68
69
70
71 @Test
72 public void testNoEdits() throws Exception {
73 final String tableName = "TestLogRollPeriodNoEdits";
74
75 TEST_UTIL.createTable(tableName, "cf");
76 try {
77 HTable table = new HTable(TEST_UTIL.getConfiguration(), tableName);
78 try {
79 HRegionServer server = TEST_UTIL.getRSForFirstRegionInTable(Bytes.toBytes(tableName));
80 HLog log = server.getWAL();
81 checkMinLogRolls(log, 5);
82 } finally {
83 table.close();
84 }
85 } finally {
86 TEST_UTIL.deleteTable(tableName);
87 }
88 }
89
90
91
92
93 @Test(timeout=60000)
94 public void testWithEdits() throws Exception {
95 final String tableName = "TestLogRollPeriodWithEdits";
96 final String family = "cf";
97
98 TEST_UTIL.createTable(tableName, family);
99 try {
100 HRegionServer server = TEST_UTIL.getRSForFirstRegionInTable(Bytes.toBytes(tableName));
101 HLog log = server.getWAL();
102 final HTable table = new HTable(TEST_UTIL.getConfiguration(), tableName);
103
104 Thread writerThread = new Thread("writer") {
105 @Override
106 public void run() {
107 try {
108 long row = 0;
109 while (!interrupted()) {
110 Put p = new Put(Bytes.toBytes(String.format("row%d", row)));
111 p.add(Bytes.toBytes(family), Bytes.toBytes("col"), Bytes.toBytes(row));
112 table.put(p);
113 row++;
114
115 Thread.sleep(LOG_ROLL_PERIOD / 16);
116 }
117 } catch (Exception e) {
118 LOG.warn(e);
119 }
120 }
121 };
122
123 try {
124 writerThread.start();
125 checkMinLogRolls(log, 5);
126 } finally {
127 writerThread.interrupt();
128 writerThread.join();
129 table.close();
130 }
131 } finally {
132 TEST_UTIL.deleteTable(tableName);
133 }
134 }
135
136 private void checkMinLogRolls(final HLog log, final int minRolls)
137 throws Exception {
138 final List<Path> paths = new ArrayList<Path>();
139 log.registerWALActionsListener(new WALActionsListener() {
140 @Override
141 public void preLogRoll(Path oldFile, Path newFile) {}
142 @Override
143 public void postLogRoll(Path oldFile, Path newFile) {
144 LOG.debug("postLogRoll: oldFile="+oldFile+" newFile="+newFile);
145 paths.add(newFile);
146 }
147 @Override
148 public void preLogArchive(Path oldFile, Path newFile) {}
149 @Override
150 public void postLogArchive(Path oldFile, Path newFile) {}
151 @Override
152 public void logRollRequested(boolean tooFewReplicas) {}
153 @Override
154 public void logCloseRequested() {}
155 @Override
156 public void visitLogEntryBeforeWrite(HRegionInfo info, HLogKey logKey, WALEdit logEdit) {}
157 @Override
158 public void visitLogEntryBeforeWrite(HTableDescriptor htd, HLogKey logKey, WALEdit logEdit) {}
159 });
160
161
162 long wtime = System.currentTimeMillis();
163 Thread.sleep((minRolls + 1) * LOG_ROLL_PERIOD);
164
165
166 final int NUM_RETRIES = 1 + 8 * (minRolls - paths.size());
167 for (int retry = 0; paths.size() < minRolls && retry < NUM_RETRIES; ++retry) {
168 Thread.sleep(LOG_ROLL_PERIOD / 4);
169 }
170 wtime = System.currentTimeMillis() - wtime;
171 LOG.info(String.format("got %d rolls after %dms (%dms each) - expected at least %d rolls",
172 paths.size(), wtime, wtime / paths.size(), minRolls));
173 assertFalse(paths.size() < minRolls);
174 }
175 }