diff options
author | Kaushik Lingarkar <kaushikl@codeaurora.org> | 2021-12-13 15:18:54 -0800 |
---|---|---|
committer | Kaushik Lingarkar <kaushikl@codeaurora.org> | 2021-12-16 13:50:44 -0800 |
commit | 0bb9f91c44760dee3ee571abe6f8c9aef3655f9e (patch) | |
tree | bb4cf902ef75550fe0790d25835baea1663f0beb | |
parent | ffdc7af24f369be7577df1cfe568ab7078b3e888 (diff) |
Run background GC in Schema 144 and update GCs done in Schema 146
The initial preparatory GC in schema 146 can be skipped for two reasons:
1) Several updates were done to keep All-Users in good state in
preceding schemas by not writing loose objects.
2) Schema 144 now triggers a GC in the background. Schema 144 belongs to
the same Gerrit release as 146, so users will never run an older
version of 144(w/o the background GC) and a newer version of 146
(w/o the preparatory in-line GC).
The inline GC in schema 146 which runs every 50 packs has been converted
to a background GC. The intent of this inline GC was to keep All-Users
from getting worse when there are a large number of user refs that need
to be rewritten. Running a background GC also achieves that goal and has
the added advantage of not holding up a data migration thread to run GC,
thereby not slowing down the schema and allowing other schemas to
proceed without waiting for the GC to complete.
Change-Id: I16b048cf75671c40edc38e54d339735a93c1ebc9
-rw-r--r-- | java/com/google/gerrit/server/schema/SchemaVersion.java | 32 | ||||
-rw-r--r-- | java/com/google/gerrit/server/schema/Schema_144.java | 1 | ||||
-rw-r--r-- | java/com/google/gerrit/server/schema/Schema_146.java | 29 |
3 files changed, 18 insertions, 44 deletions
diff --git a/java/com/google/gerrit/server/schema/SchemaVersion.java b/java/com/google/gerrit/server/schema/SchemaVersion.java index da87c50691..b78b5a6233 100644 --- a/java/com/google/gerrit/server/schema/SchemaVersion.java +++ b/java/com/google/gerrit/server/schema/SchemaVersion.java @@ -345,7 +345,22 @@ public abstract class SchemaVersion { backgroundGcThread.execute(new GcTask(project, repoManager, ui)); } - protected void gc(Repository repo, UpdateUI ui, ProgressMonitor pm, Stopwatch sw) + protected static ObjectId emptyTree(ObjectInserter oi) throws IOException { + return oi.insert(Constants.OBJ_TREE, new byte[] {}); + } + + protected static ObjectInserter getPackInserterFirst(Repository repo) { + if (repo instanceof FileRepository) { + return ((FileRepository) repo).getObjectDatabase().newPackInserter(); + } + return repo.getObjectDatabase().newInserter(); + } + + private static long countDone(Collection<Future> futures) { + return futures.stream().filter(Future::isDone).count(); + } + + private void gc(Repository repo, UpdateUI ui, ProgressMonitor pm, Stopwatch sw) throws IOException, ParseException { FileRepository r = (FileRepository) repo; GC gc = new GC(r); @@ -362,21 +377,6 @@ public abstract class SchemaVersion { gc.gc(); } - protected static ObjectId emptyTree(ObjectInserter oi) throws IOException { - return oi.insert(Constants.OBJ_TREE, new byte[] {}); - } - - protected static ObjectInserter getPackInserterFirst(Repository repo) { - if (repo instanceof FileRepository) { - return ((FileRepository) repo).getObjectDatabase().newPackInserter(); - } - return repo.getObjectDatabase().newInserter(); - } - - private static long countDone(Collection<Future> futures) { - return futures.stream().filter(Future::isDone).count(); - } - private class GcTask implements Runnable { final GitRepositoryManager repoManager; final Project.NameKey project; diff --git a/java/com/google/gerrit/server/schema/Schema_144.java b/java/com/google/gerrit/server/schema/Schema_144.java index 88f24c2a7c..adddc2e8d1 100644 --- a/java/com/google/gerrit/server/schema/Schema_144.java +++ b/java/com/google/gerrit/server/schema/Schema_144.java @@ -101,6 +101,7 @@ public class Schema_144 extends SchemaVersion { } inserter.flush(); bru.execute(rw, NullProgressMonitor.INSTANCE); + runGcInBackground(repoManager, allUsersName, ui); } } catch (IOException | ConfigInvalidException e) { throw new OrmException("Failed to migrate external IDs to NoteDb", e); diff --git a/java/com/google/gerrit/server/schema/Schema_146.java b/java/com/google/gerrit/server/schema/Schema_146.java index bc90c6d73d..e955bada74 100644 --- a/java/com/google/gerrit/server/schema/Schema_146.java +++ b/java/com/google/gerrit/server/schema/Schema_146.java @@ -32,7 +32,6 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.sql.Timestamp; -import java.text.ParseException; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -43,7 +42,6 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReentrantLock; -import org.eclipse.jgit.internal.storage.file.FileRepository; import org.eclipse.jgit.internal.storage.file.PackInserter; import org.eclipse.jgit.lib.BatchRefUpdate; import org.eclipse.jgit.lib.CommitBuilder; @@ -52,10 +50,8 @@ import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.ObjectReader; import org.eclipse.jgit.lib.PersonIdent; -import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; -import org.eclipse.jgit.lib.TextProgressMonitor; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevSort; import org.eclipse.jgit.revwalk.RevWalk; @@ -100,9 +96,6 @@ public class Schema_146 extends SchemaVersion { protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException, SQLException { ui.message("Migrating accounts"); Set<Entry<Account.Id, Timestamp>> accounts = scanAccounts(db, ui).entrySet(); - ui.message("Run full gc as preparation for the migration"); - gc(ui); - ui.message(String.format("... (%.3f s) full gc completed", elapsed())); Set<List<Entry<Account.Id, Timestamp>>> batches = Sets.newHashSet(Iterables.partition(accounts, 500)); ExecutorService pool = createExecutor(ui); @@ -159,9 +152,7 @@ public class Schema_146 extends SchemaVersion { inserter.flush(); bru.execute(rw, NullProgressMonitor.INSTANCE); if (inserter instanceof PackInserter && packs.incrementAndGet() % 50 == 0) { - ui.message("Run full gc"); - gc(ui); - ui.message(String.format("... (%.3f s) full gc completed", elapsed())); + runGcInBackground(repoManager, allUsersName, ui); } } showProgress(ui, migratedAccounts.addAndGet(batch.size())); @@ -183,24 +174,6 @@ public class Schema_146 extends SchemaVersion { } } - private void gc(UpdateUI ui) { - try (Repository repo = repoManager.openRepository(allUsersName)) { - if (repo instanceof FileRepository && gcLock.tryLock()) { - ProgressMonitor pm = new TextProgressMonitor(); - try { - gc(repo, ui, pm, sw); - } catch (IOException | ParseException e) { - throw new RuntimeException(e); - } finally { - gcLock.unlock(); - pm.endTask(); - } - } - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - private void rewriteUserBranch( RevWalk rw, ObjectInserter oi, |