![]() |
|
|||
WebMoney: WMZ Z294115950220 WMR R409981405661 WME E134003968233 |
Visa 4274 3200 2453 6495 |
Этот документ описывает детали низкого уровня о том, как
режим WAL работает в unix и windows. Отдельный формат файла
предоставляет подробную информацию о структуре файла базы данных и файла
журнала записи, используемого в режиме WAL.
Но детали протокола блокировки и формата WAL-индекса сознательно опущены, так
как те детали оставляют усмотрению отдельных внедрений
VFS. Этот документ заполняет пропущенные детали для
Unix и windows VFS. Для полноты часть высокоуровневой информации о форматировании, которая
содержится в документе формата файла и в
другом месте, копируется здесь, когда это относится к
обработке режима WAL. Когда в активном использовании, статус базы данных WAL описан
тремя отдельными файлами: Формат главного файла базы данных описан в документе
file format.
Номера версий формата файла
по адресам 18 и 19 в главной базе данных должны оба быть 2, чтобы указать,
что база данных находится в режиме WAL.
Главная база данных имеет произвольное имя. Никакие специальные суффиксы
файла не требуются, хотя ".db", ".sqlite" и
".sqlite3", кажется, популярный выбор. Журнал с упреждающей записью или файл "-wal" это журнал наката, который
делает запись транзакций, которые передавались, но еще не применились к
главной базе данных. Детали о формате wal-файла описывают в подразделе
WAL format
описания формата файла.
wal-файл называют, прилагая эти четыре знака "-wal" к концу
названия главного файла базы данных. За исключением 8+3 файловых систем, где
не позволены такие имена, в этом случае суффикс файла изменяется на ".WAL".
Но поскольку 8+3 файловых системы все более и более редки,
этот исключительный случай может обычно игнорироваться.
Wal-Index или файл "-shm" на самом деле не используется в качестве файла.
Скорее отдельные клиенты базы данных отображают файл shm
и используют это как общую память для координирования доступа к базе данных
и как кэш для того, чтобы быстро определить местонахождение структуры в
wal-файле. Название файла shm это главное имя файла базы данных с этими
четырьмя знаками "-shm". Или для 8+3 файловых систем файл это
главный файл базы данных с суффиксом, измененным на ".SHM". shm не содержит содержания базы данных и не требуется, чтобы восстановить
базу данных после катастрофы. По этой причине первый клиент, который
соединится с базой данных, будет обычно усекать файл shm, если он будет
существовать. Так как содержание файла shm не должно быть сохранено после
сбоя, он никогда не fsync() на диск. На самом деле, если бы был механизм,
которым SQLite мог сказать операционной системе никогда не сохранять файл
shm на диск, а всегда держать его в кэш-памяти, то SQLite использовал бы этот
механизм, чтобы избежать любого ненужного дискового I/O, связанного с этим
файлом. Однако, никакой такой механизм не существует в стандарте posix. Поскольку shm используется только, чтобы скоординировать доступ между
параллельными клиентами, файл shm опущен, если установлен
exclusive locking mode.
Когда exclusive locking mode
установлен, SQLite использует память кучи вместо файла
shm с отображенной памятью. Когда база данных WAL в активном употреблении, все три из вышеупомянутых
файлов обычно существуют. Wal-Index опущен, если установлен
exclusive locking mode. Если последний клиент, использующий базу данных, закрывается чисто,
вызывая sqlite3_close(),
то контрольной точкой управляют автоматически,
чтобы передать всю информацию от wal-файла в главную базу данных,
файл shm и файл wal расцепляются. Таким образом, когда база данных не
используется никаким клиентом, обычно имеет место, что только главный файл
базы данных существует на диске. Однако, если последний клиент не вызвал
sqlite3_close()
прежде чем он закрылся, или если последний клиент
был клиентом только для чтения, то заключительная операция очистки не
происходит и файлы shm и wal могут все еще существовать на диске, даже когда
база данных не используется. Когда
PRAGMA locking_mode=EXCLUSIVE (установлен exclusive locking mode),
только единственному клиенту разрешают иметь базу данных, открытую когда-то.
Так как только единственный клиент может использовать базу данных, файл shm
опущен. Единственный клиент использует буфер в памяти кучи
вместо файла shm. Если клиент чтения-записи вызывает
sqlite3_file_control(
SQLITE_FCNTL_PERSIST_WAL) до закрытия,
то при закрытии контрольной точкой все еще управляют, но файлы shm и wal
не удалены. Это позволяет последующим клиентам только для чтения соединяться
и читать базу данных.
WAL-index или "shm" используется, чтобы скоординировать доступ к базе
данных многократными клиентами, и как кэш, чтобы помочь клиентам быстро
определить местонахождение структур в wal-файле. Поскольку файл shm не вовлечен в восстановление, файл shm не должен
быть машинн-независимым порядком байтов. Следовательно, числовые значения в
файле shm написаны в родном порядке байтов компьютера, вместо того, чтобы
быть преобразованными в определенный кроссплатформенный порядок байтов, как
сделано с главным файлом базы данных и wal-файлом. Файл shm состоит из одной или более хэш-таблиц, где каждая хэш-таблица
составляет 32768 байтов в размере. Кроме того, 136-байтовый заголовок
вырезан из самой первой хэш-таблицы, таким образом, первая хэш-таблица
составляет только 32632 байта в размере. Полный размер файла shm всегда
кратен 32768. В большинстве случаев полный размер файла shm точно 32768
байтов. Файл shm должен вырасти вне единственной хэш-таблицы только когда
wal-файл становится очень большим (больше 4079 структур).
Начиная с умолчания автоматического
порога контрольной точки 1000, файлы WAL редко достигают 4079. Первые 136 байтов файла shm это заголовок. У заголовка shm есть
три главных раздела: Отдельные области заголовка shm, за исключением значений salt,
скопированных с заголовка WAL, являются целыми без знака в родном порядке
байтов хост-машины. Значения salt это точные копии от заголовка WAL и
находятся в любом порядке байтов, который используется файлом WAL.
Размер целых чисел может быть 8, 16, 32 или 64 бита.
Значение отдельных областей заголовка shm: 32-bit unsigned integer по адресу 16 (повторен по адресу 64) это
количество действительных структур в WAL. Поскольку структуры WAL
пронумерованы с 1, mxFrame это также индекс последней действительной
переданной структуры в WAL. Переданная структура это структура, у которой
есть ненулевое значение "size of database" в байтах
4-7 заголовка структуры и это указывает на конец транзакции. Когда mxFrame = 0, это указывает, что WAL пуст и что все содержание должно
быть получено непосредственно из файла базы данных. Когда mxFrame = nBackfill,
это указывает, что все содержание в WAL было написано в ответ в базу данных.
В этом случае все содержание может быть прочитано непосредственно из базы
данных. Кроме того, следующий писатель свободен
перезапустить WAL,
если никакие другие связи не держат блокировки WAL_READ_LOCK(N) для N>0. mxFrame всегда больше или равно
nBackfill и nBackfillAttempted.
32-bit unsigned integer по адресу 128 в заголовке WAL-index это
"nBackfill". Эта область содержит количество структур в файле WAL, которые
были скопированы назад в главную базу данных. nBackfill никогда не больше
mxFrame. Когда
nBackfill = mxFrame, это
означает, что содержание WAL было полностью написано в ответ в базу данных и
нормально можно перезапустить WAL,
нет блокировок на любом WAL_READ_LOCK(N) для N>0. nBackfill может быть увеличен только, держа WAL_CKPT_LOCK.
Однако, nBackfill изменяется на ноль во время
WAL reset
и это происходит, держа WAL_WRITE_LOCK.
Восемь байтов обойдены в заголовке для поддержки блокировки файла,
используя метод xShmLock() объекта
sqlite3_io_methods.
Эти восемь байтов никогда не читаются и не пишутся SQLite, начиная с
некоторого VFS (кроме Windows). Это восемь поддержанных блокировок: Хэш-таблицы в файле shm разработаны, чтобы ответить на
следующий вопрос быстро: Допустим, что типы "u8", "u16" и "u32" это unsigned integer длиной
8, 16 и 32 бит, соответственно. Первая 32768-байтовая единица файла shm
организована следующим образом: Вторая и все последующие 32768-байтовые единицы файла shm
похожи на это: Коллективно, записи aPgno делают запись номера страницы базы данных,
сохраненного во всех структурах файла WAL. Вход aPgno[0] в первой
хэш-таблице делает запись номера страницы базы данных, сохраненного в самой
первой структуре в файле WAL. aPgno[i] из первой хэш-таблицы является номером
страницы базы данных для i-й структуры в файле WAL. Вход aPgno[k] для
второй хэш-таблицы это номер страницы базы данных для (k+4062)-й структуры в
файле WAL. Вход aPgno[k] для n-й 32768-байтной хэш-таблицы в файле shm (для
n>1) считает номер страницы базы данных сохраненным в
(k+4062+4096*(n-2))-м фрейме файла WAL. Вот немного отличающийся способ описать значения aPgno:
если вы думаете обо всех значениях
aPgno как о смежном множестве, то номер страницы базы данных, сохраненный в
i-й структуре файла WAL, сохранен в aPgno[i].
Конечно, aPgno не смежное множество. Первые 4062 записей находятся в первой
32768-байтовой единице файла shm, и последующие значения
находятся в кусках по 4096 входа в более поздних единицах файла shm. Один способ вычислить FindFrame (P, M) состоял бы в том, чтобы просмотреть
множество aPgno, начинающееся с входа M, работать назад к началу и
возвратить J, где aPgno[J]==P.
Такой алгоритм работал бы, и это будет быстрее, чем поиск целого файла WAL
для последней структуры с номером страницы P. Но поиск может быть сделан
намного быстрее при помощи структуры aHash. Номер страницы P базы данных отображен
в значение хэш-функции, используя следующую хеш-функцию: Эта функция отображает каждый номер страницы в целое число между 0 и 8191
включительно. Поле aHash каждой 32768-байтовой единицы файла shm отображает
значения P в индексы поля aPgno той же самой единицы следующим образом: У каждого входа во множестве aPgno есть единственный соответствующий вход
во множестве aHash. Есть более доступные места в aHash, чем есть в aPgno.
Неиспользуемые слоты в aHash заполнены нолем.
И с тех пор там, как гарантируют, будут неиспользуемыми слотами в aHash,
это означает, что цикл, который вычисляет X, закончится. Ожидаемый размер X
является меньше 2. Худший случай это то, что X совпадет с
количеством записей в aPgno, в этом случае алгоритма работает на
приблизительно той же самой скорости, как линейный просмотр aPgno.
Но это редко. Обычно размер X будет небольшим и использование множества
aHash позволяет вычислять FindFrame(P,M) намного быстрее. Вот альтернативный способ описать алгоритм поиска хэша: начните с
h = (P * 383)%8192 и посмотрите на aHash[h] и последующие записи,
когда h достигнет 8192 до нахождения входа с aHash[h] == 0.
У всех записей aPgno, имеющих номер страницы P, будет индекс, который
является одним из значений aHash[h], таким образом вычисленных. Но не все
вычисленные значения aHash[h] будет соответствовать соответствующим
критериям, таким образом, необходимо проверить их независимо.
Преимущество скорости появляется, потому что обычно этот набор
значений h очень маленький. Обратите внимание на то, что у каждой 32768-байтовой единицы файла shm
есть свой собственный aHash и множество aPgno. Множество aHash для единого
блока полезно только в нахождении записи aPgno в той же самой единице.
Функция FindFrame(P,M) должна сделать поиски хэша, начинающиеся с последней
единицы и работающие назад к самой старой единице, пока это
не находит ответ. Доступ скоординирован в режиме WAL, используя и устаревшие блокировки
DELETE, которыми управляют методы xLock и xUnlock объекта
sqlite3_io_methods, и блокировки
WAL, которыми управляет метод xShmLock объекта
sqlite3_io_methods. Концептуально, есть только единственная блокировка DELETE.
Она для связи единой базы данных может быть в точно одном
из следующих состояний: Блокировка DELETE сохранена в
странице блокировок главного файла базы данных. Только SQLITE_LOCK_SHARED
и SQLITE_LOCK_EXCLUSIVE это факторы для баз данных WAL. Другие состояния
блокировки используются в режиме обратной перемотки, но не в WAL. Следующие правила показывают, как каждая блокировка применяется. SQLITE_LOCK_SHARED Все связи держат SQLITE_LOCK_SHARED непрерывно в то время, как
подключены к базе данных WAL. Это верно для связей чтения-записи и для связей
только для чтения. SQLITE_LOCK_SHARED проводится даже связями, которые не в
транзакции. Это отличается от способа обратной перемотки, где
SQLITE_LOCK_SHARED снята в конце каждой транзакции. SQLITE_LOCK_EXCLUSIVE Связи держат монопольную блокировку, когда переключаются между WAL
и любым режимом обратной перемотки. Связи могли бы также попытаться получить
блокировку EXCLUSIVE, когда они отсоединяются от режима WAL.
Если связь в состоянии получить блокировку EXCLUSIVE,
это означает, что это единственная связь с базой данных и таким образом, это
может попытаться перейти к контрольной точке и затем удалить
WAL-индекс и файлы WAL. Когда связь держит блокировку SHARED на главной базе данных, это
будет препятствовать тому, чтобы любая другая связь приобрела блокировку
exclusive, которая в свою очередь препятствует тому, чтобы WAL-индекс и файлы
WAL были удалены из-под других пользователей и предотвращает выход из режима
WAL в то время, как другие пользователи получают доступ к базе
данных в режиме WAL. WAL_WRITE_LOCK WAL_WRITE_LOCK только исключительная блокировка.
Никогда нет коллективной блокировки, взятой WAL_WRITE_LOCK. EXCLUSIVE WAL_WRITE_LOCK
проводится любой связью, которая прилагает содержание к концу WAL.
Следовательно, только единственный процесс за один раз может приложить
содержание к WAL. Если перезапуск
WAL происходит в результате записи, то поле
nBackfill заголовка WAL-index
перезагружается к нолю, держа эту блокировку. EXCLUSIVE также держит WAL_WRITE_LOCK
и на нескольких других байтах блокировки, когда связь управляет
восстановлением
на общем WAL-индексе. WAL_CKPT_LOCK WAL_CKPT_LOCK только исключительная блокировка.
Никогда нет коллективной блокировки, взятой WAL_CKPT_LOCK. EXCLUSIVE WAL_CKPT_LOCK проводится любой связью, которая управляет
контрольной точкой. Поле
nBackfill заголовка WAL-index
может быть увеличено, держа эту монопольную блокировку, но это
не может быть уменьшено. EXCLUSIVE также держит WAL_CKPT_LOCK и на нескольких других байтах
блокировки, когда связь управляет
восстановлением
на общем WAL-индексе. WAL_RECOVER_LOCK WAL_RECOVER_LOCK только исключительная блокировка.
Никогда нет коллективной блокировки, взятой WAL_RECOVER_LOCK. EXCLUSIVE WAL_RECOVER_LOCK проводится любой связью, которая управляет
восстановлением,
чтобы восстановить общий WAL-индекс. Связь только для чтения, которая восстанавливает ее частный WAL-индекс
памяти кучи, не держит эту блокировку.
Это не может ее получить, так как связям только для чтения не позволяют
держать монопольные блокировки. Эта блокировка проводится только
восстанавливая глобальный общий WAL-индекс, содержавшийся в файле
SHM с отображенной памятью. В дополнение к блокировке этого байта связь, выполняющая
восстановление, также
получает монопольную блокировку на всех других блокировках WAL кроме
WAL_READ_LOCK(0). WAL_READ_LOCK(N) Есть пять отдельных блокировок чтения с номерами от 0 до 4.
Они могут быть SHARED или EXCLUSIVE.
Связи получают коллективную блокировку на одном из байтов блокировки чтения
в то время, как они в транзакции. Связи также получают монопольную блокировку
на блокировках чтения, по одной, в течение краткого момента в то время, как
они обновляют значения соответствующих прочитанных отметок. Блокировки чтения
1-4 проводятся исключительно когда выполняется
восстановление. Каждый байт блокировки чтения соответствует одному из пяти 32-битных
integer прочитанной отметки, расположенных в байтах 100-119 заголовка
WAL-индекса, следующим образом: Когда связь держит коллективную блокировку на WAL_READ_LOCK(N),
которая является обещанием связи, что это будет использовать WAL, а не файл
базы данных для любых страниц базы данных, которые изменяются первой
прочитанной отметкой read-mark[N] в WAL. read-mark[0] всегда 0.
Если связь держит коллективную блокировку на WAL_READ_LOCK(0),
это означает, что связь ожидает быть в состоянии проигнорировать WAL и
прочитать любое содержание от главной базы данных.
Если N>0, связь может использовать больше файла WAL вне read-mark[N],
если хочет, до первых структур mxFrame. Но когда связь держит коллективную
блокировку на WAL_READ_LOCK(0), это является обещанием, что это никогда не
будет читать содержание от WAL и приобретет все содержание непосредственно
от главной базы данных. Когда контрольная точка работает, если она видит блокировку на
WAL_READ_LOCK(N), она не должна перемещать содержание WAL в главную базу
данных для больше, чем N первых структур read-mark[N]. Если сделать так, это
перепишет содержание, которое процесс, держащий блокировку, ожидал быть в
состоянии прочитать из главного файла базы данных. Последствие этого,
если файл WAL f содержит больше, чем read-mark[N]
структур (если mxFrame>read-mark[N] для любой read-mark,
для которой WAL_READ_LOCK(N) проводится другим процессом), тогда контрольная
точка не может завершиться. Когда писатель хочет перезагрузить
WAL, он должен гарантировать, что нет блокировок
WAL_READ_LOCK(N) для N>0 потому что такие блокировки
указывают, что некоторая другая связь все еще использует текущий файл WAL, и
перезапуск WAL
удалил бы содержание из тех других связей. Для
перезапуска WAL
нормально происходить, если другие связи держат WAL_READ_LOCK(0)
потому что, держа WAL_READ_LOCK(0), те другие связи обещают не использовать
любое содержание от WAL. Переход в и из WAL-режима Блокировка SQLITE_LOCK_EXCLUSIVE должна быть проведена связью, которая
хочет выйти из режима WAL. Переходить в WAL поэтому можно точно так же, как
любая другая транзакция записи, так как каждая транзакция записи в режиме
обратной перемотки требует блокировку SQLITE_LOCK_EXCLUSIVE.
Если файл базы данных уже будет в режиме WAL (следовательно, если надо
изменить его назад в режим обратной перемотки), и если будет две или больше
связи с базой данных, то каждая из этих связей будет держать блокировку
SQLITE_LOCK_SHARED. Это означает, что SQLITE_LOCK_EXCLUSIVE не может быть
получена, и переход из WAL не будет позволен. Это препятствует тому, чтобы
одна связь удалила WAL из-под другой.
Это также означает, что единственный способ переместить базу данных от WAL
в режим обратной перемотки состоит в том, чтобы закрыть все кроме одной
связи с базой данных. Закройте связь с базой данных WAL Когда соединение с базой данных закрывается (через
sqlite3_close() или
sqlite3_close_v2()),
попытка предпринята, чтобы приобрести SQLITE_LOCK_EXCLUSIVE.
Если эта попытка успешна, это означает, что связь, которая закрывается,
это последняя связь с базой данных. В этом случае желательно очистить файлы
WAL и WAL-индекс, таким образом, заключительная связь управляет
контрольной точкой (держа SQLITE_LOCK_EXCLUSIVE) и
удаляет файлы WAL и WAL-index. SQLITE_LOCK_EXCLUSIVE
не выпущена до окончания удаления файлов WAL и WAL-index. Если применение вызывает
sqlite3_file_control(
SQLITE_FCNTL_PERSIST_WAL) на соединение с базой данных до закрытия, то
заключительной контрольной точкой все еще управляют, но WAL и WAL-индекс
не удалены. Это оставляет базу данных в состоянии
, которое позволяет другим процессам без права записи
на базе данных, WAL или WAL-индексе открыть базу данных только для чтения.
Если WAL и WAL-индекс будут отсутствовать, то процесс, который испытывает
недостаток в разрешении создать и инициализировать те файлы, не будет в
состоянии открыть базу данных, если база данных не будет определяться как
неизменная через использование
without write permission on the database, WAL, or WAL-index files
неизменного параметра запроса. Восстановите глобальный общий WAL-индекс во время
восстановления. Все блокировки WAL-индекса, за исключением WAL_READ_LOCK(0),
проводятся исключительно, восстанавливая глобальный общий WAL-индекс во время
восстановления. Добавьте новую транзакцию до конца WAL Монопольная блокировка держится на WAL_WRITE_LOCK, добавляя новую
структуру в конец файла WAL. Прочитайте содержание от базы данных и WAL как часть транзакции.
Управляйте контрольной точкой. Перезагрузите файл WAL. Перезапуск WAL означает
перемотать WAL и начать добавлять новые структуры в начало.
Это происходит, прилагая новые структуры к WAL, у которого
mxFrame =
nBackfill
и который не имеет блокировок на
WAL_READ_LOCK(1)-WAL_READ_LOCK(4). WAL_WRITE_LOCK проводится. Восстановление это процесс восстановления WAL-индекса так, чтобы это
было синхронизировано с WAL. Восстановлением управляет первый поток, чтобы соединиться с базой данных
WAL-режима. Восстановление восстанавливает WAL-индекс так, чтобы это точно
описало файл WAL. Если нет никакого файла WAL, когда первый поток
соединяется с базой данных, нет ничего, чтобы восстановить, но процесс
восстановления все еще работает, чтобы инициализировать WAL-индекс. Если WAL-индекс осуществляется как файл с отображенной памятью,
и тот файл только для чтения к первому потоку, то этот поток
создает частную память кучи WAL-индекса и управляет режимом восстановления,
чтобы наполнить тот частный WAL-индекс. Восстановление работает, делая единственный проход по WAL с начала до
конца. Контрольные суммы проверяются на каждой структуре WAL, когда это
прочитано. Просмотр останавливается в конце файла или в первой
недействительной контрольной сумме.
Поле mxFrame
установлена в индекс последней действительной переданной структуры в WAL.
Так как номера структур WAL внесены в указатель, начиная с 1,
mxFrame также количество действительных структур в WAL. "commit frame" это
структура, у которой есть ненулевое значение в байтах 4-7 заголовка
структуры. Так как у процедуры восстановления нет способа знать, сколько
структур WAL, возможно, было ранее скопировано назад в базу данных, это
инициализирует значение
nBackfill=0. Во время восстановления глобального WAL-индекса общей памяти монопольные
блокировки держатся на WAL_WRITE_LOCK, WAL_CKPT_LOCK, WAL_RECOVER_LOCK и
WAL_READ_LOCK(1)-WAL_READ_LOCK(4). Другими словами, все блокировки,
связанные с WAL-индексом за исключением WAL_READ_LOCK(0),
проводятся исключительно. Это препятствует тому, чтобы любой другой поток
писал базу данных и от чтения любых транзакций, которые проводятся в WAL,
пока восстановление не завершено.
Choose any three.
1. Файлы на диске
1.1. Главный файл базы данных
1.2. Журнал с упреждающей записью или файл "-wal"
1.3.
Wal-Index или файл "-shm"
1.4. Жизненные циклы файла
1.5. Изменения
2. Формат файла WAL-Index
2.1. Заголовок WAL-Index
Байты Описание 0..47 Первая копия WAL Index 48..95 Вторая копия WAL Index 96..135
Информация о контрольной точке и блокировках
Байты Имя Смысл 0..3 iVersion
Номер версии формата WAL-индекса. Всегда 3007000. 4..7
Неиспользованное пространство дополнения. Должен быть ноль. 8..11 iChange
Счетчик Unsigned integer, растет с каждой транзакцией. 12 isInit
Флаг "isInit". 1, когда файл shm был инициализирован. 13 bigEndCksum
True,если файл WAL использует контрольные суммы
big-ending. 0 иначе. 14..15 szPage
Размер страницы базы данных в байтах или 1,
если размер страницы 65536. 16..19 mxFrame
Количество действительных и переданных структур в файле WAL. 20..23 nPage
Размер файла базы данных в страницах. 24..31 aFrameCksum
Контрольная сумма последней структуры в файле WAL. 32..39 aSalt
Два значения salt, скопированных с заголовка файла WAL.
Эти значения в порядке байтов файла WAL, который мог бы отличаться от родного
порядка байтов машины. 40..47 aCksum
Контрольная сумма байтов 0-39 заголовка. 48..95
Контрольная сумма байтов 0-47 заголовка. 96..99 nBackfill
Количество структур WAL, которые были уже заделаны в базу данных
предшествующими контрольными точками. 100..119 read-mark[0..4]
Пять "прочитанных отметок". Каждая прочитанная отметка это
32-битное целое без знака (4 байта). 120..127
Неиспользуемое место отложено для 8 блокировок файла. 128..132 nBackfillAttempted
Количество структур WAL, которые попытались быть заделанными, но которые,
возможно, не были заделаны успешно. 132..136
Неиспользуемое место зарезервировано для дальнейшего расширения.
2.1.1. Поле mxFrame
2.1.2. Поле nBackfill
2.1.3. Блокировки WAL
Имя Смещение xShmLock WAL_WRITE_LOCK 0 120 WAL_CKPT_LOCK 1 121 WAL_RECOVER_LOCK 2 122 WAL_READ_LOCK(0) 3 123 WAL_READ_LOCK(1) 4 124 WAL_READ_LOCK(2) 5 125 WAL_READ_LOCK(3) 6 126 WAL_READ_LOCK(4) 7 127 2.2. Хэш-таблицы WAL-Index
FindFrame(P,M): Учитывая номер страницы P и максимальный
индекс M структуры WAL, возвратите самый большой индекс структуры WAL для
страницы P, который не превышает M, или NULL при отсутствии структур для
страницы P, которые не превышают M.
u8 aWalIndexHeader[136];
u32 aPgno[4062];
u16 aHash[8192];
u32 aPgno[4096];
u16 aHash[8192];
h = (P * 383)%8192
2.3. Блокировка матрицы
2.3.1. Как различные блокировки используются
Имя блокировки Смещение блокировки
Имя прочитанной отметки Смещение прочитанной отметки WAL_READ_LOCK(0) 123 read-mark[0]
100..103 WAL_READ_LOCK(1) 124 read-mark[1]
104..107 WAL_READ_LOCK(2) 125 read-mark[2]
108..111 WAL_READ_LOCK(3) 126 read-mark[3]
112..115 WAL_READ_LOCK(4) 127 read-mark[4]
116..119
2.3.2. Операции, которые требуют блокировок
3. Восстановление