Migrate starred changes to git (part 1)

To support a live migration on a multi-master Gerrit installation, the
upgrade is done in 2 steps:

- part 1 (this change):
  * always write to both backends (database and git)
  * a configuration option (user.readStarredChangesFromGit) decides if
    the starred changes are read from database or git (default:
    database)
  * upgraded instances write to both backends, old instances only
    read/write from/to the database
  * after upgrading all instances (all still read from the database)
    run a batch to copy all starred changes from the database to git
  * update all instances to read from git
  * make sure all instances use the new schema version
- part 2 (next change):
  * bump the database schema version
  * migrate the starred changes from database to git (for single
    instance Gerrit servers)
  * delete the database table
  * delete the user.readStarredChangesFromGit config option

The user.readStarredChangesFromGit configuration options is replacing
the global readAccounts bit from NotesMigration in
StarredChangesUtil. This way we can migrate the starred changes
already now while other account data is still in the database.

Change-Id: Iac4f68ea6e0c65b589de25013bfffdcd0fca0d38
Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
Edwin Kempin
2016-04-15 08:25:02 +02:00
parent b0a6d69537
commit 2bdaa68b4a

View File

@@ -33,10 +33,10 @@ import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.client.StarredChange;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.index.change.ChangeField;
import com.google.gerrit.server.index.change.ChangeIndexer;
import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.InternalChangeQuery;
@@ -48,6 +48,7 @@ import com.google.inject.Provider;
import com.google.inject.Singleton;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId;
@@ -81,38 +82,36 @@ public class StarredChangesUtil {
private final GitRepositoryManager repoManager;
private final AllUsersName allUsers;
private final NotesMigration migration;
private final Provider<ReviewDb> dbProvider;
private final PersonIdent serverIdent;
private final ChangeIndexer indexer;
private final Provider<InternalChangeQuery> queryProvider;
private final boolean readFromGit;
@Inject
StarredChangesUtil(GitRepositoryManager repoManager,
AllUsersName allUsers,
NotesMigration migration,
Provider<ReviewDb> dbProvider,
@GerritPersonIdent PersonIdent serverIdent,
ChangeIndexer indexer,
Provider<InternalChangeQuery> queryProvider) {
Provider<InternalChangeQuery> queryProvider,
@GerritServerConfig Config cfg) {
this.repoManager = repoManager;
this.allUsers = allUsers;
this.migration = migration;
this.dbProvider = dbProvider;
this.serverIdent = serverIdent;
this.indexer = indexer;
this.queryProvider = queryProvider;
this.readFromGit =
cfg.getBoolean("user", null, "readStarredChangesFromGit", false);
}
public void star(Account.Id accountId, Project.NameKey project,
Change.Id changeId) throws OrmException, IOException {
Change.Id changeId) throws OrmException {
dbProvider.get().starredChanges()
.insert(Collections.singleton(new StarredChange(
new StarredChange.Key(accountId, changeId))));
if (!migration.writeAccounts()) {
indexer.index(dbProvider.get(), project, changeId);
return;
}
try (Repository repo = repoManager.openRepository(allUsers)) {
String refName = RefNames.refsStarredChanges(changeId, accountId);
ObjectId oldObjectId = getObjectId(repo, refName);
@@ -128,14 +127,11 @@ public class StarredChangesUtil {
}
public void unstar(Account.Id accountId, Project.NameKey project,
Change.Id changeId) throws OrmException, IOException {
Change.Id changeId) throws OrmException {
dbProvider.get().starredChanges()
.delete(Collections.singleton(new StarredChange(
new StarredChange.Key(accountId, changeId))));
if (!migration.writeAccounts()) {
indexer.index(dbProvider.get(), project, changeId);
return;
}
try (Repository repo = repoManager.openRepository(allUsers);
RevWalk rw = new RevWalk(repo)) {
RefUpdate u = repo.updateRef(
@@ -170,13 +166,10 @@ public class StarredChangesUtil {
}
public void unstarAll(Project.NameKey project, Change.Id changeId)
throws OrmException, IOException, NoSuchChangeException {
throws OrmException, NoSuchChangeException {
dbProvider.get().starredChanges().delete(
dbProvider.get().starredChanges().byChange(changeId));
if (!migration.writeAccounts()) {
indexer.index(dbProvider.get(), project, changeId);
return;
}
try (Repository repo = repoManager.openRepository(allUsers);
RevWalk rw = new RevWalk(repo)) {
BatchRefUpdate batchUpdate = repo.getRefDatabase().newBatchUpdate();
@@ -206,7 +199,7 @@ public class StarredChangesUtil {
public Set<Account.Id> byChange(Change.Id changeId)
throws OrmException {
if (!migration.readAccounts()) {
if (!readFromGit) {
return FluentIterable
.from(dbProvider.get().starredChanges().byChange(changeId))
.transform(new Function<StarredChange, Account.Id>() {
@@ -242,7 +235,7 @@ public class StarredChangesUtil {
@Deprecated
public ResultSet<Change.Id> queryFromIndex(final Account.Id accountId) {
try {
if (!migration.readAccounts()) {
if (!readFromGit) {
return new ChangeIdResultSet(
dbProvider.get().starredChanges().byAccount(accountId));
}