Merge ~juliank/autopkgtest-cloud:sqlite3-backup-api into autopkgtest-cloud:master

Proposed by Julian Andres Klode
Status: Merged
Merge reported by: Julian Andres Klode
Merged at revision: 3c4bc222d21a8f34ac8ab291f729c5ef2d32e374
Proposed branch: ~juliank/autopkgtest-cloud:sqlite3-backup-api
Merge into: autopkgtest-cloud:master
Diff against target: 48 lines (+17/-9)
1 file modified
charms/focal/autopkgtest-web/webcontrol/publish-db (+17/-9)
Reviewer Review Type Date Requested Status
Dave Jones (community) Approve
Review via email: mp+402216@code.launchpad.net

Description of the change

Code not run yet, needs testing on staging to make sure it works. Twice as slow as before, but this should take care of proper locking.

To post a comment you must log in.
Revision history for this message
Julian Andres Klode (juliank) wrote :

Updated to run in steps of 16 pages, such that the lock can be released in between. The database currently has 17k iterations this way, giving plenty of time for other threads, maybe too wasteful (2/17k seconds per lock).

Revision history for this message
Julian Andres Klode (juliank) wrote :

Updated for 1024 pages per iteration (267 iterations, so 2/267 or 7ms per iteration followed by 250ms sleep in case someone else wants to write)

Revision history for this message
Julian Andres Klode (juliank) wrote :

Readjusted to move the database copying into init_db(), because we need to copy the db before updating the schema. Verified it works on staging now.

Revision history for this message
Dave Jones (waveform) wrote :

Looks good to me, particularly with the bigger pages value (so there's no more than a ~25% premium on an otherwise uninterrupted copy time). +1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/charms/focal/autopkgtest-web/webcontrol/publish-db b/charms/focal/autopkgtest-web/webcontrol/publish-db
2index 666ff81..6d6caae 100755
3--- a/charms/focal/autopkgtest-web/webcontrol/publish-db
4+++ b/charms/focal/autopkgtest-web/webcontrol/publish-db
5@@ -22,11 +22,20 @@ archive_url = "http://archive.ubuntu.com/ubuntu"
6 components = ["main", "restricted", "universe", "multiverse"]
7
8
9-def init_db(path, path_current):
10+def init_db(path, path_current, path_rw):
11 """Create DB if it does not exist, and connect to it"""
12
13 db = sqlite3.connect(path)
14 db_current = sqlite3.connect(path_current)
15+ db_rw = sqlite3.connect("file:%s?mode=ro" % path_rw, uri=True)
16+
17+ # Copy r/w database over
18+ with db:
19+ # Specifying a number of pages allows Python to let sqlite sleep,
20+ # in turn allowing other clients to write to the db again.
21+ db_rw.backup(db, pages=128 * 1024)
22+ db_rw.close()
23+
24 c = db.cursor()
25 current_c = db_current.cursor()
26 try:
27@@ -181,14 +190,13 @@ if __name__ == "__main__":
28 target = config["web"]["database_ro"]
29 target_new = "{}.new".format(target)
30
31- with open(config["web"]["database"], "rb") as src:
32- with open(target_new, "wb") as dest:
33- fcntl.flock(dest, fcntl.LOCK_EX | fcntl.LOCK_NB)
34- shutil.copyfileobj(src, dest)
35- dest.flush()
36- os.fsync(dest.fileno())
37-
38- db_con = init_db(target_new, target)
39+ try:
40+ # systemd makes sure to not run us in parallel, so we can safely
41+ # delete any leftover file.
42+ os.unlink(target_new)
43+ except FileNotFoundError:
44+ pass
45+ db_con = init_db(target_new, target, config["web"]["database"])
46
47 for row in db_con.execute("SELECT DISTINCT release FROM test"):
48 get_sources(db_con, row[0])

Subscribers

People subscribed via source and target branches