PHP возвращает предупреждение: SQLite3 :: exec (): база данных заблокирована даже в WAL journal_mode - PullRequest
0 голосов
/ 25 сентября 2019

Я написал локальное PHP-приложение, работающее на Raspberry Pi 3B, где некоторые 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 (), вызываемая любым сценарием, которому необходимо что-то уведомить, сохраняет исходящее сообщение в таблице БД, в то время как флаг «sent» изначально установлен в 0:

$db->exec("INSERT INTO telegram_outbound (to_id, message, sent) VALUES ('$chatid','".SQLite3::escapeString($msg)."',0)");

(иногда это вызывает блокированное предупреждение

Кроме того, тот же сценарий проверяет, находится ли Интернет в автономном режиме или он снова подключен, отправляя эхо-запрос на URL-адрес, и сохраняет его с помощью

$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");

и вызывает URL-адрес API.После этого он обновляет исходящее сообщение следующим образом:

$db->exec("UPDATE telegram_outbound SET sent=1,time=datetime('now','localtime') WHERE id={$message[2]} LIMIT 1");

(иногда это вызывает предупреждение)

Ни один из этих операторов не выполняется "чрезмерно", все они только происходяткогда что-то происходит, мы не говорим о загруженном чате.

Это случается не часто, наоборот, это может происходить раз в две недели, но я думаю, что с небольшой нагрузкой,и с включенным WAL это никогда не должно происходить.

Есть ли способ хотя бы отладить это?

...