Skip to content

Commit 73105e0

Browse files
committed
HDDS-15103. OM crash due to race condition between om start and install snapshot
1 parent 7eaf46f commit 73105e0

2 files changed

Lines changed: 86 additions & 0 deletions

File tree

hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOMRatisSnapshots.java

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,81 @@ public void testInstallSnapshotWithClientRead() throws Exception {
933933
assertLogCapture(logCapture, "Install Checkpoint is finished");
934934
}
935935

936+
@Test
937+
public void testInstallSnapshotOzoneManagerNotInRunningState() throws Exception {
938+
// Get the leader OM
939+
final String leaderOMNodeId = OmTestUtil.getCurrentOmProxyNodeId(objectStore);
940+
941+
OzoneManager leaderOM = cluster.getOzoneManager(leaderOMNodeId);
942+
OzoneManagerRatisServer leaderRatisServer = leaderOM.getOmRatisServer();
943+
944+
// Find the inactive OM
945+
String followerNodeId = leaderOM.getPeerNodes().get(0).getNodeId();
946+
if (cluster.isOMActive(followerNodeId)) {
947+
followerNodeId = leaderOM.getPeerNodes().get(1).getNodeId();
948+
}
949+
OzoneManager followerOM = cluster.getOzoneManager(followerNodeId);
950+
951+
// Do some transactions so that the log index increases
952+
List<String> keys = writeKeysToIncreaseLogIndex(leaderRatisServer, 200);
953+
954+
// Get transaction Index
955+
TransactionInfo transactionInfo =
956+
TransactionInfo.readTransactionInfo(leaderOM.getMetadataManager());
957+
TermIndex leaderOMTermIndex =
958+
TermIndex.valueOf(transactionInfo.getTerm(),
959+
transactionInfo.getTransactionIndex());
960+
long leaderOMSnapshotIndex = leaderOMTermIndex.getIndex();
961+
long leaderOMSnapshotTermIndex = leaderOMTermIndex.getTerm();
962+
963+
// Start the inactive OM. Checkpoint installation will happen spontaneously.
964+
cluster.startInactiveOM(followerNodeId);
965+
OzoneManager.setTestInstallSnapshot(true);
966+
LogCapturer logCapture = LogCapturer.captureLogs(OzoneManager.class);
967+
assertLogCapture(logCapture, "OzoneManager is not in running state");
968+
OzoneManager.setTestInstallSnapshot(false);
969+
970+
// The recently started OM should be lagging behind the leader OM.
971+
// Wait & for follower to update transactions to leader snapshot index.
972+
// Timeout error if follower does not load update within 3s
973+
GenericTestUtils.waitFor(() -> {
974+
return followerOM.getOmRatisServer().getLastAppliedTermIndex().getIndex()
975+
>= leaderOMSnapshotIndex - 1;
976+
}, 100, 30_000);
977+
978+
long followerOMLastAppliedIndex =
979+
followerOM.getOmRatisServer().getLastAppliedTermIndex().getIndex();
980+
assertThat(followerOMLastAppliedIndex).isGreaterThanOrEqualTo(leaderOMSnapshotIndex - 1);
981+
982+
// After the new checkpoint is installed, the follower OM
983+
// lastAppliedIndex must >= the snapshot index of the checkpoint. It
984+
// could be great than snapshot index if there is any conf entry from ratis.
985+
followerOMLastAppliedIndex = followerOM.getOmRatisServer()
986+
.getLastAppliedTermIndex().getIndex();
987+
assertThat(followerOMLastAppliedIndex).isGreaterThanOrEqualTo(leaderOMSnapshotIndex);
988+
assertThat(followerOM.getOmRatisServer().getLastAppliedTermIndex()
989+
.getTerm()).isGreaterThanOrEqualTo(leaderOMSnapshotTermIndex);
990+
991+
// Verify that the follower OM's DB contains the transactions which were
992+
// made while it was inactive.
993+
OMMetadataManager followerOMMetaMngr = followerOM.getMetadataManager();
994+
assertNotNull(followerOMMetaMngr.getVolumeTable().get(
995+
followerOMMetaMngr.getVolumeKey(volumeName)));
996+
assertNotNull(followerOMMetaMngr.getBucketTable().get(
997+
followerOMMetaMngr.getBucketKey(volumeName, bucketName)));
998+
for (String key : keys) {
999+
assertNotNull(followerOMMetaMngr.getKeyTable(
1000+
TEST_BUCKET_LAYOUT)
1001+
.get(followerOMMetaMngr.getOzoneKey(volumeName, bucketName, key)));
1002+
}
1003+
1004+
// Wait installation finish
1005+
Thread.sleep(5000);
1006+
// Verify checkpoint installation was happened.
1007+
assertLogCapture(logCapture, "Reloaded OM state");
1008+
assertLogCapture(logCapture, "Install Checkpoint is finished");
1009+
}
1010+
9361011
@Test
9371012
public void testInstallOldCheckpointFailure() throws Exception {
9381013
// Get the leader OM

hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@ public final class OzoneManager extends ServiceRuntimeInfoImpl
488488
private static boolean testReloadConfigFlag = false;
489489
private static boolean testSecureOmFlag = false;
490490
private static UserGroupInformation testUgi;
491+
private static boolean testInstallSnapshot = false;
491492

492493
private final OzoneLockProvider ozoneLockProvider;
493494
private final OMPerformanceMetrics perfMetrics;
@@ -4063,6 +4064,12 @@ public List<OzoneAcl> getAcl(OzoneObj obj) throws IOException {
40634064
* @throws IOException if download or cleanup fails
40644065
*/
40654066
public synchronized TermIndex installSnapshotFromLeader(String leaderId) throws IOException {
4067+
if (!isRunning() || testInstallSnapshot) {
4068+
LOG.warn("OzoneManager is not in running state, state {}. Abort install snapshot from Leader.",
4069+
omState);
4070+
return null;
4071+
}
4072+
40664073
if (omRatisSnapshotProvider == null) {
40674074
LOG.error("OM Snapshot Provider is not configured as there are no peer " +
40684075
"nodes.");
@@ -4511,6 +4518,10 @@ public static void setTestReloadConfigFlag(boolean testReloadConfigFlag) {
45114518
OzoneManager.testReloadConfigFlag = testReloadConfigFlag;
45124519
}
45134520

4521+
public static void setTestInstallSnapshot(boolean testInstallSnapshot) {
4522+
OzoneManager.testInstallSnapshot = testInstallSnapshot;
4523+
}
4524+
45144525
public static void setTestSecureOmFlag(boolean testSecureOmFlag) {
45154526
OzoneManager.testSecureOmFlag = testSecureOmFlag;
45164527
}

0 commit comments

Comments
 (0)