我写了一个在树莓派3B上运行的本地PHP应用程序,其中一些PHP脚本都共享一个SQLite数据库。这是一个家庭防盗警报系统,具有电报消息传递和停电+互联网中断检测功能。 每个PHP脚本都有一个角色,一个用于传感器监视,另一个用于在布防和传感器警报时触发警报,另一个用于检测停电,一个用于侦听电报,另一个用于管理电报出站队列,这看起来可能很多,但实际上写入活动仅用于传感器监视(即使未布防时也会记录每个警报)。 无论如何,我启用了WAL日记模式。 每个脚本包括公用文件,配置文件,功能文件和db.inc.php文件,其中包含以下代码行:
$db = new SQLite3(dirname(__FILE__)."/DB/db.sqlite");
$db->exec("PRAGMA busy_timeout=5000");
$db->exec('PRAGMA journal_mode = wal;');
其中一个脚本偶尔会返回数据库锁定警告,它是管理电报出站队列的脚本,以便每秒发送不超过一条消息。任何需要通知某些内容的脚本调用的send_telegram()函数都会将传出消息保存在DB表中,该表最初将“ sent”标志设置为0:
$db->exec("INSERT INTO telegram_outbound (to_id, message, sent) VALUES ('$chatid','".SQLite3::escapeString($msg)."',0)");
(此语句有时触发锁定的警告)
同样,该脚本通过ping URL来检查Internet是否脱机或是否已恢复,并使用
保存$db->exec("INSERT INTO internet_outages (status) VALUES ($status)");
(有时会触发警告)
队列脚本每秒检查数据库一次:
$outbox=$db->query("SELECT to_id, message, id, time FROM telegram_outbound WHERE sent=0 ORDER BY id");
并调用API URL。 这样做之后,它将使用以下命令更新出站消息:
$db->exec("UPDATE telegram_outbound SET sent=1,time=datetime('now','localtime') WHERE id={$message[2]} LIMIT 1");
(有时这会引起警告)
这些语句中的任何一个都不以“过度”方式运行,所有这些语句仅在发生某些事情时才发生,我们并不是在谈论繁忙的聊天室。
这种情况并不经常发生,相反,可能每两周一次,但是我认为在负载较小且启用WAL的情况下,这种情况永远不会发生。
至少有一种方法可以调试吗?