class Module(MgrModule):
# latest (if db does not exist)
- SCHEMA = """
-CREATE TABLE Device (
- devid TEXT PRIMARY KEY
-) WITHOUT ROWID;
-CREATE TABLE DeviceHealthMetrics (
- time DATETIME DEFAULT (strftime('%s', 'now')),
- devid TEXT NOT NULL REFERENCES Device (devid),
- raw_smart TEXT NOT NULL,
- PRIMARY KEY (time, devid)
-);
-"""
+ SCHEMA = [
+ """
+ CREATE TABLE Device (
+ devid TEXT PRIMARY KEY
+ ) WITHOUT ROWID;
+ """,
+ """
+ CREATE TABLE DeviceHealthMetrics (
+ time DATETIME DEFAULT (strftime('%s', 'now')),
+ devid TEXT NOT NULL REFERENCES Device (devid),
+ raw_smart TEXT NOT NULL,
+ PRIMARY KEY (time, devid)
+ );
+ """
+ ]
SCHEMA_VERSIONED = [
# v1
- """
-CREATE TABLE Device (
- devid TEXT PRIMARY KEY
-) WITHOUT ROWID;
-CREATE TABLE DeviceHealthMetrics (
- time DATETIME DEFAULT (strftime('%s', 'now')),
- devid TEXT NOT NULL REFERENCES Device (devid),
- raw_smart TEXT NOT NULL,
- PRIMARY KEY (time, devid)
-);
-"""
+ [
+ """
+ CREATE TABLE Device (
+ devid TEXT PRIMARY KEY
+ ) WITHOUT ROWID;
+ """,
+ """
+ CREATE TABLE DeviceHealthMetrics (
+ time DATETIME DEFAULT (strftime('%s', 'now')),
+ devid TEXT NOT NULL REFERENCES Device (devid),
+ raw_smart TEXT NOT NULL,
+ PRIMARY KEY (time, devid)
+ );
+ """,
+ ]
]
MODULE_OPTIONS = [
done = False
with ioctx, self._db_lock, self.db:
+ self.db.execute('BEGIN;')
count = 0
for obj in ioctx.list_objects():
try:
"""
with self._db_lock, self.db:
+ self.db.execute('BEGIN;')
self._create_device(devid)
self.db.execute(SQL, (devid, json.dumps(data)))
self._prune_device_metrics()
self.log.debug(f"_get_device_metrics: {devid} {sample} {min_sample}")
with self._db_lock, self.db:
+ self.db.execute('BEGIN;')
if isample:
cursor = self.db.execute(SQL_EXACT, (devid, isample))
else:
MODULE_OPTION_DEFAULTS = {} # type: Dict[str, Any]
# Database Schema
- SCHEMA = None # type: Optional[str]
- SCHEMA_VERSIONED = None # type: Optional[List[str]]
+ SCHEMA = None # type: Optional[List[str]]
+ SCHEMA_VERSIONED = None # type: Optional[List[List[str]]]
# Priority definitions for perf counters
PRIO_CRITICAL = 10
self.appify_pool(self.MGR_POOL_NAME, 'mgr')
def create_skeleton_schema(self, db: sqlite3.Connection) -> None:
- SQL = """
+ SQL = [
+ """
CREATE TABLE IF NOT EXISTS MgrModuleKV (
key TEXT PRIMARY KEY,
value NOT NULL
) WITHOUT ROWID;
- INSERT OR IGNORE INTO MgrModuleKV (key, value) VALUES ('__version', 0);
+ """,
"""
+ INSERT OR IGNORE INTO MgrModuleKV (key, value) VALUES ('__version', 0);
+ """,
+ ]
- db.executescript(SQL)
+ for sql in SQL:
+ db.execute(sql)
def update_schema_version(self, db: sqlite3.Connection, version: int) -> None:
SQL = "UPDATE OR ROLLBACK MgrModuleKV SET value = ? WHERE key = '__version';"
if version <= 0:
self.log.info(f"creating main.db for {self.module_name}")
assert self.SCHEMA is not None
- db.executescript(self.SCHEMA)
+ for sql in self.SCHEMA:
+ db.execute(sql)
self.update_schema_version(db, 1)
else:
assert self.SCHEMA_VERSIONED is not None
raise RuntimeError(f"main.db version is newer ({version}) than module ({latest})")
for i in range(version, latest):
self.log.info(f"upgrading main.db for {self.module_name} from {i-1}:{i}")
- SQL = self.SCHEMA_VERSIONED[i]
- db.executescript(SQL)
+ for sql in self.SCHEMA_VERSIONED[i]:
+ db.execute(sql)
if version < latest:
self.update_schema_version(db, latest)
kv = self.get_module_option('sqlite3_killpoint')
with db:
+ db.execute('BEGIN;')
self.create_skeleton_schema(db)
if kv == 1:
os._exit(120)
self.create_mgr_pool()
uri = f"file:///{self.MGR_POOL_NAME}:{self.module_name}/main.db?vfs=ceph";
self.log.debug(f"using uri {uri}")
- db = sqlite3.connect(uri, check_same_thread=False, uri=True)
+ try:
+ db = sqlite3.connect(uri, check_same_thread=False, uri=True, autocommit=False) # type: ignore[call-arg]
+ except TypeError:
+ db = sqlite3.connect(uri, check_same_thread=False, uri=True, isolation_level=None)
# if libcephsqlite reconnects, update the addrv for blocklist
with db:
cur = db.execute('SELECT json_extract(ceph_status(), "$.addr");')