Skip to content

Commit 2a3be86

Browse files
Add database support script
1 parent c56d906 commit 2a3be86

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import argparse
2+
import time
3+
from contextlib import closing
4+
5+
import mysql.connector
6+
7+
"""
8+
This script will delete rows from the archive engine sample table
9+
that are more than `history` days old in batcehs of `limit` to improve performance
10+
11+
This would normally be run after a database backup and be used instead of truncating
12+
the entire database. It will not reduce the size of the database on disk, but the
13+
deleted rows can be re-used by teh database and so the file should not grow
14+
"""
15+
16+
17+
def main() -> None:
18+
parser = argparse.ArgumentParser(description="Set query options")
19+
parser.add_argument(
20+
"--host", dest="host", action="store", help="Host (default: localhost)", default="127.0.0.1"
21+
)
22+
parser.add_argument(
23+
"--limit",
24+
dest="limit",
25+
action="store",
26+
type=int,
27+
help="Rows to delete each query (default: 1000)",
28+
default=1000,
29+
)
30+
parser.add_argument(
31+
"--sleep",
32+
dest="sleep",
33+
action="store",
34+
type=float,
35+
help="Seconds to sleep between queries (default: 0.5)",
36+
default=0.5,
37+
)
38+
parser.add_argument(
39+
"--history",
40+
dest="history",
41+
action="store",
42+
type=int,
43+
help="How many days to keep (default: 7)",
44+
default=7,
45+
)
46+
parser.add_argument(
47+
"--password", dest="password", action="store", help="mysql root password", default=""
48+
)
49+
parser.add_argument("--dry-run", dest="dry_run", action="store_true", help="dry run")
50+
51+
args = parser.parse_args()
52+
53+
with closing(
54+
mysql.connector.connect(
55+
user="root", password=args.password, host=args.host, database="archive"
56+
)
57+
) as conn:
58+
# this is so we don't cache query results and keep getting the same answer
59+
conn.autocommit = True
60+
61+
with closing(conn.cursor(prepared=True)) as c:
62+
c.execute("SET SQL_LOG_BIN=0") # disable any binary logging for this session
63+
print(f"Looking for sample_id corresponding to {args.history} days ago")
64+
c.execute(
65+
"SELECT MAX(sample_id) FROM sample WHERE smpl_time < TIMESTAMPADD(DAY, -?, NOW())",
66+
(args.history,),
67+
)
68+
sample_id = c.fetchone()[0]
69+
c.execute(
70+
"SELECT COUNT(sample_id) FROM sample "
71+
"WHERE smpl_time < TIMESTAMPADD(DAY, -?, NOW())",
72+
(args.history,),
73+
)
74+
count_sample_id = c.fetchone()[0]
75+
print(
76+
f"ID of last row to delete is {sample_id} and there are {count_sample_id} rows "
77+
f"-> {int(1 + count_sample_id / args.limit)} delete operations"
78+
)
79+
print(
80+
f"This will take at least {args.sleep * count_sample_id / args.limit:.1f} "
81+
"seconds based on sleep time alone"
82+
)
83+
if args.dry_run:
84+
print("Exiting as dry-run")
85+
return
86+
rowcount = 1
87+
it = 0
88+
while rowcount > 0:
89+
c.execute(f"DELETE FROM sample WHERE sample_id < {sample_id} LIMIT {args.limit}")
90+
rowcount = c.rowcount
91+
print(f"{it % 10}", end="", flush=True)
92+
it += 1
93+
time.sleep(args.sleep)
94+
print("")
95+
96+
97+
if __name__ == "__main__":
98+
main()

0 commit comments

Comments
 (0)