BatchUpdate: Add debug logs for slow change updates
Change-Id: Ibc00cf124ee3cb378144a569dcd10242628e19d2
This commit is contained in:
@@ -17,6 +17,9 @@ package com.google.gerrit.server.git;
|
|||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
|
import static java.util.concurrent.TimeUnit.NANOSECONDS;
|
||||||
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
|
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
@@ -41,6 +44,8 @@ import com.google.gerrit.server.CurrentUser;
|
|||||||
import com.google.gerrit.server.GerritPersonIdent;
|
import com.google.gerrit.server.GerritPersonIdent;
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
import com.google.gerrit.server.config.AllUsersName;
|
import com.google.gerrit.server.config.AllUsersName;
|
||||||
|
import com.google.gerrit.server.config.ConfigUtil;
|
||||||
|
import com.google.gerrit.server.config.GerritServerConfig;
|
||||||
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||||
import com.google.gerrit.server.index.change.ChangeIndexer;
|
import com.google.gerrit.server.index.change.ChangeIndexer;
|
||||||
import com.google.gerrit.server.notedb.ChangeNotes;
|
import com.google.gerrit.server.notedb.ChangeNotes;
|
||||||
@@ -59,6 +64,7 @@ import com.google.inject.assistedinject.Assisted;
|
|||||||
import com.google.inject.assistedinject.AssistedInject;
|
import com.google.inject.assistedinject.AssistedInject;
|
||||||
|
|
||||||
import org.eclipse.jgit.lib.BatchRefUpdate;
|
import org.eclipse.jgit.lib.BatchRefUpdate;
|
||||||
|
import org.eclipse.jgit.lib.Config;
|
||||||
import org.eclipse.jgit.lib.NullProgressMonitor;
|
import org.eclipse.jgit.lib.NullProgressMonitor;
|
||||||
import org.eclipse.jgit.lib.ObjectInserter;
|
import org.eclipse.jgit.lib.ObjectInserter;
|
||||||
import org.eclipse.jgit.lib.ObjectReader;
|
import org.eclipse.jgit.lib.ObjectReader;
|
||||||
@@ -463,6 +469,7 @@ public class BatchUpdate implements AutoCloseable {
|
|||||||
private final ReviewDb db;
|
private final ReviewDb db;
|
||||||
private final SchemaFactory<ReviewDb> schemaFactory;
|
private final SchemaFactory<ReviewDb> schemaFactory;
|
||||||
|
|
||||||
|
private final long logThresholdNanos;
|
||||||
private final Project.NameKey project;
|
private final Project.NameKey project;
|
||||||
private final CurrentUser user;
|
private final CurrentUser user;
|
||||||
private final Timestamp when;
|
private final Timestamp when;
|
||||||
@@ -485,6 +492,7 @@ public class BatchUpdate implements AutoCloseable {
|
|||||||
|
|
||||||
@AssistedInject
|
@AssistedInject
|
||||||
BatchUpdate(
|
BatchUpdate(
|
||||||
|
@GerritServerConfig Config cfg,
|
||||||
AllUsersName allUsers,
|
AllUsersName allUsers,
|
||||||
ChangeControl.GenericFactory changeControlFactory,
|
ChangeControl.GenericFactory changeControlFactory,
|
||||||
ChangeIndexer indexer,
|
ChangeIndexer indexer,
|
||||||
@@ -513,6 +521,10 @@ public class BatchUpdate implements AutoCloseable {
|
|||||||
this.schemaFactory = schemaFactory;
|
this.schemaFactory = schemaFactory;
|
||||||
this.updateManagerFactory = updateManagerFactory;
|
this.updateManagerFactory = updateManagerFactory;
|
||||||
|
|
||||||
|
this.logThresholdNanos = MILLISECONDS.toNanos(
|
||||||
|
ConfigUtil.getTimeUnit(
|
||||||
|
cfg, "change", null, "updateDebugLogThreshold",
|
||||||
|
SECONDS.toMillis(2), MILLISECONDS));
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.project = project;
|
this.project = project;
|
||||||
this.user = user;
|
this.user = user;
|
||||||
@@ -670,10 +682,14 @@ public class BatchUpdate implements AutoCloseable {
|
|||||||
tasks.add(task);
|
tasks.add(task);
|
||||||
futures.add(executor.submit(task));
|
futures.add(executor.submit(task));
|
||||||
}
|
}
|
||||||
|
long startNanos = System.nanoTime();
|
||||||
Futures.allAsList(futures).get();
|
Futures.allAsList(futures).get();
|
||||||
|
maybeLogSlowUpdate(startNanos, "change");
|
||||||
|
|
||||||
if (notesMigration.commitChangeWrites()) {
|
if (notesMigration.commitChangeWrites()) {
|
||||||
|
startNanos = System.nanoTime();
|
||||||
executeNoteDbUpdates(tasks);
|
executeNoteDbUpdates(tasks);
|
||||||
|
maybeLogSlowUpdate(startNanos, "NoteDb");
|
||||||
}
|
}
|
||||||
} catch (ExecutionException | InterruptedException e) {
|
} catch (ExecutionException | InterruptedException e) {
|
||||||
Throwables.propagateIfInstanceOf(e.getCause(), UpdateException.class);
|
Throwables.propagateIfInstanceOf(e.getCause(), UpdateException.class);
|
||||||
@@ -693,6 +709,25 @@ public class BatchUpdate implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class SlowUpdateException extends Exception {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private SlowUpdateException(String fmt, Object... args) {
|
||||||
|
super(String.format(fmt, args));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void maybeLogSlowUpdate(long startNanos, String desc) {
|
||||||
|
long elapsedNanos = System.nanoTime() - startNanos;
|
||||||
|
if (!log.isDebugEnabled() || elapsedNanos <= logThresholdNanos) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log.debug("Slow " + desc + " update",
|
||||||
|
new SlowUpdateException(
|
||||||
|
"Slow %s update (%d ms) to %s for %s",
|
||||||
|
desc, NANOSECONDS.toMillis(elapsedNanos), project, ops.keySet()));
|
||||||
|
}
|
||||||
|
|
||||||
private void executeNoteDbUpdates(List<ChangeTask> tasks) {
|
private void executeNoteDbUpdates(List<ChangeTask> tasks) {
|
||||||
// Aggregate together all NoteDb ref updates from the ops we executed,
|
// Aggregate together all NoteDb ref updates from the ops we executed,
|
||||||
// possibly in parallel. Each task had its own NoteDbUpdateManager instance
|
// possibly in parallel. Each task had its own NoteDbUpdateManager instance
|
||||||
|
|||||||
Reference in New Issue
Block a user