Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
Шрифт:
* Заголовок блока всегда будет первым.
* Далее идут группы владельцев - за группой владельца следуют все запросы этого владельца. Каждый владелец цепочки выводится с его запросами.
* После всех владельцев и запросов идут блокировки.
* Последним элементом является история записей.
Вначале мы рассмотрим только группу заголовка блока, которая описывает основную конфигурацию и состояние таблицы блокировок. На рис. 40.2 числа добавлены для ссылок на каждый элемент при объяснении в табл. 40.2.
Рис. 40.2. Группа Lock_Header
Наш отчет Lock Print представляет только что созданную базу данных, к которой имеет доступ одна копия isql в версии l.O.x Суперсервера для Windows.
Таблица 40.2. Записи группы Lock_Header
№ | Элемент | Объяснение |
1 | LOCK_HEADER_BLOCK | Первая группа любого отчета Lock Print. Каждый отчет выводит ровно одну группу заголовка блока |
2 | Version (Версия) | Номер версии Менеджера блокировок. В Firebird 1.5 версия будет 115 для Суперсервера и 5 для Классического сервера. В Firebird 1.0.x (для нашего примера) такими версиями будут 114 и 4 соответственно |
3 | Active owner (Активный владелец) | Смещение в группе владельца, представляющее владельца, который в настоящий момент управляет таблицей блокировок, если такой существует. Если ни один процесс не пишет в таблицу блокировок, то активным владельцем будет 0 |
4 | Length (Длина) | Общий объем памяти, выделенный таблице блокировок в байтах |
5 | Used (Используется) | Наибольшая величина смещения в таблице блокировок, которая используется в настоящий момент. В таблице могут существовать свободные группы между ее началом и используемой точкой, если владельцы приходят и уходят. Перед созданием новых групп между этой точкой и концом таблицы блокировок могут быть заново использованы свободные блоки |
6 | Semmask (Маска семафора) | В системах, которые используют статичные семафоры (например, POSIX), это указатель на блок SMB, содержащий количество используемых семафоров. Когда нужен семафор, и ни один недоступен, Менеджер блокировок проходит через группы владельцев для поиска того владельца, имеющего неиспользуемый семафор. Если такого |
7 | Flags (Флаги) | Определены два битовых флага: LHB_shut_manager, который, если установлен, указывает, что база данных остановлена, и Менеджер блокировок не может обработать больше запросов; и LHB_lock ordering. В Firebird значение по умолчанию LHB_lock_ordering означает, что блокировки предоставляются в порядке запросов (порядок FIFO - первый пришел - первый ушел). Другая установка связана с устаревшей стратегией блокировки и сейчас не используется |
8 | Enqs (Запросы в очереди) | Запросы в очереди- полученные запросы на блокировку. Это число включает запросы, которые пока не могут быть удовлетворены, и запросы, которые могут быть удовлетворены немедленно, но не запросы, которые пришли и ушли |
9 | Converts (Преобразования) | Запросы на повышение уровня блокировки. Процесс, поддерживающий блокировку ресурса, запросит изменение режима, если изменяется его доступ к этому ресурсу. Преобразование происходит от блокировки низшего уровня (например, совместное чтение) к более ограничивающему уровню (например, исключительный доступ). Например, транзакция в режиме CONCURRENCY, которая читала данные таблицы, и решает изменить данные в этой таблице, будет преобразовывать свою блокировку от разделяемого чтения до разделяемой записи. Преобразования являются наиболее частыми для блокировок страниц, поскольку страница обычно вначале читается, а потом изменяется |
10 | Rejects (Отмены) | Запросы, которые не могут быть удовлетворены. Это могут быть блокировки, запрошенные в режиме "no wait", или это могут быть блокировки, которые были отменены, потому что приводили к взаимным блокировкам. Так как методы доступа иногда запрашивают блокировку "по wait" для внутренних структур, то вы увидите отмены, даже если все транзакции выполняются в режиме "wait" и не существует конфликтов между их операциями |
11 | Blocks(Блоки) | Запросы, которые не могут быть удовлетворены немедленно, потому что некоторый другой владелец имеет несовместимую блокировку на этот ресурс |
12 | Deadlock scans (Сканирование взаимных блокировок) | Сколько раз Менеджер блокировок просматривает цепочку блокировок и владельцев в процессе поиска взаимных блокировок. Менеджер блокировок начинает сканирование, когда процесс ожидает блокировки в течение 10 секунд |
13 | Deadlocks (Взаимные блокировки) | Количество найденных взаимных блокировок. См. разд. "Взаимные блокировки" |
14 | Scan interval (Интервал сканирования) | Количество секунд, которые ожидает Менеджер блокировок после начала запроса, прежде чем запустить сканирование взаимных блокировок. Значение по умолчанию 10 секунд |
15 | acquires(Запросы) | Количество раз, сколько владелец- или сервер от имени конкретного владельца - запрашивает исключительное управление для таблицы блокировок, чтобы выполнить изменения |
16 | Acquire blocks (Заблокированные запросы) | Количество раз, сколько владелец - или сервер от имени конкретного владельца - находился в состоянии ожидания при запросе исключительного управления таблицей блокировок |
17 | Spin count (Количество блокировок) | Это режим для ожидания взаимной блокировки и повторения запроса к таблице блокировок Firebird. По умолчанию установлено в ноль (отключено), но может быть сделано доступным в файле конфигурации |
18 | Mutex wait (Ожидание блокировок) | Процент попыток, которые были заблокированы, когда владелец старался обратиться к таблице блокировок - т.е. ((acquire blocks) / (acquires)) * 100 |
19 | Hash slots (Сегменты хэша) | Ресурсы размещены в хэш-таблице. Они хранятся согласно значению. По умолчанию хэш-таблица содержит 101 сегмент. Это значение (которое должно быть простым числом) может быть увеличено в файле конфигурации. Оно никогда не должно быть меньше, чем 101 |
20 | Hash lengths(Длина сегмента) | При каждом сегменте находятся ресурсы (заблокированные группы). Этот элемент сообщает минимальную, среднюю и максимальную длину цепочки заблокированных групп, находящихся в сегменте. Среднее значение, большее чем 15, означает, что не достаточно сегментов |
21 | Remove node (Удаление узла) | Для устранения проблем, которые являются следствием того, что активный владелец зависает при запросе к таблице блокировок с потенциально осуществленными ее изменениями, владелец сообщает о намерении удалить узел из этой таблицы. После успешного завершения операции владелец удаляет сообщение об удалении. Если любой другой владелец находит сообщение об удалении, которое он не создавал, он наводит порядок |
22 | Insert queue (Добавить очередь) | Эквивалент предыдущей схеме удаления узла, за исключением того, что здесь узел добавляется |
23 | Insert prior (Предыдущее добавление) | Для очистки ошибочного добавления необходимо знать не только, что было добавлено, но и где это размещалось. Это как раз где |
24 | Owners (Владельцы) | Количество владельцев, которые соединены с таблицей блокировок. Только один из этих владельцев может изменять таблицу в конкретный момент ("активный владелец"). Другие владельцы ожидают освобождения блокировок. В нашем примере существует четыре владельца, не являющихся активными. Два владельца подключены через isql; один может быть подключен через DSQL, а еще один - сама база данных |
25 | Free owners (Свободные владельцы) | Количество блоков владельцев, выделенных владельцам, которые завершили их соединения, оставив блоки неиспользованными. В этом случае, вероятно, существует две транзакции, занимавшиеся созданием базы данных, которые были подтверждены |
26 | Free locks (Свободные блокировки) | Группы блокировок определяют ресурс (база данных, отношение, транзакция и т.д.), который заблокирован, а не блок на ресурс. Этот элемент является количеством групп блокировок, которые были освобождены, но пока повторно не использованы. В этом случае существует один свободный блок. Когда владелец запрашивает блокировку на ресурс, который в настоящий момент не заблокирован, Менеджер блокировок сначала просматривает список свободных блоков в заголовке блока. Если существует группа с нужным размером ключа, то эта группа блока будет использована. Если нет, то в свободной памяти будет размещена новая группа блока |
27 | Free requests (Свободные запросы) | Группы запросов идентифицируют запросы на блокировки ресурсов, неважно, удовлетворенные или нет. Этот элемент является количеством групп запросов, которые были освобождены и не использованы повторно |
28 | Lock ordering (Порядок блокировок) | Порядок блокировок означает получение запросов на блокировку в порядке их поступления, даже если последующие запросы должны быть обслужены немедленно. Включено, если флаг LHB_lock_ordering (см. элемент 7) установлен, и является значением по умолчанию для Firebird, т. к. обеспечивает оптимальную производительность. Альтернативой является (не используется сейчас) предоставление блокировок всем владельцам, желающим совместно использовать и "подавлять" владельцев, которые имеют существующие запросы. Эта не используемая стратегия гарантирует, что участники будут обработаны быстро, однако с риском причинения вреда другим |
Группы владельцев, изображенные на рис. 40.3, описывают транзакцию или другого пользователя в Менеджере блокировок. Владельцы делятся на несколько типов, идентифицируемых пятью числами:
* 1 - процесс;
* 2 - база данных;
* 3 - клиентское соединение (в Классическом сервере клиентские соединения всегда являются процессами);
* 4 - транзакция;
* 5 - фиктивный процесс.
! ! !
ПРИМЕЧАНИЕ. В некоторых причудливых соглашениях по кодированию на транзакции никогда не ссылаются по их идентификационному номеру (4), а используют номер 255.
. ! .
Рис. 40.3. Группа владельца
Смещение конкретной группы владельца в таблице блокировок (здесь это 11 872) также является идентификатором, используемым в заголовке блокировок для "активного владельца", если этот пользователь активно изменяет таблицу блокировки. Первая выводимая группа обычно является номером, выводимым в группу заголовка блокировок в начале списка владельцев. Значение в списке указателей является полем в группе, которое содержит прямые и обратные указатели на группы владельцев. В табл. 40.3 описаны записи в группе владельца.
! ! !
СОВЕТ. Если вы просматриваете ваш результат работы утилиты в текстовом редакторе, вы можете отыскивать запросы, принадлежащие идентификатору этого владельца.
. ! .
Таблица 40.3. Записи групп владельцев
№ | Элемент | Объяснение |
1 | OWNER BLOCK | Идентифицирует конкретного владельца. Число, следующее за заголовком (11 872), является смещением группы владельца в таблице блокировок и используется в качестве идентификатора владельца в этой таблице |
2 | Owner ID (Идентификатор владельца) | В Классическом сервере владельцем всегда является процесс, а идентификатором владельца всегда является идентификатор процесса. В Суперсервере владельцем является либо база данных и идентификатором будет группа базы данных, либо соединение и идентификатором будет эта группа соединения |
3 | Owner type (Тип владельца) | Типом владельца является число между 1 и 4 или 255 (фиктивный процесс) |
4 | Flags (Флаги) | Биты, которые определяют состояние. Процесс в одно и то же время может находиться более чем в одном состоянии (см. табл. 40.4) |
5 | Pending (Ожидание завершения) | Смещение группы запроса блокировки, описывающей запрошенную владельцем блокировку, но еще им не полученную. Владелец может иметь не более одного ожидающего запроса в один момент времени |
6 | Semid (Идентификатор семафора) | Идентификатор семафора, назначенного этому пользователю. Если он может быть использован, то слово "Available" (Доступен) должно следовать после идентификатора |
7 | Process_id (Идентификатор процесса) | В Классическом сервере это идентификатор процесса владельца. В Суперсервере, если владельцем является соединение, база данных или транзакция, то этот владелец станет идентификатором процесса |
8 | UID (Идентификатор пользователя) | В POSIX это идентификатор пользователя, являющегося владельцем процесса. В Windows это всегда ноль |
9 | Alive | Dead (Живой | Мертвый) | Lock Printer вызывает подпрограмму ISC_check_process_ existence и сообщает результат |
10 | Flags (Флаги) | Мнемоника флагов - корректно выводится 2 в виде 0x02 (а не 0x202, как в пункте (4)) |
11 | Requests (Запросы) | Запросы на блокировку, обработанные или ожидающие завершения, которые связаны с этим процессом. Числа последующее и предыдущее ссылаются на последующий и предыдущий элемент в очереди запросов, принадлежащих этому процессу. Числа задают смещения |
12 | Blocks (Группы) | Временный список блокировок (групп запросов), блокирующих другие запросы на блокировку, которыми владеет этот процесс. Этот список очищается, когда процесс сообщает, что он должен освободить или понизить уровень его блокировки в предположении, что он в состоянии это сделать |
В табл. 40.4 описаны состояния, представленные разнообразными флагами владельца.
Таблица 40.4. Состояния флагов владельца
Символ | Значение | Состояние |
OWN blocking | 1 | Владелец заблокирован. Если установлен, значит процесс имеет, по меньшей мере, один блок, который другой процесс не хочет совместно использовать |
OWN scanned | 2 | Владелец был проверен в текущем сканировании взаимных блокировок |
OWN manager | 4 | Системы, которые отключают сообщения между группами, имеют привилегированный Менеджер блокировок, который передает сообщения. Этот владелец является таким менеджером |
OWN signal | 8 | Владелец должен был выдать сообщение, но не смог это сделать из-за ошибки, поэтому сигнал будет вызван менеджером блокировок |
OWN wakeup | 32 | Владелец сообщил об освобождении блокировки |
OWN starved | 128 | Может быть, этот поток завис. Зависание случается в многопоточной системе Solaris и означает, что владелец (процесс) выполнил более 500 неудачных попыток получения доступа к таблице блокировок для освобождения блока |
OWN signaled | 16 | Предполагается, что сигнал был отправлен. Он обращается к флагу OWN ast flags, но был суммирован по OR с указанными флагами. Обратите внимание: похоже, что выведенное здесь шестнадцатеричное число 202 является ошибкой синтаксического анализатора |
Группы блокировок следуют после групп запросов в выходном протоколе, однако группы запросов будут проще в понимании, если мы вначале рассмотрим группы блокировок. Группа блокировок представляет блокируемый ресурс.
Блокировки ресурсов приходят различных типов или в виде серий в соответствии с типом ресурса, блокировку которого владельцы запрашивают у таблицы блокировок. В табл. 40.5 определяются и описываются различные типы блокировки ресурсов и их назначение.
Таблица 40.5. Типы ресурсов (серии)
Символ | Серия | Тип |
LCK_database | 1 | Корень дерева блокировки. В Классическом сервере блокировка базы данных выполняется для каждого процесса, который соединяется с базой данных. Первый процесс получает исключительную блокировку. Следующий процесс сообщает о конфликте и сигнализирует первому о необходимости понижения уровня его блокировки от исключительной до уровня совместного использования. После этого все блокировки самой базы данных создаются для совместного чтения. В Суперсервере база данных получает на себя исключительную блокировку |
LCK_relation | 2 | Индивидуальная таблица блокировки. Таблица блокировки указывает, что процесс читает и пишет в указанную таблицу в своей текущей транзакции или что он использует предложение RESERVING в операторе START TRANSACTION для сообщения своего намерения читать таблицу или писать в таблицу. В этой таблице ключевым полем является RDB$RELATION_ID. Заметьте, что оба запроса сообщают ее состояние как 2(2), указывая, что они запросили и получили блокировку на совместное чтение из таблицы |
LCK_bdb | 3 | Индивидуальный блок буфера. Блокировка BDB является блокировкой страницы базы данных. Такие блокировки возводятся, когда два или более владельца соединяются с базой данных в Классическом сервере. Они устанавливаются, когда процесс собирается читать или писать страницу, и освобождаются, когда процесс завершает работу с буфером и требует освобождения памяти, или когда другому владельцу нужна эта страница |
LCK_tra | 4 | Блокировка индивидуальной транзакции. Каждое действие получает исключительную блокировку для своей транзакции при ее старте. Другие владельцы могут получать пустую блокировку для чтения их состояния |
LCK_rel_exist | 5 | Блокировка существования отношения. Предотвращает удаление таблиц, в то время как любые другие владельцы подготавливают запрос, который использует эту таблицу |
LCK idx exist | 6 | Блокировка существования индекса. Предотвращает удаление или дезактивацию индекса, в то время как любые другие владельцы подготавливают запрос, который использует этот ресурс |
LCK_attachment | 7 | Не используется. Блокировка соединения для поддержания блокировок записей dBase, которые могут присутствовать в пределах транзакции |
LCK shadow | 8 | Блокировка для синхронизации добавления теневых копий (shadow). Главным образом для Классического сервера |
LCK_sweep | 9 | Блокировка чистки для одного процесса чистки. Чистка является довольно дорогой операцией и лучше работает, если выполняется только одним потоком или соединением. Реальные "чистильщики" сохраняют исключительную блокировку в своей серии для исключения конфликтов. Эта серия используется для межпроцессных связей в Классическом сервере |
LCK file_extend | 10 | Блокировка на синхронизацию расширения файла. Файл расширения базы данных является другой операцией, которая не выполняется таким же образом, если две транзакции пытаются выполнять операцию одновременно. Эта серия используется для межпроцессных связей в Классическом сервере |
LCK retaining | 11 | Самая молодая транзакция, подтвержденная с сохранением контекста (commit retaining). Это используется только в VMS. Возможно, это отмечает то место, где Firebird имеет расширенную семантику блокировок для нужд VMS и, следовательно, требует специальных средств для работы с Менеджером блокировок VMS |
LCK expression | 12 | Механизм кэширования выражения индекса. Первоначально эта серия предназначалась для описания выражений индексов - как их вычислять, как должен выглядеть результат вычислений и т.д. По разным причинам сейчас это используется при удалении индекса |
LCK record locking | 13 | Блок на существование блокировки записи. Эта серия указывает, что была запрошена блокировка записи конкретной таблицы. Первый процесс, запрашивающий блокировку записи таблицы, также получает блокировку таблицы. Пока требуется эта блокировка, блокировки сохраняются для соединения. Когда появляется вторая транзакция, уровень блокировки таблицы снижается до совместного использования. Эта серия используется только в устаревшем коде эмуляции PC |
LCK record | 14 | Блокировка записи. Эта серия также используется только в устаревшем коде эмуляции PC и использует RDB$DB_KEY в качестве имени блокировки |
LCK_prc exist | 15 | Блокировка существующей процедуры. Не позволяет удалять процедуры и триггеры, пока любой другой владелец подготавливает запрос, который использует этот ресурс (или зависит от него) |
LCK range_relation | 16 | Блокировка диапазона отношения. Опять же, эта серия используется только в коде эмуляции PC, который имеет концепцию изменения диапазонов |
LCK_update_shadow | 17 | Блокировка синхронного изменения теневой копии. Эта серия используется для ограничения до единицы количества процессов, которые приводят к замене теневой копии или отмене теневого копирования |
Для вывода групп блокировок ресурсов заданной серии вам нужно включить номер серии в качестве аргумента:
fb_lock_print -s 2
Группа блокировки на рис. 40.4 представляет саму базу данных. Она имеет исключительный доступ для одного владельца- базы данных. В Классическом сервере вы увидите несколько владельцев для базы данных.
< image l:href="#"/>Рис. 40.4. Группа блокировки серии 1 (база данных) В табл. 40.6 объяснено, что означают записи этого отчета.
Таблица 40.6. Записи группы блокировки (ресурсов)
№ | Значение | Объяснение |
1 | LOCK BLOCK | Идентифицирует группу описания заблокированного ресурса. Число является смещением этой группы в таблице блокировок. Оно указывает группу в другой группе, которая на нее ссылается |
2 | Series (Серия) | Тип ресурса, представляемого этой блокировкой. Это серия типа 1 - ресурс базы данных |
3 | Parent (Родитель) | Родитель для всех блокировок, связанных с базой данных. Является блокировкой самой базы данных. Единственными блокировками ресурсов, которые имеют значение 0 для родителя, являются блокировки базы данных и журналы. Ключи, которые идентифицируют блокировки в серии, имеют смысл только в контексте базы данных. Обратите внимание: несовпадения (ошибки) будут замечены внимательным читателем |
4 | State (Состояние) | Наивысшее текущее состояние блокировки. Блокировки имеют семь возможных состояний - см. рис. 40.1. Состояния внутренних блокировок Firebird описаны в самом начале этой главы. Пустая блокировка позволяет процессу получить блокировку ресурса, независимо от того, заблокирован ли (и как) этот ресурс кем-либо другим. Получение такой блокировки позволяет этому владельцу читать данные самой блокировки. Firebird сохраняет важную, но быстро меняющуюся информацию в блокировках- см. разд. "Использование пустой блокировки" |
5 | Size (Размер) | Длина в байтах той части группы блокировки, которая содержит ключ. Размер округляется до естественных границ машины (слово, двойное слово, четыре слова) |
6 | Length (Длина) | Фактическая длина ключа, которая из-за округления может быть меньше, чем размер |
7 | Data (Данные) | Только блокировки журналов и транзакций содержат данные. Данные являются 32-битовым целым числом |
8 | Key (Ключ) | Идентификатор заблокированного ресурса. Комбинация ключа, серии и родителя уникально идентифицирует заблокированный ресурс. Для базы данных ключом является имя базы данных (или некоторый эквивалент). Он может не выводиться в системах, которые используют целые числа как идентификаторы. Для отношения и существующей блокировки отношения ключ является идентификатором отношения. Для существующей блокировки индекса ключом является идентификатор отношения * 1000 плюс идентификатор индекса. Для блокировки теневой копии ключом является NULL, потому что существует только одно состояние теневого копирования базы данных. Для транзакции ключом является идентификатор транзакции. Для соединения ключом является идентификатор соединения |
9 | Hash queue (Очередь) | Начало и конец очереди хэш для ключей ресурсов. Менеджер блокировок хранит хэш-таблицу для упрощения поиска ресурсов по имени. Когда процесс запрашивает блокировку ресурса, он задает ресурс по серии, родителю и ключу. Менеджер блокировок объединяет эти значения вместе для создания ключа хэш, а затем отыскивает в списке, связанном с этим хэш-ключом, группу нужной блокировки |
10 | Requests (Запросы) | Вначале количество запросов на блокировку этого ресурса, затем указатели вперед и назад на группы блокировок. Имейте в виду, что обратный указатель ссылается на конец последнего блока |
– - | Request (Запрос) | Список запросов, включая идентификатор запрашиваемой группы, процесс, выполняющий запрос, фактическое состояние блокировки с запрашиваемым состоянием в круглых скобках. Состояние 6(6) в этом случае указывает фактическое состояние 6 и запрашиваемое состояние 6 |
– - | Flags (Флаги) | Флаг запроса содержит биты, которые могут комбинироваться. Это: 1. Блокирование: запрос отмечается как заблокированный, если кто-то другой требует этот ресурс и не может его совместно использовать по причине текущего уровня блокировки. Блокирующий бит очищается, когда блокирующее сообщение отправляется блокирующему владельцу. 2. Ожидание завершения: это наиболее часто просматриваемый бит. Он указывает, что запрос ожидает, когда блокирующий процесс освободит эту блокировку. Вы не должны смотреть установку этого бита в блокировках BDB. 4. Конвертирование: запрос конвертируется, если процесс уже имеет блокировку этого ресурса и требует более высокого уровня блокировки, а преобразование не может быть выполнено немедленно. 8. Отмена: запрос блокировки отменяется, если запрос в режиме NO WAIT и не может быть удовлетворен немедленно или если удовлетворение запроса может привести к взаимной блокировке |
На рис. 40.5 показана группа для ресурса отношения (таблица, просмотр).
Рис. 40.5. Группа серии 2 (ресурс отношения)
В этом случае оба владельца читают отношение. Для отношения ключевым полем является значение RDB$RELATION_ID. Заметьте, что оба запроса сообщают о своем состоянии как 2(2), указывая, что они запросили и получили блокировку на совместное чтение таблицы.