Мы используем sql -lite для перезаписи URL в [apache веб-сервере] с использованием [mod_rewrite]: идея проста: ask sql -lite для перевода полученного URL
... для этого мы используем [sqlite] (v3.22) только с таблицей с двумя столбцами: URL-адрес и переписанный URL-адрес
Перезапись настроена как описано в официальной документации [mod_rewrite]:
RewriteMap translate_url_map "dbd:SELECT tranlate_url FROM rewrite WHERE url = %s"
RewriteRule "^/(.*)" "${translate_url_map:$1}"
Таблица sqlite обновляется нашим процессом [publi sh], поэтому каждый раз, когда контент публикуется, запись вставляется в таблицу [tranlate_url]
(fastdbd НЕ используется, поскольку, хотя он более эффективен, он не будет записывать изменения в базу данных, пока сервер не будет перезапущен)
Таким образом, [sqlite] доступен ДВА процесса :
- [apache веб-сервер], который читает данные в таблице [tranlate_url]
- Внешний [publi sh process] что записывает данные в таблицу [translate_url]
Проблема в том, что если установлен режим ведения журнала по умолчанию DELETE, веб-сервер [apache] жалуется с ошибкой database is locked
, когда писатель (издатель) вставляет данные.
Очевидно, что если только [apache веб-сервер] читатели имеют доступ к базе данных, все работает правильно.
Итак, проблема в следующем: как настроить sqlite для процесса чтения и другого процесса записи
На официальной странице написано:
WAL mode permits simultaneous readers and writers.
It can do this because changes do not overwrite the original database file, but rather go into the separate write-ahead log file.
That means that readers can continue to read the old, original, unaltered content from the original database file while the writer is appending to the write-ahead log.
In WAL mode, SQLite exhibits "snapshot isolation".
When a read transaction starts, that reader continues to see an unchanging "snapshot" of the database file as it existed at the moment in time when the read transaction started.
Any write transactions that commit while the read transaction is active are still invisible to the read transaction, because the reader is seeing a snapshot of database file from a prior moment in time."
However, if we set the WAL journaling mode (sqlite3 testPaths.db "PRAGMA journal_mode=WAL;") and several processes query to the database at the same time (each one in a different thread) we get the message "Error: database is locked" even though no writers are active.
Мы попробовал простой тестовый пример за пределами [apache веб-сервера]:
Создайте БД и вставьте кучу записей:
sqlite3 testPaths.db "create table paths(key varchar(80), value varchar(80));"
sqlite3 testPaths.db "create unique index paths_index on paths(key);"
sqlite3 testPaths.db "PRAGMA journal_mode=WAL;";
sqlite3 testPaths.db "insert into paths values ('path1', 'translated_path1');";
sqlite3 testPaths.db "insert into paths values ('path2', 'translated_path2');";
sqlite3 testPaths.db "insert into paths values ('path3', 'translated_path3');";
sqlite3 testPaths.db "insert into paths values ('path4', 'translated_path4');";
sqlite3 testPaths.db "insert into paths values ('path5', 'translated_path5');";
Запустите скрипт, который просто выбирает строку в бесконечности l oop:
sqlite3 testPaths.db "select * from paths where key='path2'";
Если при запуске этого скрипта мы запускаем другой скрипт, который просто вставляет другую строку:
sqlite3 testPaths.db "insert into paths values ('path99', 'translated_path99');";
, мы получаем ошибку database is locked
при [read] script
... но это не должно иметь место с режимом WAL, не так ли?
Кажется, что режим WAL должен быть установлен при создании соединение, но как это можно сделать на [apache веб-сервере] или в нашем процессе публикации ??