[Bug][Colocation Join] Fix colocation balance endless loop bug (#4471)

1. Only one available backend.
2. All backends are checked but this round is not changed. For example, all backends are on the same host.
This commit is contained in:
wyb
2020-08-28 09:27:57 +08:00
committed by GitHub
parent 174c9f89ea
commit ec64789e89
2 changed files with 48 additions and 3 deletions

View File

@ -546,6 +546,11 @@ public class ColocateTableBalancer extends MasterDaemon {
// sort backends with replica num
List<Map.Entry<Long, Long>> backendWithReplicaNum =
getSortedBackendReplicaNumPairs(allAvailBackendIds, flatBackendsPerBucketSeq);
// if there is only one available backend, end the outer loop
if (backendWithReplicaNum.size() == 1) {
LOG.info("there is only one available backend, end the outer loop in colocate group {}", groupId);
break;
}
int i = 0;
int j = backendWithReplicaNum.size() - 1;
@ -600,11 +605,18 @@ public class ColocateTableBalancer extends MasterDaemon {
}
if (!isThisRoundChanged) {
// select another load backend and try again
LOG.info("unable to replace backend {} with backend {} in colocate group {}",
srcBeId, destBeId, groupId);
j--;
continue;
if (--j == i) {
// if all backends are checked but this round is not changed,
// we should end the outer loop to avoid endless loops
LOG.info("all backends are checked but this round is not changed, " +
"end outer loop in colocate group {}", groupId);
break OUT;
} else {
// select another load backend and try again
continue;
}
}
break;

View File

@ -151,4 +151,37 @@ public class ColocateTableBalancerTest {
Assert.assertFalse(changed);
Assert.assertTrue(balancedBackendsPerBucketSeq.isEmpty());
}
@Test
public void testFixBalanceEndlessLoop() {
GroupId groupId = new GroupId(10000, 10001);
List<Column> distributionCols = Lists.newArrayList();
distributionCols.add(new Column("k1", PrimitiveType.INT));
ColocateGroupSchema groupSchema = new ColocateGroupSchema(groupId, distributionCols, 5, (short) 1);
Map<GroupId, ColocateGroupSchema> group2Schema = Maps.newHashMap();
group2Schema.put(groupId, groupSchema);
// 1. only one available backend
// [[7], [7], [7], [7], [7]]
ColocateTableIndex colocateTableIndex = createColocateIndex(groupId, Lists.newArrayList(7L, 7L, 7L, 7L, 7L));
Deencapsulation.setField(colocateTableIndex, "group2Schema", group2Schema);
List<List<Long>> balancedBackendsPerBucketSeq = Lists.newArrayList();
List<Long> allAvailBackendIds = Lists.newArrayList(7L);
boolean changed = Deencapsulation.invoke(balancer, "balance", groupId, allAvailBackendIds,
colocateTableIndex, infoService, balancedBackendsPerBucketSeq);
Assert.assertFalse(changed);
// 2. all backends are checked but this round is not changed
// [[7], [7], [7], [7], [7]]
// and add new backends 8, 9 that are on the same host with 7
colocateTableIndex = createColocateIndex(groupId, Lists.newArrayList(7L, 7L, 7L, 7L, 7L));
Deencapsulation.setField(colocateTableIndex, "group2Schema", group2Schema);
balancedBackendsPerBucketSeq = Lists.newArrayList();
allAvailBackendIds = Lists.newArrayList(7L, 8L, 9L);
changed = Deencapsulation.invoke(balancer, "balance", groupId, allAvailBackendIds,
colocateTableIndex, infoService, balancedBackendsPerBucketSeq);
Assert.assertFalse(changed);
}
}