55.5. Блокировка строк в обёртках сторонних данных #
Если нижележащий механизм хранения FDW поддерживает концепцию блокировки отдельных строк, предотвращающую одновременное изменение этих строк, обычно имеет смысл реализовать в FDW установление блокировок на уровне строк в приближении, настолько близком к обычным таблицам Postgres Pro, насколько это возможно и практично. При этом нужно учитывать ряд замечаний.
Первое важное решение, которое нужно принять — будет ли реализована ранняя блокировка или поздняя блокировка. С ранней блокировкой строка блокируется, когда впервые считывается из нижележащего хранилища, тогда как с поздней блокировкой строка блокируется, только когда известно, что её нужно заблокировать. (Различие возникает из-за того, что некоторые строки могут быть отброшены локально проверяемыми условиями ограничений или соединений.) Ранняя блокировка гораздо проще и не требует дополнительных обращений к удалённому хранилищу, но может вызывать блокировку строк, которые можно было бы не блокировать, что может повлечь учащение конфликтов и даже неожиданные взаимоблокировки. Кроме того, поздняя блокировка возможна, только если блокируемая строка может быть однозначно идентифицирована позже. Поэтому в идентификаторе строки следует идентифицировать определённую версию строки, как это делает TID в Postgres Pro.
По умолчанию Postgres Pro игнорирует возможности блокировки, обращаясь к FDW, но FDW может установить ранние блокировки и без явной поддержки со стороны ядра. Функции, описанные в Подразделе 55.2.6, которые были добавлены в API в Postgres Pro 9.5, позволяют FDW применять поздние блокировки, если она этого пожелает.
Также следует учесть, что в режиме изоляции READ COMMITTED
серверу Postgres Pro может потребоваться перепроверить условия ограничений и соединения с изменённой версией некоторого целевого кортежа. Для перепроверки условий соединения требуется повторно получить копии исходных строк, которые ранее были соединены в целевой кортеж. В случае со стандартными таблицами Postgres Pro для этого в список столбцов, проходящих через соединение, включаются TID из исходных таблиц, а затем исходные строки извлекаются заново при необходимости. При таком подходе набор данных соединения остаётся компактным, но требуется недорогая операция повторного чтения строк, а также возможность однозначно идентифицировать повторно считываемую версию строки по TID. Поэтому по умолчанию при работе со сторонними таблицами в список столбцов, проходящих через соединение, включается копия всей строки, извлекаемой из сторонней таблицы. Это не накладывает специальных требований на FDW, но может привести к снижению производительности при соединении слиянием или по хешу. FDW, которая может удовлетворить требованиям повторного чтения, может реализовать первый вариант.
Для команд UPDATE
или DELETE
со сторонней таблицей рекомендуется, чтобы операция ForeignScan
в целевой таблице выполняла раннюю блокировку строк, которые она выбирает, возможно, используя аналог SELECT FOR UPDATE
. FDW может определить, является ли таблица целевой таблицей команд UPDATE
/DELETE
, во время планирования, сравнив её relid с root->parse->resultRelation
, или во время планирования, вызвав ExecRelationIsTargetRelation()
. Также возможно выполнять позднюю блокировку в обработчике ExecForeignUpdate
или ExecForeignDelete
, но специальной поддержки для этого нет.
Для сторонних таблиц, блокировка которых запрашивается командой SELECT FOR UPDATE/SHARE
, операция ForeignScan
так же может произвести раннюю блокировку, выбрав кортежи, используя аналог SELECT FOR UPDATE/SHARE
. Чтобы вместо этого произвести позднюю блокировку, предоставьте подпрограммы-обработчики, описанные в Подразделе 55.2.6. В GetForeignRowMarkType
выберите вариант отметки строк ROW_MARK_EXCLUSIVE
, ROW_MARK_NOKEYEXCLUSIVE
, ROW_MARK_SHARE
или ROW_MARK_KEYSHARE
, в зависимости от запрошенной силы блокировки. (Код ядра будет работать одинаково при любом из этих четырёх вариантов.) Затем вы сможете определить, должна ли сторонняя таблица блокироваться командой этого типа, вызвав функцию get_plan_rowmark
во время планирования либо ExecFindRowMark
во время выполнения; нужно проверить не только, что возвращённая структура rowmark отлична от NULL, но и что её поле strength
не равно LCS_NONE
.
Наконец, для сторонних таблиц, задействованных в командах UPDATE
, DELETE
или SELECT FOR UPDATE/SHARE
, но не требующих блокировки строк, можно переопределить поведение по умолчанию, заключающееся в копировании строк целиком, выбрав в GetForeignRowMarkType
вариант ROW_MARK_REFERENCE
, получив значение силы блокировки LCS_NONE
. В результате RefetchForeignRow
будет вызываться с таким значением markType
; она должна будет заново считывать строку, не запрашивая новую блокировку. (Если вы реализуете функцию GetForeignRowMarkType
, но не хотите повторно считывать незаблокированные строки, выберите для LCS_NONE
вариант ROW_MARK_COPY
.)
49.64. System Views
In addition to the system catalogs, Postgres Pro provides a number of built-in views. Some system views provide convenient access to some commonly used queries on the system catalogs. Other views provide access to internal server state.
The information schema (Chapter 34) provides an alternative set of views which overlap the functionality of the system views. Since the information schema is SQL-standard whereas the views described here are Postgres Pro-specific, it's usually better to use the information schema if it provides all the information you need.
Table 49.65 lists the system views described here. More detailed documentation of each view follows below. There are some additional views that provide access to the results of the statistics collector; they are described in Table 27.2.
Except where noted, all the views described here are read-only.
Table 49.65. System Views
View Name | Purpose |
---|---|
pg_available_extensions | available extensions |
pg_available_extension_versions | available versions of extensions |
pg_config | compile-time configuration parameters |
pg_cursors | open cursors |
pg_file_settings | summary of configuration file contents |
pg_group | groups of database users |
pg_hba_file_rules | summary of client authentication configuration file contents |
pg_indexes | indexes |
pg_locks | locks currently held or awaited |
pg_matviews | materialized views |
pg_policies | policies |
pg_prepared_statements | prepared statements |
pg_prepared_xacts | prepared transactions |
pg_publication_tables | publications and their associated tables |
pg_replication_origin_status | information about replication origins, including replication progress |
pg_replication_slots | replication slot information |
pg_roles | database roles |
pg_rules | rules |
pg_seclabels | security labels |
pg_sequences | sequences |
pg_settings | parameter settings |
pg_shadow | database users |
pg_stats | planner statistics |
pg_tables | tables |
pg_timezone_abbrevs | time zone abbreviations |
pg_timezone_names | time zone names |
pg_user | database users |
pg_user_mappings | user mappings |
pg_views | views |