You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@hbase.apache.org by "Zephyr Guo (JIRA)" <ji...@apache.org> on 2015/07/01 03:51:04 UTC
[jira] [Updated] (HBASE-13997) ScannerCallableWithReplicas cause
Infinitely blocking
[ https://issues.apache.org/jira/browse/HBASE-13997?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Zephyr Guo updated HBASE-13997:
-------------------------------
Description:
Bug in ScannerCallableWithReplicas.addCallsForOtherReplicas method
{code:title=code in ScannerCallableWithReplicas.addCallsForOtherReplicas |borderStyle=solid}
private int addCallsForOtherReplicas(
BoundedCompletionService<Pair<Result[], ScannerCallable>> cs, RegionLocations rl, int min,
int max) {
if (scan.getConsistency() == Consistency.STRONG) {
return 0; // not scheduling on other replicas for strong consistency
}
for (int id = min; id <= max; id++) {
if (currentScannerCallable.getHRegionInfo().getReplicaId() == id) {
continue; //this was already scheduled earlier
}
ScannerCallable s = currentScannerCallable.getScannerCallableForReplica(id);
if (this.lastResult != null) {
s.getScan().setStartRow(this.lastResult.getRow());
}
outstandingCallables.add(s);
RetryingRPC retryingOnReplica = new RetryingRPC(s);
cs.submit(retryingOnReplica);
}
return max - min + 1; //bug? should be "max - min",because "continue"
//always happen once
}
{code}
{code:title=code in ScannerCallableWithReplicas.call|borderStyle=solid}
submitted += addCallsForOtherReplicas(cs, rl, 0, rl.size() - 1);
// submitted larger than the actual one
{code}
It can cause completed < submitted always so that the following code will be infinitely blocked.
{code:title=code in ScannerCallableWithReplicas.call|borderStyle=solid}
while (completed < submitted) {
try {
Future<Pair<Result[], ScannerCallable>> f = cs.take();
Pair<Result[], ScannerCallable> r = f.get();
if (r != null && r.getSecond() != null) {
updateCurrentlyServingReplica(r.getSecond(), r.getFirst(), done, pool);
}
return r == null ? null : r.getFirst(); // great we got an answer
} catch (ExecutionException e) {
// if not cancel or interrupt, wait until all RPC's are done
// one of the tasks failed. Save the exception for later.
if (exceptions == null) exceptions = new ArrayList<ExecutionException>(rl.size());
exceptions.add(e);
completed++;
}
}
{code}
If all replica-RS occur ExecutionException ,it will be infinitely blocked in cs.take()
was:
Bug in ScannerCallableWithReplicas.addCallsForOtherReplicas method
{code:title=ScannerCallableWithReplicas.java|borderStyle=solid}
private int addCallsForOtherReplicas(
BoundedCompletionService<Pair<Result[], ScannerCallable>> cs, RegionLocations rl, int min,
int max) {
if (scan.getConsistency() == Consistency.STRONG) {
return 0; // not scheduling on other replicas for strong consistency
}
for (int id = min; id <= max; id++) {
if (currentScannerCallable.getHRegionInfo().getReplicaId() == id) {
continue; //this was already scheduled earlier
}
ScannerCallable s = currentScannerCallable.getScannerCallableForReplica(id);
if (this.lastResult != null) {
s.getScan().setStartRow(this.lastResult.getRow());
}
outstandingCallables.add(s);
RetryingRPC retryingOnReplica = new RetryingRPC(s);
cs.submit(retryingOnReplica);
}
return max - min + 1; //bug? max - min
}
{code}
It can cause completed < submitted always so that the following code will be infinitely blocked.
{code:title=ScannerCallableWithReplicas.java|borderStyle=solid}
while (completed < submitted) {
try {
Future<Pair<Result[], ScannerCallable>> f = cs.take();
Pair<Result[], ScannerCallable> r = f.get();
if (r != null && r.getSecond() != null) {
updateCurrentlyServingReplica(r.getSecond(), r.getFirst(), done, pool);
}
return r == null ? null : r.getFirst(); // great we got an answer
} catch (ExecutionException e) {
// if not cancel or interrupt, wait until all RPC's are done
// one of the tasks failed. Save the exception for later.
if (exceptions == null) exceptions = new ArrayList<ExecutionException>(rl.size());
exceptions.add(e);
completed++;
}
}
{code}
The code in ScannerCallableWithReplicas.call
If all replica-RS occur ExecutionException ,it will be blocked in cs.take()
> ScannerCallableWithReplicas cause Infinitely blocking
> -----------------------------------------------------
>
> Key: HBASE-13997
> URL: https://issues.apache.org/jira/browse/HBASE-13997
> Project: HBase
> Issue Type: Bug
> Components: Client
> Affects Versions: 1.0.1.1
> Reporter: Zephyr Guo
> Assignee: Zephyr Guo
> Priority: Minor
>
> Bug in ScannerCallableWithReplicas.addCallsForOtherReplicas method
> {code:title=code in ScannerCallableWithReplicas.addCallsForOtherReplicas |borderStyle=solid}
> private int addCallsForOtherReplicas(
> BoundedCompletionService<Pair<Result[], ScannerCallable>> cs, RegionLocations rl, int min,
> int max) {
> if (scan.getConsistency() == Consistency.STRONG) {
> return 0; // not scheduling on other replicas for strong consistency
> }
> for (int id = min; id <= max; id++) {
> if (currentScannerCallable.getHRegionInfo().getReplicaId() == id) {
> continue; //this was already scheduled earlier
> }
> ScannerCallable s = currentScannerCallable.getScannerCallableForReplica(id);
> if (this.lastResult != null) {
> s.getScan().setStartRow(this.lastResult.getRow());
> }
> outstandingCallables.add(s);
> RetryingRPC retryingOnReplica = new RetryingRPC(s);
> cs.submit(retryingOnReplica);
> }
> return max - min + 1; //bug? should be "max - min",because "continue"
> //always happen once
> }
> {code}
> {code:title=code in ScannerCallableWithReplicas.call|borderStyle=solid}
> submitted += addCallsForOtherReplicas(cs, rl, 0, rl.size() - 1);
> // submitted larger than the actual one
> {code}
> It can cause completed < submitted always so that the following code will be infinitely blocked.
> {code:title=code in ScannerCallableWithReplicas.call|borderStyle=solid}
> while (completed < submitted) {
> try {
> Future<Pair<Result[], ScannerCallable>> f = cs.take();
> Pair<Result[], ScannerCallable> r = f.get();
> if (r != null && r.getSecond() != null) {
> updateCurrentlyServingReplica(r.getSecond(), r.getFirst(), done, pool);
> }
> return r == null ? null : r.getFirst(); // great we got an answer
> } catch (ExecutionException e) {
> // if not cancel or interrupt, wait until all RPC's are done
> // one of the tasks failed. Save the exception for later.
> if (exceptions == null) exceptions = new ArrayList<ExecutionException>(rl.size());
> exceptions.add(e);
> completed++;
> }
> }
> {code}
> If all replica-RS occur ExecutionException ,it will be infinitely blocked in cs.take()
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)