Spec-Zone.ru › SQLite

API резервного копирования баз данных

API резервного копирования баз данных.

sqlite3_backup *sqlite3_backup_init(
  sqlite3 *pDest,                        /* Destination database handle */
  const char *zDestName,                 /* Destination database name */
  sqlite3 *pSource,                      /* Source database handle */
  const char *zSourceName                /* Source database name */
);
int sqlite3_backup_step(sqlite3_backup *p, int nPage);
int sqlite3_backup_finish(sqlite3_backup *p);
int sqlite3_backup_remaining(sqlite3_backup *p);
int sqlite3_backup_pagecount(sqlite3_backup *p);

API резервного копирования копирует содержимое одной базы данных в другую. Он полезен для создания резервных копий баз данных или для копирования баз данных в оперативной памяти в постоянные файлы или из них.

См. также: Использование API резервного копирования SQLite

SQLite держит открытую транзакцию записи в файле целевой базы данных на протяжении всего процесса резервного копирования. База данных источника заблокирована для чтения только во время чтения; она не заблокирована постоянно на протяжении всего процесса резервного копирования. Таким образом, резервное копирование может выполняться на активной базе данных источника без предотвращения других подключений к базе данных от чтения или записи в базу данных источника во время выполнения резервного копирования.

Для выполнения операции резервного копирования:

  1. sqlite3_backup_init() вызывается один раз для инициализации резервного копирования,
  2. sqlite3_backup_step() вызывается один или несколько раз для передачи данных между двумя базами данных, и, наконец,
  3. sqlite3_backup_finish() вызывается для освобождения всех ресурсов, связанных с операцией резервного копирования.
Должен быть ровно один вызов sqlite3_backup_finish() для каждого успешного вызова sqlite3_backup_init().

sqlite3_backup_init()

Аргументы D и N в sqlite3_backup_init(D,N,S,M) — это соединение с базой данных, связанное с целевой базой данных, и имя базы данных соответственно. Имя базы данных — "main" для основной базы данных, "temp" для временной базы данных или имя, указанное после ключевого слова AS в операторе ATTACH для присоединённой базы данных. Аргументы S и M, переданные в sqlite3_backup_init(D,N,S,M), идентифицируют соединение с базой данных и имя базы данных базы данных источника соответственно. Источник и целевые соединения с базой данных (параметры S и D) должны быть разными, иначе sqlite3_backup_init(D,N,S,M) завершится с ошибкой.

Вызов sqlite3_backup_init() завершится неудачей, вернув NULL, если уже открыта транзакция чтения или чтения/записи в целевой базе данных.

Если при выполнении sqlite3_backup_init(D,N,S,M) возникнет ошибка, то возвращается NULL, а код ошибки и сообщение об ошибке сохраняются в целевом соединении с базой данных D. Код ошибки и сообщение об ошибке для неудачного вызова sqlite3_backup_init() можно получить с помощью функций sqlite3_errcode(), sqlite3_errmsg() и/или sqlite3_errmsg16(). Успешный вызов sqlite3_backup_init() возвращает указатель на объект sqlite3_backup. Объект sqlite3_backup может использоваться с функциями sqlite3_backup_step() и sqlite3_backup_finish() для выполнения указанной операции резервного копирования.

sqlite3_backup_step()

Функция sqlite3_backup_step(B,N) скопирует до N страниц между базами данных источника и назначения, указанными объектом sqlite3_backup B. Если N отрицательно, копируются все оставшиеся страницы источника. Если sqlite3_backup_step(B,N) успешно скопирует N страниц и ещё есть страницы для копирования, то функция вернёт SQLITE_OK. Если sqlite3_backup_step(B,N) успешно завершит копирование всех страниц из источника в назначение, то она вернёт SQLITE_DONE. Если при выполнении sqlite3_backup_step(B,N) возникнет ошибка, то возвращается код ошибки. Помимо SQLITE_OK и SQLITE_DONE, вызов sqlite3_backup_step() может вернуть SQLITE_READONLY, SQLITE_NOMEM, SQLITE_BUSY, SQLITE_LOCKED или расширенный код ошибки SQLITE_IOERR_XXX.

Функция sqlite3_backup_step() может вернуть SQLITE_READONLY, если

  1. целевая база данных была открыта только для чтения, или
  2. целевая база данных использует журналирование write-ahead-log, и размеры страниц назначения и источника отличаются, или
  3. целевая база данных — база данных в оперативной памяти, и размеры страниц назначения и источника отличаются.

Если sqlite3_backup_step() не может получить необходимую файловую блокировку, то вызывается функция обработчика занятости (если она указана). Если обработчик занятости возвращает ненулевое значение до того, как блокировка станет доступной, то вызывающему объекту возвращается SQLITE_BUSY. В этом случае вызов sqlite3_backup_step() можно повторить позже. Если соединение с базой данных источника используется для записи в базу данных источника во время вызова sqlite3_backup_step(), то сразу возвращается SQLITE_LOCKED. Опять же, в этом случае вызов sqlite3_backup_step() можно повторить позже. Если возвращается SQLITE_IOERR_XXX, SQLITE_NOMEM или SQLITE_READONLY, то нет смысла повторять вызов sqlite3_backup_step(). Эти ошибки считаются фатальными. Приложение должно принять тот факт, что операция резервного копирования завершилась неудачно, и передать дескриптор операции резервного копирования в sqlite3_backup_finish() для освобождения связанных ресурсов.

Первый вызов sqlite3_backup_step() получает эксклюзивную блокировку целевого файла. Эксклюзивная блокировка не освобождается до тех пор, пока не будет вызван sqlite3_backup_finish() или пока операция резервного копирования не будет завершена, и sqlite3_backup_step() не вернёт SQLITE_DONE. Каждый вызов sqlite3_backup_step() получает совместную блокировку на базе данных источника, которая длится на протяжении всего вызова sqlite3_backup_step(). Поскольку база данных источника не блокируется между вызовами sqlite3_backup_step(), база данных источника может быть изменена в середине процесса резервного копирования. Если база данных источника изменяется внешним процессом или через соединение с базой данных, отличное от используемого операцией резервного копирования, то резервное копирование автоматически перезапускается следующим вызовом sqlite3_backup_step(). Если база данных источника изменяется с помощью того же соединения с базой данных, что и операция резервного копирования, то база данных резервного копирования автоматически обновляется одновременно.

sqlite3_backup_finish()

Когда sqlite3_backup_step() вернул SQLITE_DONE или когда приложение хочет отказаться от операции резервного копирования, приложение должно уничтожить sqlite3_backup, передав его в sqlite3_backup_finish(). Интерфейс sqlite3_backup_finish() освобождает все ресурсы, связанные с объектом sqlite3_backup. Если sqlite3_backup_step() ещё не вернул SQLITE_DONE, то любая активная транзакция записи в целевой базе данных откатывается. Объект sqlite3_backup становится недействительным и больше не может использоваться после вызова sqlite3_backup_finish().

Значение, возвращаемое sqlite3_backup_finish, — SQLITE_OK, если не произошло ошибок sqlite3_backup_step(), независимо от того, завершил ли sqlite3_backup_step() свою работу или нет. Если во время любого предыдущего вызова sqlite3_backup_step() для того же объекта sqlite3_backup произошла ошибка из-за отсутствия памяти или ошибки ввода-вывода, то sqlite3_backup_finish() возвращает соответствующий код ошибки.

Возврат SQLITE_BUSY или SQLITE_LOCKED из sqlite3_backup_step() — это не постоянная ошибка и не влияет на значение, возвращаемое sqlite3_backup_finish().

sqlite3_backup_remaining() и sqlite3_backup_pagecount()

Функция sqlite3_backup_remaining() возвращает количество страниц, которые ещё нужно скопировать, по завершении последнего вызова sqlite3_backup_step(). Функция sqlite3_backup_pagecount() возвращает общее количество страниц в базе данных источника по завершении последнего вызова sqlite3_backup_step(). Значения, возвращаемые этими функциями, обновляются только вызовом sqlite3_backup_step(). Если база данных источника изменяется таким образом, что изменяет размер базы данных источника или оставшееся количество страниц, эти изменения не отражаются в выводе sqlite3_backup_pagecount() и sqlite3_backup_remaining() до следующего вызова sqlite3_backup_step().

Одновременное использование дескрипторов баз данных

Соединение с базой данных источника может использоваться приложением для других целей во время или в процессе инициализации операции резервного копирования. Если SQLite скомпилирован и настроен для поддержки потокобезопасных соединений с базой данных, то соединение с базой данных источника можно использовать параллельно из других потоков.

Однако приложение должно гарантировать, что целевое соединение с базой данных не передаётся ни одному другому API (ни одним потоком) после вызова sqlite3_backup_init() и до соответствующего вызова sqlite3_backup_finish(). SQLite в настоящее время не проверяет, не обращается ли приложение некорректно к целевому соединению с базой данных, поэтому код ошибки не сообщается, но операции могут тем не менее работать неправильно. Использование целевого соединения с базой данных во время выполнения резервного копирования также может привести к тупиковой ситуации с мьютексом.

Если используется режим совместного кэша, приложение должно гарантировать, что к совместному кэшу, используемому целевой базой данных, не обращаются во время выполнения резервного копирования. На практике это означает, что приложение должно гарантировать, что к файлу диска, в который выполняется резервное копирование, не обращается ни одно соединение в процессе, а не только то конкретное соединение, которое было передано в sqlite3_backup_init().

Сам объект sqlite3_backup частично потокобезопасен. Несколько потоков могут безопасно делать несколько одновременных вызовов sqlite3_backup_step(). Однако API sqlite3_backup_remaining() и sqlite3_backup_pagecount() не являются строго говоря потокобезопасными. Если они вызываются одновременно с другим потоком, вызывающим sqlite3_backup_step(), возможно, они вернут некорректные значения.

Альтернативы использованию API резервного копирования

Другие методы безопасного создания согласованной резервной копии базы данных SQLite включают:

  • Команда VACUUM INTO.
  • Утилита sqlite3_rsync.

См. также списки объектов, констант и функций.

SQLite is in the Public Domain.
https://sqlite.org/c3ref/backup_finish.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API