Mini Shell
#!/opt/imh-python/bin/python3
"""locate any innodb tablespace conflicts and log them to
/home/nagios/tablespace_conflicts.json"""
import os
import json
from pathlib import Path
from collections import defaultdict
from construct import Struct, Int16ub, Int32ub, Int64ub
IBD_STRUCT = Struct(
'checksum' / Int32ub,
'page_number' / Int32ub,
'previous_page' / Int32ub,
'next_page' / Int32ub,
'last_mod_lsn' / Int64ub,
'page_type' / Int16ub,
'flush_lsn' / Int64ub,
'tbl_space' / Int32ub,
)
CONFLICTS_LOG = '/home/nagios/tablespace_conflicts.json'
def main():
"""Main: if file per table, log conflicts to `CONFLICTS_LOG`"""
data = map_innodb_tablespace_ids()
conflicts = {}
for space_id, ibd_files in data.items():
if space_id == 0:
continue
if space_id == 'missing' or len(ibd_files) > 1:
conflicts[space_id] = ibd_files
print(conflicts)
with open(f"{CONFLICTS_LOG}.tmp", 'w', encoding='utf-8') as file:
json.dump(conflicts, file, indent=4)
os.rename(f"{CONFLICTS_LOG}.tmp", CONFLICTS_LOG)
def map_innodb_tablespace_ids():
"""Build a mapping what tablespace IDs go to what ibd file"""
tablespace_ids = defaultdict(list)
for path in Path('/var/lib/mysql').glob('*/*.ibd'):
if not path.is_file():
continue
try:
with path.open('rb') as file:
ibd_head = file.read(38)
tbl_id = IBD_STRUCT.parse(ibd_head)['tbl_space']
except Exception:
tbl_id = 'missing'
tablespace_ids[tbl_id].append(str(path))
return tablespace_ids
if __name__ == '__main__':
main()
Zerion Mini Shell 1.0