Add ssh command to activate the latest index

In case the online indexer fails, this allows the admins to activate
the latest index.

Change-Id: I59ebf2bce02a599b87d0f7771fc806ff64a3ba64
This commit is contained in:
Hugo Arès
2015-06-30 10:36:08 -04:00
parent 3a593351d6
commit 47f15bed74
6 changed files with 108 additions and 2 deletions

View File

@@ -0,0 +1,32 @@
= gerrit index activate
== NAME
gerrit index activate - Activate the latest index version available
== SYNOPSIS
--
'ssh' -p @SSH_PORT@ @SSH_HOST@ 'gerrit index activate'
--
== DESCRIPTION
Gerrit supports online index schema upgrades. When starting Gerrit for the first
time after an upgrade that requires an index schema upgrade, the online indexer
will be started. If the schema upgrade is a success, the new index will be
activated and if it fails, a statement in the logs will be printed with the
number of successfully/failed indexed changes.
This command allows to activate the latest index even if there were some
failures.
== ACCESS
Caller must be a member of the privileged 'Administrators' group.
== SCRIPTING
This command is intended to be used in scripts.
GERRIT
------
Part of link:index.html[Gerrit Code Review]
SEARCHBOX
---------

View File

@@ -117,6 +117,9 @@ link:cmd-gc.html[gerrit gc]::
link:cmd-gsql.html[gerrit gsql]::
Administrative interface to active database.
link:cmd-index-index.html[gerrit index activate]::
Activate the latest index version available.
link:cmd-index-start.html[gerrit index start]::
Start the online indexer.

View File

@@ -182,6 +182,22 @@ public class LuceneVersionManager implements LifecycleListener {
return false;
}
/**
* Activate the latest index if the current index is not already the latest.
*
* @return true if index was activate, otherwise false.
* @throws ReindexerAlreadyRunningException
*/
public synchronized boolean activateLatestIndex()
throws ReindexerAlreadyRunningException {
validateReindexerNotRunning();
if (!isCurrentIndexVersionLatest()) {
reindexer.activateIndex();
return true;
}
return false;
}
private boolean isCurrentIndexVersionLatest() {
return reindexer == null
|| reindexer.getVersion() == indexes.getSearchIndex().getSchema()

View File

@@ -43,6 +43,7 @@ public class OnlineReindexer {
private final SiteIndexer batchIndexer;
private final ProjectCache projectCache;
private final int version;
private ChangeIndex index;
private final AtomicBoolean running = new AtomicBoolean();
@Inject
@@ -88,7 +89,7 @@ public class OnlineReindexer {
}
private void reindex() {
ChangeIndex index = checkNotNull(indexes.getWriteIndex(version),
index = checkNotNull(indexes.getWriteIndex(version),
"not an active write schema version: %s", version);
log.info("Starting online reindex from schema version {} to {}",
version(indexes.getSearchIndex()), version(index));
@@ -100,9 +101,13 @@ public class OnlineReindexer {
version(index), result.doneCount(), result.failedCount());
return;
}
log.info("Reindex to version {} complete", version(index));
activateIndex();
}
void activateIndex() {
indexes.setSearchIndex(index);
log.info("Reindex complete, using schema version {}", version(index));
log.info("Using schema version {}", version(index));
try {
index.markReady(true);
} catch (IOException e) {

View File

@@ -59,6 +59,7 @@ public class DefaultCommandModule extends CommandModule {
command(gerrit, GarbageCollectionCommand.class);
command(index).toProvider(new DispatchCommandProvider(index));
command(index, IndexActivateCommand.class);
command(index, IndexStartCommand.class);
command(gerrit, "plugin").toProvider(new DispatchCommandProvider(plugin));

View File

@@ -0,0 +1,49 @@
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.sshd.commands;
import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.lucene.LuceneVersionManager;
import com.google.gerrit.lucene.ReindexerAlreadyRunningException;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand;
import com.google.inject.Inject;
@RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER)
@CommandMetaData(name = "activate",
description = "Activate the latest index version available",
runsAt = MASTER)
public class IndexActivateCommand extends SshCommand {
@Inject
private LuceneVersionManager luceneVersionManager;
@Override
protected void run() throws UnloggedFailure {
try {
if (luceneVersionManager.activateLatestIndex()) {
stdout.println("Activated latest index version");
} else {
stdout.println("Not activating index, already using latest version");
}
} catch (ReindexerAlreadyRunningException e) {
throw new UnloggedFailure("Failed to activate latest index: "
+ e.getMessage());
}
}
}