HBASE-20817 Infinite loop when executing ReopenTableRegionsProcedure
Signed-off-by: zhangduo <zhangduo@apache.org>
This commit is contained in:
parent
7c5188f39e
commit
cfdabe9267
|
@ -66,9 +66,11 @@ public class MoveRegionProcedure extends AbstractStateMachineRegionProcedure<Mov
|
||||||
throws HBaseIOException {
|
throws HBaseIOException {
|
||||||
super(env, plan.getRegionInfo());
|
super(env, plan.getRegionInfo());
|
||||||
this.plan = plan;
|
this.plan = plan;
|
||||||
|
if (check) {
|
||||||
preflightChecks(env, true);
|
preflightChecks(env, true);
|
||||||
checkOnline(env, plan.getRegionInfo());
|
checkOnline(env, plan.getRegionInfo());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Flow executeFromState(final MasterProcedureEnv env, final MoveRegionState state)
|
protected Flow executeFromState(final MasterProcedureEnv env, final MoveRegionState state)
|
||||||
|
@ -135,7 +137,7 @@ public class MoveRegionProcedure extends AbstractStateMachineRegionProcedure<Mov
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MoveRegionState getState(final int stateId) {
|
protected MoveRegionState getState(final int stateId) {
|
||||||
return MoveRegionState.valueOf(stateId);
|
return MoveRegionState.forNumber(stateId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -974,8 +974,11 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
|
||||||
long maxSeqIdFromFile =
|
long maxSeqIdFromFile =
|
||||||
WALSplitter.getMaxRegionSequenceId(fs.getFileSystem(), fs.getRegionDir());
|
WALSplitter.getMaxRegionSequenceId(fs.getFileSystem(), fs.getRegionDir());
|
||||||
long nextSeqId = Math.max(maxSeqId, maxSeqIdFromFile) + 1;
|
long nextSeqId = Math.max(maxSeqId, maxSeqIdFromFile) + 1;
|
||||||
if (writestate.writesEnabled) {
|
// The openSeqNum will always be increase even for read only region, as we rely on it to
|
||||||
LOG.debug("writing seq id for " + this.getRegionInfo().getEncodedName());
|
// determine whether a region has been successfully reopend, so here we always need to update
|
||||||
|
// the max sequence id file.
|
||||||
|
if (RegionReplicaUtil.isDefaultReplica(getRegionInfo())) {
|
||||||
|
LOG.debug("writing seq id for {}", this.getRegionInfo().getEncodedName());
|
||||||
WALSplitter.writeRegionSequenceIdFile(fs.getFileSystem(), fs.getRegionDir(), nextSeqId - 1);
|
WALSplitter.writeRegionSequenceIdFile(fs.getFileSystem(), fs.getRegionDir(), nextSeqId - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1657,7 +1660,10 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
|
||||||
}
|
}
|
||||||
|
|
||||||
status.setStatus("Writing region close event to WAL");
|
status.setStatus("Writing region close event to WAL");
|
||||||
if (!abort && wal != null && getRegionServerServices() != null && !writestate.readOnly) {
|
// Always write close marker to wal even for read only table. This is not a big problem as we
|
||||||
|
// do not write any data into the region.
|
||||||
|
if (!abort && wal != null && getRegionServerServices() != null &&
|
||||||
|
RegionReplicaUtil.isDefaultReplica(getRegionInfo())) {
|
||||||
writeRegionCloseMarker(wal);
|
writeRegionCloseMarker(wal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7050,7 +7056,6 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
|
||||||
* HRegion#getMinSequenceId() to ensure the wal id is properly kept
|
* HRegion#getMinSequenceId() to ensure the wal id is properly kept
|
||||||
* up. HRegionStore does this every time it opens a new region.
|
* up. HRegionStore does this every time it opens a new region.
|
||||||
* @return new HRegion
|
* @return new HRegion
|
||||||
* @throws IOException
|
|
||||||
*/
|
*/
|
||||||
public static HRegion openHRegion(final Configuration conf, final FileSystem fs,
|
public static HRegion openHRegion(final Configuration conf, final FileSystem fs,
|
||||||
final Path rootDir, final RegionInfo info, final TableDescriptor htd, final WAL wal)
|
final Path rootDir, final RegionInfo info, final TableDescriptor htd, final WAL wal)
|
||||||
|
@ -7072,7 +7077,6 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
|
||||||
* @param rsServices An interface we can request flushes against.
|
* @param rsServices An interface we can request flushes against.
|
||||||
* @param reporter An interface we can report progress against.
|
* @param reporter An interface we can report progress against.
|
||||||
* @return new HRegion
|
* @return new HRegion
|
||||||
* @throws IOException
|
|
||||||
*/
|
*/
|
||||||
public static HRegion openHRegion(final Configuration conf, final FileSystem fs,
|
public static HRegion openHRegion(final Configuration conf, final FileSystem fs,
|
||||||
final Path rootDir, final RegionInfo info, final TableDescriptor htd, final WAL wal,
|
final Path rootDir, final RegionInfo info, final TableDescriptor htd, final WAL wal,
|
||||||
|
@ -7096,7 +7100,6 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
|
||||||
* @param rsServices An interface we can request flushes against.
|
* @param rsServices An interface we can request flushes against.
|
||||||
* @param reporter An interface we can report progress against.
|
* @param reporter An interface we can report progress against.
|
||||||
* @return new HRegion
|
* @return new HRegion
|
||||||
* @throws IOException
|
|
||||||
*/
|
*/
|
||||||
public static HRegion openHRegion(final Configuration conf, final FileSystem fs,
|
public static HRegion openHRegion(final Configuration conf, final FileSystem fs,
|
||||||
final Path rootDir, final Path tableDir, final RegionInfo info, final TableDescriptor htd,
|
final Path rootDir, final Path tableDir, final RegionInfo info, final TableDescriptor htd,
|
||||||
|
@ -7121,7 +7124,6 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
|
||||||
* @param other original object
|
* @param other original object
|
||||||
* @param reporter An interface we can report progress against.
|
* @param reporter An interface we can report progress against.
|
||||||
* @return new HRegion
|
* @return new HRegion
|
||||||
* @throws IOException
|
|
||||||
*/
|
*/
|
||||||
public static HRegion openHRegion(final HRegion other, final CancelableProgressable reporter)
|
public static HRegion openHRegion(final HRegion other, final CancelableProgressable reporter)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
@ -7154,8 +7156,11 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
|
||||||
checkClassLoading();
|
checkClassLoading();
|
||||||
this.openSeqNum = initialize(reporter);
|
this.openSeqNum = initialize(reporter);
|
||||||
this.mvcc.advanceTo(openSeqNum);
|
this.mvcc.advanceTo(openSeqNum);
|
||||||
if (wal != null && getRegionServerServices() != null && !writestate.readOnly) {
|
// The openSeqNum must be increased every time when a region is assigned, as we rely on it to
|
||||||
// Only write the region open event marker to WAL if we are not read-only.
|
// determine whether a region has been successfully reopened. So here we always write open
|
||||||
|
// marker, even if the table is read only.
|
||||||
|
if (wal != null && getRegionServerServices() != null &&
|
||||||
|
RegionReplicaUtil.isDefaultReplica(getRegionInfo())) {
|
||||||
writeRegionOpenMarker(wal, openSeqNum);
|
writeRegionOpenMarker(wal, openSeqNum);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
|
@ -7168,7 +7173,6 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
|
||||||
* @param info Info for region to be opened.
|
* @param info Info for region to be opened.
|
||||||
* @param htd the table descriptor
|
* @param htd the table descriptor
|
||||||
* @return new HRegion
|
* @return new HRegion
|
||||||
* @throws IOException e
|
|
||||||
*/
|
*/
|
||||||
public static HRegion openReadOnlyFileSystemHRegion(final Configuration conf, final FileSystem fs,
|
public static HRegion openReadOnlyFileSystemHRegion(final Configuration conf, final FileSystem fs,
|
||||||
final Path tableDir, RegionInfo info, final TableDescriptor htd) throws IOException {
|
final Path tableDir, RegionInfo info, final TableDescriptor htd) throws IOException {
|
||||||
|
|
|
@ -31,7 +31,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import org.apache.hadoop.hbase.HBaseClassTestRule;
|
import org.apache.hadoop.hbase.HBaseClassTestRule;
|
||||||
import org.apache.hadoop.hbase.HBaseTestingUtility;
|
import org.apache.hadoop.hbase.HBaseTestingUtility;
|
||||||
import org.apache.hadoop.hbase.HColumnDescriptor;
|
import org.apache.hadoop.hbase.HColumnDescriptor;
|
||||||
|
@ -69,6 +68,7 @@ import org.junit.experimental.categories.Category;
|
||||||
import org.junit.rules.TestName;
|
import org.junit.rules.TestName;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import org.apache.hadoop.hbase.shaded.protobuf.RequestConverter;
|
import org.apache.hadoop.hbase.shaded.protobuf.RequestConverter;
|
||||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MergeTableRegionsRequest;
|
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MergeTableRegionsRequest;
|
||||||
|
|
||||||
|
@ -500,10 +500,31 @@ public class TestAdmin1 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify schema change for read only table
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testReadOnlyTableModify() throws IOException, InterruptedException {
|
||||||
|
final TableName tableName = TableName.valueOf(name.getMethodName());
|
||||||
|
TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
|
||||||
|
|
||||||
|
// Make table read only
|
||||||
|
TableDescriptor htd = TableDescriptorBuilder.newBuilder(this.admin.getDescriptor(tableName))
|
||||||
|
.setReadOnly(true).build();
|
||||||
|
admin.modifyTable(htd);
|
||||||
|
|
||||||
|
// try to modify the read only table now
|
||||||
|
htd = TableDescriptorBuilder.newBuilder(this.admin.getDescriptor(tableName))
|
||||||
|
.setCompactionEnabled(false).build();
|
||||||
|
admin.modifyTable(htd);
|
||||||
|
// Delete the table
|
||||||
|
this.admin.disableTable(tableName);
|
||||||
|
this.admin.deleteTable(tableName);
|
||||||
|
assertFalse(this.admin.tableExists(tableName));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify schema modification takes.
|
* Verify schema modification takes.
|
||||||
* @throws IOException
|
|
||||||
* @throws InterruptedException
|
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testOnlineChangeTableSchema() throws IOException, InterruptedException {
|
public void testOnlineChangeTableSchema() throws IOException, InterruptedException {
|
||||||
|
|
Loading…
Reference in New Issue