Настройка базы данных для снижения дисковых конфликтов ввода/вывода поможет справиться с блокировками, однако в некоторых случаях хранимая процедура new_edit_state все равно может блокировать вызывающее приложение и все другие возможности использования базы геоданных.
Представьте себе ситуацию, когда хранимая процедура получает большое число блокировок строк из таблицы STATE_LINEAGES. При этом превышается ограничение максимального количества блокировок и совершается попытка эскалации до исключительной блокировки таблицы. К сожалению, в запросе вызывающего приложения уже имеется общая блокировка таблицы STATE_LINEAGES, в результате чего происходит полная блокировка. Большое количество блокировок строк связано с глубоким происхождением состояния. При этом низкое значение размера списка блокировок гарантирует возникновение проблем. В зависимости от обработки эскалации блокировок возможны и другие сценарии полной блокировки.
Здесь подразумевается, что блокировки могут нередко случаться на определенных сайтах, в зависимости от используемого вами приложения и конфигурации баз данных. Опять же, проблема может быть усугублена глубокими линиями состояний.
Однако в IBM Db2 имеются параметры для настройки контроля размера списка блокировок (LOCKLIST), максимальной доли блокировок в приложении (MAXLOCKS), времени ожидания получения блокировки запросом (LOCKTIMEOUT), интервала определения блокировки (DLCHKTIME) и действий при откате при полной блокировке (DB2LOCK_TO_RB).
Для увеличения вместимости списка блокировок и повышения ограничения эскалации блокировок следует соответственно изменить параметры LOCKLIST и MAXLOCKS.
По умолчанию параметры LOCKLIST и MAXLOCKS имеют значение AUTOMATIC, т.е. они настраиваются автоматически. Это позволяет диспетчеру памяти Db2 динамически распределять память между потребителями. Автоматическая настройка происходит только тогда, когда в базе данных включена самостоятельная настройка памяти (SELF_TUNING_MEM=ON).
Кроме того, может появиться возможность оптимизации параллельной работы посредством предотвращения блокировок. Для этого используются переменные реестра отсрочки блокировок Db2 DB2_EVALUNCOMMITED, DB2_SKIPDELETED и DB2_SKIPINSERTED. Эти переменные реестра допускают выполнение сканирования для безусловного пропуска незаписанных операций удаления и вставки.
По умолчанию по прошествии срока ожидания блокировки происходит откат запрошенной транзакции. Для баз геоданных в Db2 будет достаточно поведения по умолчанию.
Подробные сведения о том, как правильно настраивать эти параметры, см. документацию для Db2 в IBM Knowledge Center.
В следующем разделе предлагаются некоторые советы по диагностированию блокировок.
Диагностирование проблем блокировки
Ниже перечислено несколько полезных средств для диагностики проблем блокировки.
- Поиск идентификаторов приложения db2 для процессов ArcGIS.
SELECT appl_id FROM TABLE(SNAPSHOT_APPL_INFO('SDE',-1)) AS SNAPSHOT_APPL_INFO WHERE appl_name LIKE 'gsrvr%' SELECT appl_id,appl_name FROM TABLE(SNAPSHOT_APPL_INFO('SDE',-1))
- Использование снимков для получения информации о блокировках и приложении, например:Быстрый поиск интересующих элементов на снимке дает следующее:
db2 get snapshot for locks on sde > all_locks.txt db2 get snapshot for locks for application applid '*LOCAL.DB2.00AB42215335' > app_locks.txt db2 get snapshot for application applid '*LOCAL.DB2.00AB42215335' > app_info.txt
Application status = Lock-wait Locks held by application = 1254 Number of SQL requests since last commit = 12 Open local cursors = 1 Most recent operation = Execute Object type = Table Tablespace name = USERSPACE1 Table schema = SDE Table name = STATE_LINEAGES Mode = X Status = Converting Current mode = IX Lock escalation = YES
- Как указывалось выше, глубокое происхождение может быть проблемой при получении большого числа блокировок строк. Следующие выражения SQL позволяют быстро проверить глубину происхождения и максимальную глубину происхождения:
SELECT COUNT (*) FROM state_lineages GROUP BY lineage_name SELECT MAX(a.depth) FROM (SELECT COUNT (*) FROM state_lineages GROUP BY lineage_name) a(depth)