#c #c #database #sqlite #locking
#c #c #База данных #sqlite #блокировка
Вопрос:
У меня есть база данных sqlite3 в некоторой системе, которую мне нужно загрузить во время текущей работы. Остановка или приостановка процессов доступа не является вариантом. Итак, насколько я понимаю, мне нужно сохранить ОБЩУЮ блокировку (как описано вhttp://www.sqlite.org/lockingv3.html ) в БД во время загрузки, чтобы избежать изменений и повреждения БД во время загрузки. Как мне явно получить такую блокировку? Загрузка контролируется из C -program, поэтому мне нужно было бы установить там блокировку.
РЕДАКТИРОВАТЬ: тхкала предложил создать дамп базы данных. Но я бы предпочел найти решение с блокировкой, потому что я не уверен, будет ли достаточно памяти для полной копии базы данных.
Ответ №1:
Нет, нет. нет и нет!
Возиться с блокировками и копировать файлы вручную — это старый способ делать вещи. У SQLite теперь есть соответствующий API резервного копирования, который вы можете использовать. Это рекомендуемый способ создания онлайновых копий базы данных SQLite — вы можете использовать его для создания копии базы данных, которую затем можно загрузить в удобное для вас время.
Редактировать:
Если вам абсолютно необходимо использовать блокировку, вы можете использовать метод, описанный здесь — возможно, после перевода на C:
-
Откройте базу данных
-
Используйте
BEGIN IMMEDIATE
инструкцию для получения общей блокировки. -
Скопируйте / загрузите файлы вручную — убедитесь, что вы ничего не пропустили. Существуют, по крайней мере, файл базы данных, файл журнала и, возможно, файл WAL. Возможно, вы захотите поместить базу данных в отдельный каталог, чтобы упростить задачу.
-
ROLLBACK
транзакция, которую вы только что начали.
Я понимаю, как этот метод может быть полезен в некоторых случаях, но я должен повторить, что это больше не рекомендуемый метод.
Комментарии:
1. Не знал об API резервного копирования, очень приятно!
2. Использование API резервного копирования является проблемой, поскольку я не уверен, достаточно ли у меня свободного места для создания полной копии базы данных.
Ответ №2:
Я как бы упустил из виду решение: начать транзакцию с
BEGIN IMMEDIATE TRANSCTION
и завершите это
END TRANSACTION
чтобы получить блокировку. IMMEDIATE
Ключевые слова не заданы по умолчанию, и база данных уже заблокирована (получена ЗАРЕЗЕРВИРОВАННАЯ блокировка), когда вызов возвращается.
Ответ №3:
Решение здесь неверно, оставляя его для потомков и для людей, чтобы узнать, почему это плохая идея.
Я думаю, вам также может сойти с рук копирование базы данных вместе с журналом. (скопируйте как базу данных, так и журнал в файлы tmp, а затем загрузите их) Затем на удаленном конце попробуйте открыть эту базу данных, и она исправится сама. Это при условии, что приложение использует правильные транзакции.
Пожалуйста, прочитайте комментарии ниже, которые объясняют, почему это неправильно:
Суть в том, что вы можете скопировать базу данных и журнал, но только в том случае, если вы можете получить ОБЕ базы данных в один и тот же момент времени.
Что более или менее невозможно.
Комментарии:
1. НЕТ! НЕТ! НЕТ! Это рецепт повреждения данных! Журналы БД требуют правильной семантики файловой системы, которой У вас НЕТ при копировании файлов по сети. -1
2. Проблема 1: через Интернет файл базы данных может быть загружен через секунды или даже минуты после / до журнала
3. Я не думаю, что это сработает, если во время копирования есть доступ на запись.
4. Но разве журнал не должен предотвращать повреждение данных? Я явно сказал сначала скопировать указанные файлы, чтобы о секундах не могло быть и речи.
5. Проблема 2. Вполне возможно, что при загрузке базы данных начало файла будет в транзакции N, а к моменту завершения его конец будет в транзакции N M…