From 0d80d93576be7f6ee6c7955f0b921b13dbe758b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E5=94=AF=20A06?= Date: Wed, 9 Sep 2026 23:02:52 +0800 Subject: [PATCH] =?UTF-8?q?fix(db-monitor):=20=E5=BC=83=E7=94=A8=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=20CLI=20sqlite3=203.45.1=20=E2=86=92=20python3=203.53?= =?UTF-8?q?.1=20mode=3Dro=20+=20=E4=BF=AE=20db=20=E8=AE=A1=E6=95=B0?= =?UTF-8?q?=E7=A9=BA=E6=98=BE=E7=A4=BA=201=20=E7=9A=84=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2026-09-09: /usr/bin/sqlite3 3.45.1 有 WAL-reset bug(#69784, vuln 3.7~3.51.2), 两代 SQLite 交替操作是 state.db 反复损坏元凶 → db-monitor 巡检也改 python3 mode=ro 与 gateway 同版本。实跑验证 4 库全 ok。顺修: DB_ALERT 空时 echo|wc -l 计 1 的历史显示 bug → grep -c 正确计 0。 --- scripts/db-monitor.sh | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/scripts/db-monitor.sh b/scripts/db-monitor.sh index 43ee9cc1..2f391a86 100755 --- a/scripts/db-monitor.sh +++ b/scripts/db-monitor.sh @@ -39,13 +39,28 @@ do continue fi # 全量 integrity_check(2026-09-06 起不用 quick_check——它会漏检深层页引用/FTS 索引错误) - # -readonly: 只读打开绝不触发 recovery; WAL 库按一致快照读, live 库无需停机 + # python3 sqlite3 3.53.1 + mode=ro:与 gateway 同版本,只读绝不触发 recovery,WAL 库一致快照读,live 库无需停机 + # 2026-09-09:弃用 /usr/bin/sqlite3 3.45.1(WAL-reset bug #69784,3.7.0~3.51.2 vulnerable)——两代 SQLite 交替操作是反复损坏元凶 # 大文件给足超时; 记录退出码供诊断 rc=0 if [ "$size" -gt 104857600 ]; then - timeout 120 sqlite3 -readonly "$db" "PRAGMA integrity_check;" > /tmp/dbmon-check-$$.tmp 2>&1 || rc=$? + timeout 120 python3 - "$db" <<'PY' > /tmp/dbmon-check-$$.tmp 2>&1 || rc=$? +import sqlite3, sys +c = sqlite3.connect(f"file:{sys.argv[1]}?mode=ro", uri=True, timeout=30) +try: + print(c.execute("PRAGMA integrity_check;").fetchone()[0]) +finally: + c.close() +PY else - timeout 20 sqlite3 -readonly "$db" "PRAGMA integrity_check;" > /tmp/dbmon-check-$$.tmp 2>&1 || rc=$? + timeout 20 python3 - "$db" <<'PY' > /tmp/dbmon-check-$$.tmp 2>&1 || rc=$? +import sqlite3, sys +c = sqlite3.connect(f"file:{sys.argv[1]}?mode=ro", uri=True, timeout=30) +try: + print(c.execute("PRAGMA integrity_check;").fetchone()[0]) +finally: + c.close() +PY fi result=$(head -1 /tmp/dbmon-check-$$.tmp) rm -f /tmp/dbmon-check-$$.tmp @@ -57,9 +72,11 @@ do fi done -# 3. 写入日志 +# 3. 写入日志(DB_ALERT 为空时计 0——2026-09-09 修:原 echo -e "" | wc -l 空也计 1,永远显示 db=1) TS=$(date '+%Y-%m-%d %H:%M:%S') -echo "[$TS] mem=${MEM_FREE}M swap=${SWAP_USED}/${SWAP_TOTAL}M db=$(echo -e "$DB_ALERT" | wc -l) issues" >> "$LOG" +db_issue_cnt=0 +[ -n "$DB_ALERT" ] && db_issue_cnt=$(printf '%b' "$DB_ALERT" | grep -c . || true) +echo "[$TS] mem=${MEM_FREE}M swap=${SWAP_USED}/${SWAP_TOTAL}M db=${db_issue_cnt} issues" >> "$LOG" # 4. 报警逻辑(异常时飞书,正常时静默) ALERT_TEXT="${MEM_ALERT}${DB_ALERT}"