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