![]() |
|
|||
WebMoney: WMZ Z294115950220 WMR R409981405661 WME E134003968233 |
Visa 4274 3200 2453 6495 |
Начиная с version 3.3.0
(2006-01-11), SQLite включает специальный режим "shared-cache"
(отключенный по умолчанию) предназначенный для использования во встроенных
серверах. Если общий режим кэширования позволен, и поток
устанавливает многократные связи с той же самой базой данных, связи разделяют
единственные данные и кэш схемы. Это может значительно уменьшить количество
памяти и IO, требуемого системой. В version 3.5.0 (2007-09-04)
был изменен общий режим кэширования так, чтобы тот же самый кэш мог быть
разделен на весь процесс, а не только в единственном потоке.
До этого изменения были ограничения на соединения с базой данных между
потоками. Те ограничения были сняты в 3.5.0.
Этот документ описывает общий режим кэширования с версии 3.5.0. Общий режим кэширования изменяет семантику модели блокировки в некоторых
случаях. Детали описаны этим документом. Принято основное понимание
нормальной логики блокировки SQLite (см.
здесь). Общий режим кэширования это устаревшая особенность.
Использованию общего режима кэширования препятствуют. Большинство вариантов
использования для общего кэша лучше реализуется режимом
WAL. Общий режим кэширования был изобретен в 2006 по требованию разработчиков
Symbian.
Их проблема состояла в том что, если бы база данных контактов по телефону
синхронизировалась, это блокировало бы файл базы данных.
Тогда, если бы было входящее обращение, блокировка базы данных препятствовала
бы тому, чтобы запросить базу данных контактов, чтобы найти соответствующую
музыку для мобильного телефона для входящего вызова или фотографию,
которую показывать на экране и т. д. Режим WAL
(приблизительно 2010) является лучшим решением этой проблемы, поскольку это
разрешает одновременный доступ, не ломая изоляцию транзакции. Приложения, которые строят их собственную копию SQLite из исходного кода,
поощряются использовать
-DSQLITE_OMIT_SHARED_CACHE, поскольку получающийся результат
будет меньшим и быстрее. Интерфейсы общего кэша, описанные здесь, продолжат поддерживаться в
SQLite. Однако, использованию общего кэша препятствуют. Внешне, с точки зрения другого процесса или потока,
два или больше соединения с БД, используя
общий кэш появляются как единственная связь. Протокол блокировки раньше
выносил решение между многократными общими кэшами или постоянными
пользователями базы данных. Рис. 1 Рис. 1 изображает конфигурацию времени выполнения в качестве примера, где
три соединения с базой данных были установлены.
Связь 1 является нормальным соединением с базой данных SQLite.
Связи 2 и 3 разделяют кэш, нормальный протокол блокировки используется, чтобы
преобразовать в последовательную форму доступ к базе данных между связью 1 и
общим кэшом. Внутренний протокол раньше преобразовывал в последовательную
форму (или нет, см. ниже) доступ к общему кэшу связями 2 и 3, это описано в
остатке от этой секции. Есть три уровня модели блокировки общего кэша: блокировка уровня
транзакций, блокировка уровня таблицы и блокировка уровня схемы.
Они описаны в следующих трех подразделах. Связи SQLite могут открыть два вида транзакций, чтения и записи.
Это не сделано явно, транзакция это неявно транзакция чтения, пока она
не пишет таблицу базы данных, тогдла это становится транзакцией записи. Самое большее одна связь с единственным общим кэшом может открыть
транзакцию записи в любой момент. Это может сосуществовать с любым
количеством транзакций чтения. Когда две или больше связи используют общий кэш, блокировки используются,
чтобы преобразовать в последовательную форму параллельные попытки доступа на
основе таблицы. Они поддерживают два типа блокировок, чтения и записи.
Блокировки предоставляют связям: в любой момент у каждого соединения с базой
данных есть блокировка чтения, блокировка записи или никакой блокировки. В любой момент у единственной таблицы может быть любое количество активных
блокировок чтения или единственная активная блокировка записи.
Чтобы прочитать данные из таблицы, связь должна сначала получить блокировку
чтения. Чтобы написать таблицу, связь должна сначала получить блокировку
записи на той таблице. Если необходимая блокировка таблицы не может быть
получена, запрос терпит неудачу, и SQLITE_LOCKED возвращена вызвавшему. Как только связь получает блокировку таблицы, она не выпущена, пока
текущая транзакция не завершена. Поведение, описанное выше, может быть изменено немного при помощи
read_uncommitted pragma,
чтобы изменить уровень изоляции от преобразованного в последовательную форму
(умолчание) на read-uncommitted. Соединение с базой данных в режиме read-uncommitted
не пытается получить блокировки чтения
прежде, чем читать от таблиц базы данных, как описано выше.
Это может привести к непоследовательным результатам запроса, если другое
соединение с базой данных изменяет таблицу
в то время, как она читается, но это также означает, что транзакция чтения,
открытая связью в режиме read-uncommitted,
не может ни заблокировать, ни быть заблокирована любой другой связью. Режим Read-uncommitted не имеет никакого эффекта на блокировки, требуемые,
чтобы написать таблицы базы данных (то есть, связи read-uncommitted
должны все еще получить блокировки записи и следовательно запись в базу
данных может все еще заблокировать или быть заблокирована).
Кроме того, режим read-uncommitted не имеет никакого эффекта на блокировки
sqlite_schema, требуемые по
правилам, перечисленным ниже. Таблица sqlite_schema
поддерживает общий кэш для блокировок чтения и записи
таким же образом, как все другие таблицы базы данных (см. описание выше).
Следующие специальные правила также применяются: В SQLite с 3.3.0 по 3.4.2 когда общий режим кэширования позволен,
соединение с базой данных может только использоваться потоком, который
вызвал sqlite3_open(), чтобы создать его.
Связь могла разделить кэш только с другой связью в том же самом потоке.
Эти ограничения были сняты в
version 3.5.0 (2007-09-04). В более старых версиях SQLite разделенный режим кэширования не мог
использоваться вместе с виртуальными таблицами.
Это ограничение было удалено в SQLite
version 3.6.17 (2009-08-10). Общий режим кэширования позволен отдельно
для каждого процесса. Используя интерфейс C, следующий API может
использоваться, чтобы глобально позволить или отключить
общий режим кэширования: Каждое обращение к
sqlite3_enable_shared_cache() затрагивает использование последующих
соединений с базой данных, созданных
sqlite3_open(),
sqlite3_open16() или
sqlite3_open_v2().
Соединения с базой данных, которые уже существуют, не затронуты.
Каждое обращение к
sqlite3_enable_shared_cache()
отвергает все предыдущие обращения в рамках того же самого процесса. Отдельные соединения с базой данных, созданные использованием
sqlite3_open_v2(),
могут участвовать (или нет) в общем режиме кэширования при помощи флагов
SQLITE_OPEN_SHAREDCACHE или
SQLITE_OPEN_PRIVATECACHE
как третий параметр. Использование любого из этих флагов отвергает глобальное
общее урегулирование режима кэширования, установленное
sqlite3_enable_shared_cache().
Не больше, чем один из флагов должен использоваться; если
SQLITE_OPEN_SHAREDCACHE и флаги SQLITE_OPEN_PRIVATECACHE используются в
третьем аргументе sqlite3_open_v2(),
поведение не определено. При использовании URI filenames
параметр запроса "cache" может использоваться, чтобы определить, будет ли
база данных использовать разделенный кэш. Используйте "cache=shared",
чтобы позволить разделенный кэш и "cache=private", чтобы
разрушить разделенный кэш. Способность использовать параметры запроса URI,
чтобы определить поведение разделения кэша соединения с базой данных
позволяет разделению кэша управляться в запросах
ATTACH: Начиная с SQLite version 3.7.13
(2012-06-11), разделенный кэш может использоваться на
базах данных в памяти при условии, что база
данных создается, используя URI filename.
Для совместимости разделенный кэш всегда разрушается для баз данных в
памяти, если имя ":memory:" используется, чтобы открыть базу данных.
До версии 3.7.13 разделенный кэш всегда запрещен для баз данных в памяти
независимо от используемого имени базы данных,
существующих настроек системы общего кэша, параметров запроса или флагов. Предоставление возможности общего кэша для базы данных в памяти позволяет
двум или больше соединениям с базой данных в том же самом процессе иметь
доступ к той же самой базе данных в памяти.
База данных в памяти в общем кэше автоматически удалена, и память
освобождена, когда последняя связь с той базой данных закрывается.
Choose any three.
1. Общий режим кэширования SQLite
1.1. Использование общего кэша
2.
Модель блокировки общего кэша
2.1.
Блокировка уровня транзакций
2.2. Блокировка уровня таблицы
2.2.1.
Читаемо-нейтральный способ изоляции
/* Set the value of the read-uncommitted flag:
**
** True -> Set the connection to read-uncommitted mode.
** False -> Set the connection to serialized (the default) mode.
*/
PRAGMA read_uncommitted = <boolean>;
/* Retrieve the current value of the read-uncommitted flag */
PRAGMA read_uncommitted;
2.3. Схема (sqlite_schema) блокировка уровня
3. Поточно-связанные проблемы
4. Общий кэш и виртуальные таблицы
5.
Предоставление возможности общего режима кэширования
int sqlite3_enable_shared_cache(int);
ATTACH 'file:aux.db?cache=shared' AS aux;
6. Общий кэш и базы данных в памяти