mirror of
				https://github.com/9001/copyparty.git
				synced 2025-10-31 04:32:20 -06:00 
			
		
		
		
	
		
			
				
	
	
		
			108 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			108 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
| #!/usr/bin/env python3
 | |
| 
 | |
| import os
 | |
| import sqlite3
 | |
| import sys
 | |
| import traceback
 | |
| 
 | |
| 
 | |
| """
 | |
| when the up2k-database is stored on a zfs volume, this may give
 | |
| slightly higher performance (actual gains not measured yet)
 | |
| 
 | |
| NOTE: must be applied in combination with the related advice in the openzfs documentation;
 | |
| https://openzfs.github.io/openzfs-docs/Performance%20and%20Tuning/Workload%20Tuning.html#database-workloads
 | |
| and see specifically the SQLite subsection
 | |
| 
 | |
| it is assumed that all databases are stored in a single location,
 | |
| for example with `--hist /var/store/hists`
 | |
| 
 | |
| three alternatives for running this script:
 | |
| 
 | |
| 1. copy it into /var/store/hists and run "python3 zfs-tune.py s"
 | |
|     (s = modify all databases below folder containing script)
 | |
| 
 | |
| 2. cd into /var/store/hists and run "python3 ~/zfs-tune.py w"
 | |
|     (w = modify all databases below current working directory)
 | |
| 
 | |
| 3. python3 ~/zfs-tune.py /var/store/hists
 | |
| 
 | |
| if you use docker, run copyparty with `--hist /cfg/hists`, copy this script into /cfg, and run this:
 | |
| podman run --rm -it --entrypoint /usr/bin/python3 ghcr.io/9001/copyparty-ac /cfg/zfs-tune.py s
 | |
| 
 | |
| """
 | |
| 
 | |
| 
 | |
| PAGESIZE = 65536
 | |
| 
 | |
| 
 | |
| # borrowed from copyparty; short efficient stacktrace for errors
 | |
| def min_ex(max_lines: int = 8, reverse: bool = False) -> str:
 | |
|     et, ev, tb = sys.exc_info()
 | |
|     stb = traceback.extract_tb(tb) if tb else traceback.extract_stack()[:-1]
 | |
|     fmt = "%s:%d <%s>: %s"
 | |
|     ex = [fmt % (fp.split(os.sep)[-1], ln, fun, txt) for fp, ln, fun, txt in stb]
 | |
|     if et or ev or tb:
 | |
|         ex.append("[%s] %s" % (et.__name__ if et else "(anonymous)", ev))
 | |
|     return "\n".join(ex[-max_lines:][:: -1 if reverse else 1])
 | |
| 
 | |
| 
 | |
| def set_pagesize(db_path):
 | |
|     try:
 | |
|         # check current page_size
 | |
|         with sqlite3.connect(db_path) as db:
 | |
|             v = db.execute("pragma page_size").fetchone()[0]
 | |
|             if v == PAGESIZE:
 | |
|                 print(" `-- OK")
 | |
|                 return
 | |
| 
 | |
|         # https://www.sqlite.org/pragma.html#pragma_page_size
 | |
|         #  `- disable wal; set pagesize; vacuum
 | |
|         #      (copyparty will reenable wal if necessary)
 | |
| 
 | |
|         with sqlite3.connect(db_path) as db:
 | |
|             db.execute("pragma journal_mode=delete")
 | |
|             db.commit()
 | |
| 
 | |
|         with sqlite3.connect(db_path) as db:
 | |
|             db.execute(f"pragma page_size = {PAGESIZE}")
 | |
|             db.execute("vacuum")
 | |
| 
 | |
|         print(" `-- new pagesize OK")
 | |
| 
 | |
|     except Exception:
 | |
|         err = min_ex().replace("\n", "\n -- ")
 | |
|         print(f"FAILED: {db_path}\n -- {err}")
 | |
| 
 | |
| 
 | |
| def main():
 | |
|     top = os.path.dirname(os.path.abspath(__file__))
 | |
|     cwd = os.path.abspath(os.getcwd())
 | |
|     try:
 | |
|         x = sys.argv[1]
 | |
|     except:
 | |
|         print(f"""
 | |
| this script takes one mandatory argument:
 | |
| specify 's' to start recursing from folder containing this script file ({top})
 | |
| specify 'w' to start recursing from the current working directory ({cwd})
 | |
| specify a path to start recursing from there
 | |
| """)
 | |
|         sys.exit(1)
 | |
| 
 | |
|     if x.lower() == "w":
 | |
|         top = cwd
 | |
|     elif x.lower() != "s":
 | |
|         top = x
 | |
| 
 | |
|     for dirpath, dirs, files in os.walk(top):
 | |
|         for fname in files:
 | |
|             if not fname.endswith(".db"):
 | |
|                 continue
 | |
|             db_path = os.path.join(dirpath, fname)
 | |
|             print(db_path)
 | |
|             set_pagesize(db_path)
 | |
| 
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     main()
 |