Блокировка базы данных sqlite3 для загрузки файла

#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…