g1t/services/repos/migrations/0014_namespace_moves.sql

62 lines2,754 bytesCodeBlame

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Repositories shard across git store namespaces, move between them, and can keep to the EU; a namespace can be served read-only from the self-hosted git store, rebuilt from the nightly backups (#20, #25)1-- Moving a repository from one git store namespace to another
2-- (src/moves.rs; docs/ARTIFACTS.md, R7). Additive; nothing is backfilled,
3-- and nothing moves until an operator asks.
4--
5-- writes_paused_until: milliseconds since the epoch. Until then nothing
6-- writes to the repository: pushes wait up to 20 seconds for it to pass,
7-- then are told to try again; merges, commits from the web and handed-out
8-- push credentials the same. Set while a move copies the repository and
9-- its pull requests' working copies, cleared when it ends either way, and
10-- it passes on its own should a move die half way.
11-- writes_paused_for: why, in words (`moving to g1t-us-1`).
12ALTER TABLE repos ADD COLUMN writes_paused_until INTEGER;
13ALTER TABLE repos ADD COLUMN writes_paused_for TEXT;
14
15-- One row per move asked for. The hourly sweep (`23 * * * *`) runs the
16-- queued ones, oldest first, one at a time.
17--
18-- status: queued | moving | moved | failed | cleaned | diverged.
19-- moved: the repository reads and writes in its new namespace; the copy
20-- in the old one is kept MOVE_KEEP_DAYS (7) in case of a rollback, then
21-- deleted (cleaned). diverged: the old copy's refs changed after the
22-- move (a push that slipped past the pause), so it is kept and an
23-- operator reconciles it.
24-- to_namespace: where it goes.
25-- requested_by: who asked, in words.
26-- note: the last thing that happened (why it waits, why it failed).
27CREATE TABLE repo_moves (
28 id TEXT PRIMARY KEY,
29 repo_id TEXT NOT NULL,
30 to_namespace TEXT NOT NULL,
31 status TEXT NOT NULL DEFAULT 'queued',
32 requested_by TEXT,
33 queued_ms INTEGER NOT NULL,
34 started_ms INTEGER,
35 finished_ms INTEGER,
36 cleaned_ms INTEGER,
37 attempts INTEGER NOT NULL DEFAULT 0,
38 note TEXT
39);
40CREATE INDEX repo_moves_queue ON repo_moves (status, queued_ms);
41-- At most one move in hand per repository.
42CREATE UNIQUE INDEX repo_moves_active ON repo_moves (repo_id) WHERE status IN ('queued', 'moving');
43
44-- What each move copied: the repository and each of its pull requests'
45-- working copies, from one key to another, with every ref as copied.
46--
47-- name: the key's name without its namespace. A name with a copy not yet
48-- cleaned stays taken (registry.rs `claim_store_key`), so a new
49-- repository never adopts an old copy left behind.
50-- refs: JSON object, ref name to object, as copied; the old copy is
51-- deleted only while it still says the same.
52CREATE TABLE repo_move_copies (
53 move_id TEXT NOT NULL,
54 repo_id TEXT NOT NULL,
55 from_key TEXT NOT NULL,
56 to_key TEXT NOT NULL,
57 name TEXT NOT NULL,
58 refs TEXT NOT NULL DEFAULT '{}',
59 cleaned_ms INTEGER,
60 PRIMARY KEY (move_id, repo_id)
61);
62CREATE INDEX repo_move_copies_name ON repo_move_copies (name) WHERE cleaned_ms IS NULL;