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