Skip to content

Commit cf1bded

Browse files
xxishuApache9
authored andcommitted
HBASE-28313 StorefileRefresherChore should not refresh readonly table (#5641)
Co-authored-by: sunhao5 <[email protected]> Signed-off-by: Duo Zhang <[email protected]> (cherry picked from commit a997301)
1 parent 7636a2d commit cf1bded

File tree

2 files changed

+58
-4
lines changed

2 files changed

+58
-4
lines changed

Diff for: hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StorefileRefresherChore.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.Map;
2424
import org.apache.hadoop.hbase.ScheduledChore;
2525
import org.apache.hadoop.hbase.Stoppable;
26+
import org.apache.hadoop.hbase.client.RegionInfo;
2627
import org.apache.hadoop.hbase.master.cleaner.TimeToLiveHFileCleaner;
2728
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
2829
import org.apache.hadoop.util.StringUtils;
@@ -81,8 +82,13 @@ public StorefileRefresherChore(int period, boolean onlyMetaRefresh, HRegionServe
8182
@Override
8283
protected void chore() {
8384
for (Region r : regionServer.getOnlineRegionsLocalContext()) {
84-
if (!r.isReadOnly()) {
85-
// skip checking for this region if it can accept writes
85+
if (
86+
!r.isReadOnly() || r.getRegionInfo().getReplicaId() == RegionInfo.DEFAULT_REPLICA_ID
87+
|| r.getTableDescriptor().isReadOnly()
88+
) {
89+
// Skip checking for this region if it can accept writes.
90+
// The refresher is only for refreshing secondary replicas. And if the table is readonly,
91+
// meaning no writes to the primary replica, skip checking the secondary replicas as well.
8692
continue;
8793
}
8894
// don't refresh unless enabled for all files, or it the meta region

Diff for: hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestStoreFileRefresherChore.java

+50-2
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,13 @@ public void setUp() throws IOException {
8181

8282
private TableDescriptor getTableDesc(TableName tableName, int regionReplication,
8383
byte[]... families) {
84-
TableDescriptorBuilder builder =
85-
TableDescriptorBuilder.newBuilder(tableName).setRegionReplication(regionReplication);
84+
return getTableDesc(tableName, regionReplication, false, families);
85+
}
86+
87+
private TableDescriptor getTableDesc(TableName tableName, int regionReplication, boolean readOnly,
88+
byte[]... families) {
89+
TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(tableName)
90+
.setRegionReplication(regionReplication).setReadOnly(readOnly);
8691
Arrays.stream(families).map(family -> ColumnFamilyDescriptorBuilder.newBuilder(family)
8792
.setMaxVersions(Integer.MAX_VALUE).build()).forEachOrdered(builder::setColumnFamily);
8893
return builder.build();
@@ -235,4 +240,47 @@ public void testIsStale() throws IOException {
235240
// expected
236241
}
237242
}
243+
244+
@Test
245+
public void testRefreshReadOnlyTable() throws IOException {
246+
int period = 0;
247+
byte[][] families = new byte[][] { Bytes.toBytes("cf") };
248+
byte[] qf = Bytes.toBytes("cq");
249+
250+
HRegionServer regionServer = mock(HRegionServer.class);
251+
List<HRegion> regions = new ArrayList<>();
252+
when(regionServer.getOnlineRegionsLocalContext()).thenReturn(regions);
253+
when(regionServer.getConfiguration()).thenReturn(TEST_UTIL.getConfiguration());
254+
255+
TableDescriptor htd = getTableDesc(TableName.valueOf(name.getMethodName()), 2, families);
256+
HRegion primary = initHRegion(htd, HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW, 0);
257+
HRegion replica1 = initHRegion(htd, HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW, 1);
258+
regions.add(primary);
259+
regions.add(replica1);
260+
261+
StorefileRefresherChore chore =
262+
new StorefileRefresherChore(period, false, regionServer, new StoppableImplementation());
263+
264+
// write some data to primary and flush
265+
putData(primary, 0, 100, qf, families);
266+
primary.flush(true);
267+
verifyData(primary, 0, 100, qf, families);
268+
269+
verifyDataExpectFail(replica1, 0, 100, qf, families);
270+
chore.chore();
271+
verifyData(replica1, 0, 100, qf, families);
272+
273+
// write some data to primary and flush before refresh the store files for the replica
274+
putData(primary, 100, 100, qf, families);
275+
primary.flush(true);
276+
verifyData(primary, 0, 200, qf, families);
277+
278+
// then the table is set to readonly
279+
htd = getTableDesc(TableName.valueOf(name.getMethodName()), 2, true, families);
280+
primary.setTableDescriptor(htd);
281+
replica1.setTableDescriptor(htd);
282+
283+
chore.chore(); // we cannot refresh the store files
284+
verifyDataExpectFail(replica1, 100, 100, qf, families);
285+
}
238286
}

0 commit comments

Comments
 (0)