HBASE-19943 Only allow removing sync replication peer which is in DA state
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/4bb4d521 Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/4bb4d521 Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/4bb4d521 Branch: refs/heads/HBASE-19064 Commit: 4bb4d5213062a34c1daf7222c374ffa58d64065f Parents: d35ba3f Author: huzheng <open...@gmail.com> Authored: Thu Mar 1 18:34:02 2018 +0800 Committer: zhangduo <zhang...@apache.org> Committed: Wed Apr 11 14:56:43 2018 +0800 ---------------------------------------------------------------------- .../replication/ReplicationPeerManager.java | 14 ++++- .../hbase/wal/SyncReplicationWALProvider.java | 2 +- .../replication/TestReplicationAdmin.java | 63 ++++++++++++++++++++ .../hbase/replication/TestSyncReplication.java | 2 +- 4 files changed, 78 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hbase/blob/4bb4d521/hbase-server/src/main/java/org/apache/hadoop/hbase/master/replication/ReplicationPeerManager.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/replication/ReplicationPeerManager.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/replication/ReplicationPeerManager.java index 0dc922d..41dd6e3 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/replication/ReplicationPeerManager.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/replication/ReplicationPeerManager.java @@ -120,8 +120,20 @@ public class ReplicationPeerManager { return desc; } + private void checkPeerInDAStateIfSyncReplication(String peerId) throws DoNotRetryIOException { + ReplicationPeerDescription desc = peers.get(peerId); + if (desc != null && desc.getPeerConfig().isSyncReplication() + && !SyncReplicationState.DOWNGRADE_ACTIVE.equals(desc.getSyncReplicationState())) { + throw new DoNotRetryIOException("Couldn't remove synchronous replication peer with state=" + + desc.getSyncReplicationState() + + ", Transit the synchronous replication state to be DOWNGRADE_ACTIVE firstly."); + } + } + ReplicationPeerConfig preRemovePeer(String peerId) throws DoNotRetryIOException { - return checkPeerExists(peerId).getPeerConfig(); + ReplicationPeerDescription pd = checkPeerExists(peerId); + checkPeerInDAStateIfSyncReplication(peerId); + return pd.getPeerConfig(); } void preEnablePeer(String peerId) throws DoNotRetryIOException { http://git-wip-us.apache.org/repos/asf/hbase/blob/4bb4d521/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/SyncReplicationWALProvider.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/SyncReplicationWALProvider.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/SyncReplicationWALProvider.java index ac4b4cd..282aa21 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/SyncReplicationWALProvider.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/SyncReplicationWALProvider.java @@ -142,7 +142,7 @@ public class SyncReplicationWALProvider implements WALProvider, PeerActionListen @Override public WAL getWAL(RegionInfo region) throws IOException { if (region == null) { - return provider.getWAL(region); + return provider.getWAL(null); } Optional<Pair<String, String>> peerIdAndRemoteWALDir = peerInfoProvider.getPeerIdAndRemoteWALDir(region); http://git-wip-us.apache.org/repos/asf/hbase/blob/4bb4d521/hbase-server/src/test/java/org/apache/hadoop/hbase/client/replication/TestReplicationAdmin.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/replication/TestReplicationAdmin.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/replication/TestReplicationAdmin.java index 0ad476f..486ab51 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/replication/TestReplicationAdmin.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/replication/TestReplicationAdmin.java @@ -254,6 +254,62 @@ public class TestReplicationAdmin { } @Test + public void testRemovePeerWithNonDAState() throws Exception { + TableName tableName = TableName.valueOf(name.getMethodName()); + TEST_UTIL.createTable(tableName, Bytes.toBytes("family")); + ReplicationPeerConfigBuilder builder = ReplicationPeerConfig.newBuilder(); + + String rootDir = "hdfs://srv1:9999/hbase"; + builder.setClusterKey(KEY_ONE); + builder.setRemoteWALDir(rootDir); + builder.setReplicateAllUserTables(false); + Map<TableName, List<String>> tableCfs = new HashMap<>(); + tableCfs.put(tableName, new ArrayList<>()); + builder.setTableCFsMap(tableCfs); + hbaseAdmin.addReplicationPeer(ID_ONE, builder.build()); + assertEquals(SyncReplicationState.DOWNGRADE_ACTIVE, + hbaseAdmin.getReplicationPeerSyncReplicationState(ID_ONE)); + + // Transit sync replication state to ACTIVE. + hbaseAdmin.transitReplicationPeerSyncReplicationState(ID_ONE, SyncReplicationState.ACTIVE); + assertEquals(SyncReplicationState.ACTIVE, + hbaseAdmin.getReplicationPeerSyncReplicationState(ID_ONE)); + + try { + hbaseAdmin.removeReplicationPeer(ID_ONE); + fail("Can't remove a synchronous replication peer with state=ACTIVE"); + } catch (IOException e) { + // OK + } + + // Transit sync replication state to DA + hbaseAdmin.transitReplicationPeerSyncReplicationState(ID_ONE, + SyncReplicationState.DOWNGRADE_ACTIVE); + assertEquals(SyncReplicationState.DOWNGRADE_ACTIVE, + hbaseAdmin.getReplicationPeerSyncReplicationState(ID_ONE)); + // Transit sync replication state to STANDBY + hbaseAdmin.transitReplicationPeerSyncReplicationState(ID_ONE, SyncReplicationState.STANDBY); + assertEquals(SyncReplicationState.STANDBY, + hbaseAdmin.getReplicationPeerSyncReplicationState(ID_ONE)); + + try { + hbaseAdmin.removeReplicationPeer(ID_ONE); + fail("Can't remove a synchronous replication peer with state=STANDBY"); + } catch (IOException e) { + // OK + } + + // Transit sync replication state to DA + hbaseAdmin.transitReplicationPeerSyncReplicationState(ID_ONE, + SyncReplicationState.DOWNGRADE_ACTIVE); + assertEquals(SyncReplicationState.DOWNGRADE_ACTIVE, + hbaseAdmin.getReplicationPeerSyncReplicationState(ID_ONE)); + + hbaseAdmin.removeReplicationPeer(ID_ONE); + assertEquals(0, hbaseAdmin.listReplicationPeers().size()); + } + + @Test public void testAddPeerWithState() throws Exception { ReplicationPeerConfig rpc1 = new ReplicationPeerConfig(); rpc1.setClusterKey(KEY_ONE); @@ -1072,5 +1128,12 @@ public class TestReplicationAdmin { } catch (Exception e) { // OK } + hbaseAdmin.transitReplicationPeerSyncReplicationState(ID_SECOND, + SyncReplicationState.DOWNGRADE_ACTIVE); + assertEquals(SyncReplicationState.DOWNGRADE_ACTIVE, + hbaseAdmin.getReplicationPeerSyncReplicationState(ID_SECOND)); + hbaseAdmin.removeReplicationPeer(ID_ONE); + hbaseAdmin.removeReplicationPeer(ID_SECOND); + assertEquals(0, hbaseAdmin.listReplicationPeers().size()); } } http://git-wip-us.apache.org/repos/asf/hbase/blob/4bb4d521/hbase-server/src/test/java/org/apache/hadoop/hbase/replication/TestSyncReplication.java ---------------------------------------------------------------------- diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/replication/TestSyncReplication.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/replication/TestSyncReplication.java index 196019d..cc84dab 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/replication/TestSyncReplication.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/replication/TestSyncReplication.java @@ -109,7 +109,7 @@ public class TestSyncReplication { UTIL1.startMiniCluster(3); UTIL2.startMiniCluster(3); TableDescriptor td = - TableDescriptorBuilder.newBuilder(TABLE_NAME).addColumnFamily(ColumnFamilyDescriptorBuilder + TableDescriptorBuilder.newBuilder(TABLE_NAME).setColumnFamily(ColumnFamilyDescriptorBuilder .newBuilder(CF).setScope(HConstants.REPLICATION_SCOPE_GLOBAL).build()).build(); UTIL1.getAdmin().createTable(td); UTIL2.getAdmin().createTable(td);