F.30. pageinspect#
F.30. pageinspect
Модуль pageinspect
предоставляет функции, которые позволяют вам
осматривать содержимое страниц базы данных на низком уровне, что полезно для
отладки. Все эти функции могут использоваться только суперпользователями.
F.30.1. Общие функции
-
get_raw_page(relname text, fork text, blkno bigint) returns bytea
get_raw_page
считывает указанный блок из именованного отношения и возвращает его копию в виде значенияbytea
. Это позволяет получить одну временно-согласованную копию блока.fork
должен быть'main'
для основного форка данных,'fsm'
для карты свободного пространства,'vm'
для карты видимости или'init'
для инициализационного форка.-
get_raw_page(relname text, blkno bigint) returns bytea
Сокращенная версия
get_raw_page
, для чтения из основного форка. Эквивалентноget_raw_page(relname, 'main', blkno)
-
page_header(page bytea) returns record
page_header
показывает поля, которые общие для всех страниц кучи и индекса Tantor SE.Изображение страницы, полученное с помощью функции
get_raw_page
, должно быть передано в качестве аргумента. Например:test=# SELECT * FROM page_header(get_raw_page('pg_class', 0)); lsn | checksum | flags | lower | upper | special | pagesize | version | prune_xid -----------+----------+--------+-------+-------+---------+----------+---------+----------- 0/24A1B50 | 0 | 1 | 232 | 368 | 8192 | 8192 | 4 | 0
Возвращаемые столбцы соответствуют полям в структуре
PageHeaderData
. См.src/include/storage/bufpage.h
для получения подробной информации.Поле
checksum
содержит контрольную сумму, хранящуюся на странице, которая может быть некорректной, если страница каким-либо образом повреждена. Если контрольные суммы данных не включены для этого экземпляра, то хранящееся значение бессмысленно.-
page_checksum(page bytea, blkno bigint) returns smallint
page_checksum
вычисляет контрольную сумму для страницы, как если бы она находилась в указанном блоке.Изображение страницы, полученное с помощью функции
get_raw_page
, должно быть передано в качестве аргумента. Например:test=# SELECT page_checksum(get_raw_page('pg_class', 0), 0); page_checksum --------------- 13443
Обратите внимание, что контрольная сумма зависит от номера блока, поэтому должны передаваться совпадающие номера блоков (за исключением случаев экзотической отладки).
Контрольная сумма, вычисленная с помощью этой функции, может быть сравнена с полем результата
checksum
функцииpage_header
. Если контрольные суммы данных включены для этого экземпляра, то два значения должны быть равными.-
fsm_page_contents(page bytea) returns text
fsm_page_contents
показывает внутреннюю структуру узла страницы FSM. Например:test=# SELECT fsm_page_contents(get_raw_page('pg_class', 'fsm', 0));
Вывод представляет собой многострочную строку, с одной строкой на каждый узел в бинарном дереве на странице. Печатаются только те узлы, которые не равны нулю. Также печатается так называемый "следующий" указатель, который указывает на следующий слот, который будет возвращен со страницы.
См.
src/backend/storage/freespace/README
для получения дополнительной информации о структуре страницы FSM.
F.30.2. Функции кучи
-
heap_page_items(page bytea) returns setof record
heap_page_items
показывает все указатели строк на странице кучи. Для тех указателей строк, которые используются, также показываются заголовки кортежей и сырые данные кортежей. Показываются все кортежи, независимо от того, были ли они видимы для снимка MVCC в момент копирования сырой страницы.Изображение страницы кучи, полученное с помощью функции
get_raw_page
, должно быть передано в качестве аргумента. Например:test=# SELECT * FROM heap_page_items(get_raw_page('pg_class', 0));
См.
src/include/storage/itemid.h
иsrc/include/access/htup_details.h
для объяснения возвращаемых полей.Функция
heap_tuple_infomask_flags
может быть использована для распаковки флаговых битовt_infomask
иt_infomask2
для кучевых кортежей.-
tuple_data_split(rel_oid oid, t_data bytea, t_infomask integer, t_infomask2 integer, t_bits text [, do_detoast bool]) returns bytea[]
tuple_data_split
разделяет данные кортежа на атрибуты таким же образом, как это делается внутри ядра.test=# SELECT tuple_data_split('pg_class'::regclass, t_data, t_infomask, t_infomask2, t_bits) FROM heap_page_items(get_raw_page('pg_class', 0));
Эта функция должна вызываться с теми же аргументами, что и возвращаемые атрибуты
heap_page_items
.Если
do_detoast
установлено вtrue
, атрибуты будут детостированы по мере необходимости. Значение по умолчанию -false
.-
heap_page_item_attrs(page bytea, rel_oid regclass [, do_detoast bool]) returns setof record
heap_page_item_attrs
эквивалентна функцииheap_page_items
, за исключением того, что она возвращает данные кортежа в виде массива атрибутов, которые могут быть опционально разжаты с помощью параметраdo_detoast
, который по умолчанию имеет значениеfalse
.Изображение страницы кучи, полученное с помощью функции
get_raw_page
, должно быть передано в качестве аргумента. Например:test=# SELECT * FROM heap_page_item_attrs(get_raw_page('pg_class', 0), 'pg_class'::regclass);
-
heap_tuple_infomask_flags(t_infomask integer, t_infomask2 integer) returns record
heap_tuple_infomask_flags
декодируетt_infomask
иt_infomask2
, возвращаемыеheap_page_items
, в человекочитаемый набор массивов из имен флагов, с одним столбцом для всех флагов и одним столбцом для комбинированных флагов. Например:test=# SELECT t_ctid, raw_flags, combined_flags FROM heap_page_items(get_raw_page('pg_class', 0)), LATERAL heap_tuple_infomask_flags(t_infomask, t_infomask2) WHERE t_infomask IS NOT NULL OR t_infomask2 IS NOT NULL;
Эта функция должна вызываться с теми же аргументами, что и возвращаемые атрибуты
heap_page_items
.Все комбинированные флаги отображаются для макросов на уровне исходного кода, которые учитывают значение более чем одного сырого бита, таких как
HEAP_XMIN_FROZEN
.См.
src/include/access/htup_details.h
для объяснения возвращаемых имен флагов.
F.30.3. Функции B-дерева
-
bt_metap(relname text) returns record
bt_metap
возвращает информацию о метаплоскости индекса B-дерева. Например:test=# SELECT * FROM bt_metap('pg_cast_oid_index'); -[ RECORD 1 ]-------------+------- magic | 340322 version | 4 root | 1 level | 0 fastroot | 1 fastlevel | 0 last_cleanup_num_delpages | 0 last_cleanup_num_tuples | 230 allequalimage | f
-
bt_page_stats(relname text, blkno bigint) returns record
bt_page_stats
возвращает сводную информацию о отдельных страницах индексов B-дерева. Например:test=# SELECT * FROM bt_page_stats('pg_cast_oid_index', 1); -[ RECORD 1 ]-+----- blkno | 1 type | l live_items | 224 dead_items | 0 avg_item_size | 16 page_size | 8192 free_size | 3668 btpo_prev | 0 btpo_next | 0 btpo_level | 0 btpo_flags | 3
-
bt_page_items(relname text, blkno bigint) returns setof record
bt_page_items
возвращает подробную информацию о всех элементах на странице индекса B-дерева. Например:test=# SELECT itemoffset, ctid, itemlen, nulls, vars, data, dead, htid, tids[0:2] AS some_tids FROM bt_page_items('tenk2_hundred', 5); itemoffset | ctid | itemlen | nulls | vars | data | dead | htid | some_tids ------------+-----------+---------+-------+------+-------------------------+------+--------+--------------------- 1 | (16,1) | 16 | f | f | 30 00 00 00 00 00 00 00 | | | 2 | (16,8292) | 616 | f | f | 24 00 00 00 00 00 00 00 | f | (1,6) | {"(1,6)","(10,22)"} 3 | (16,8292) | 616 | f | f | 25 00 00 00 00 00 00 00 | f | (1,18) | {"(1,18)","(4,22)"} 4 | (16,8292) | 616 | f | f | 26 00 00 00 00 00 00 00 | f | (4,18) | {"(4,18)","(6,17)"} 5 | (16,8292) | 616 | f | f | 27 00 00 00 00 00 00 00 | f | (1,2) | {"(1,2)","(1,19)"} 6 | (16,8292) | 616 | f | f | 28 00 00 00 00 00 00 00 | f | (2,24) | {"(2,24)","(4,11)"} 7 | (16,8292) | 616 | f | f | 29 00 00 00 00 00 00 00 | f | (2,17) | {"(2,17)","(11,2)"} 8 | (16,8292) | 616 | f | f | 2a 00 00 00 00 00 00 00 | f | (0,25) | {"(0,25)","(3,20)"} 9 | (16,8292) | 616 | f | f | 2b 00 00 00 00 00 00 00 | f | (0,10) | {"(0,10)","(0,14)"} 10 | (16,8292) | 616 | f | f | 2c 00 00 00 00 00 00 00 | f | (1,3) | {"(1,3)","(3,9)"} 11 | (16,8292) | 616 | f | f | 2d 00 00 00 00 00 00 00 | f | (6,28) | {"(6,28)","(11,1)"} 12 | (16,8292) | 616 | f | f | 2e 00 00 00 00 00 00 00 | f | (0,27) | {"(0,27)","(1,13)"} 13 | (16,8292) | 616 | f | f | 2f 00 00 00 00 00 00 00 | f | (4,17) | {"(4,17)","(4,21)"} (13 rows)
Это листовая страница B-дерева. Все кортежи, указывающие на таблицу, являются кортежами списка публикаций (все они хранят в себе 100 TID-ов длиной 6 байтов). Также есть кортеж “high key” с номером
itemoffset
равным 1.ctid
используется для хранения закодированной информации о каждом кортеже в этом примере, хотя кортежи листовых страниц часто хранят непосредственно в полеctid
ссылку на кучу.tids
- это список TID-ов, хранящихся в виде списка публикаций.Во внутренней странице (не показано) часть номера блока
ctid
является “downlink”, который является номером блока другой страницы в самом индексе. Часть смещения (второе число)ctid
хранит закодированную информацию о кортеже, такую как количество присутствующих столбцов (суффиксное усечение может удалить ненужные суффиксные столбцы). Усеченные столбцы рассматриваются как имеющие значение “минус бесконечность”.htid
показывает heap TID для кортежа, независимо от его внутреннего представления. Это значение может совпадать сctid
, или может быть декодировано из альтернативных представлений, используемых кортежами списка публикаций и кортежами из внутренних страниц. Кортежи во внутренних страницах обычно имеют усеченный столбец heap TID на уровне реализации, который представлен как NULL значениеhtid
.Обратите внимание, что первый элемент на любой странице, кроме самой правой (любой страницы с ненулевым значением в поле
btpo_next
), является "верхним ключом" страницы, что означает, что егоdata
служит верхней границей для всех элементов, появляющихся на странице, в то время как его полеctid
не указывает на другой блок. Кроме того, на внутренних страницах первый реальный элемент данных (первый элемент, который не является верхним ключом) надежно обрезается, не оставляя фактического значения в его полеdata
. Однако у такого элемента есть действительная ссылка в его полеctid
.Для получения более подробной информации о структуре индексов B-дерева, см. Раздел 65.4.1. Для получения более подробной информации о дедупликации и списке публикаций, см. Раздел 65.4.3.
-
bt_page_items(page bytea) returns setof record
Также возможно передать страницу в качестве значения типа
bytea
в функциюbt_page_items
. В качестве аргумента следует передать изображение страницы, полученное с помощью функцииget_raw_page
. Таким образом, последний пример можно переписать следующим образом:test=# SELECT itemoffset, ctid, itemlen, nulls, vars, data, dead, htid, tids[0:2] AS some_tids FROM bt_page_items(get_raw_page('tenk2_hundred', 5)); itemoffset | ctid | itemlen | nulls | vars | data | dead | htid | some_tids ------------+-----------+---------+-------+------+-------------------------+------+--------+--------------------- 1 | (16,1) | 16 | f | f | 30 00 00 00 00 00 00 00 | | | 2 | (16,8292) | 616 | f | f | 24 00 00 00 00 00 00 00 | f | (1,6) | {"(1,6)","(10,22)"} 3 | (16,8292) | 616 | f | f | 25 00 00 00 00 00 00 00 | f | (1,18) | {"(1,18)","(4,22)"} 4 | (16,8292) | 616 | f | f | 26 00 00 00 00 00 00 00 | f | (4,18) | {"(4,18)","(6,17)"} 5 | (16,8292) | 616 | f | f | 27 00 00 00 00 00 00 00 | f | (1,2) | {"(1,2)","(1,19)"} 6 | (16,8292) | 616 | f | f | 28 00 00 00 00 00 00 00 | f | (2,24) | {"(2,24)","(4,11)"} 7 | (16,8292) | 616 | f | f | 29 00 00 00 00 00 00 00 | f | (2,17) | {"(2,17)","(11,2)"} 8 | (16,8292) | 616 | f | f | 2a 00 00 00 00 00 00 00 | f | (0,25) | {"(0,25)","(3,20)"} 9 | (16,8292) | 616 | f | f | 2b 00 00 00 00 00 00 00 | f | (0,10) | {"(0,10)","(0,14)"} 10 | (16,8292) | 616 | f | f | 2c 00 00 00 00 00 00 00 | f | (1,3) | {"(1,3)","(3,9)"} 11 | (16,8292) | 616 | f | f | 2d 00 00 00 00 00 00 00 | f | (6,28) | {"(6,28)","(11,1)"} 12 | (16,8292) | 616 | f | f | 2e 00 00 00 00 00 00 00 | f | (0,27) | {"(0,27)","(1,13)"} 13 | (16,8292) | 616 | f | f | 2f 00 00 00 00 00 00 00 | f | (4,17) | {"(4,17)","(4,21)"} (13 rows)
Все остальные детали остаются такими же, как объяснено в предыдущем пункте.
F.30.4. Функции BRIN
-
brin_page_type(page bytea) returns text
brin_page_type
возвращает тип страницы данной индексной страницы BRIN или вызывает ошибку, если страница не является допустимой страницей BRIN. Например:test=# SELECT brin_page_type(get_raw_page('brinidx', 0)); brin_page_type ---------------- meta
-
brin_metapage_info(page bytea) returns record
brin_metapage_info
возвращает различную информацию о метапейдже индекса BRIN. Например:test=# SELECT * FROM brin_metapage_info(get_raw_page('brinidx', 0)); magic | version | pagesperrange | lastrevmappage ------------+---------+---------------+---------------- 0xA8109CFA | 1 | 4 | 2
-
brin_revmap_data(page bytea) returns setof tid
brin_revmap_data
возвращает список идентификаторов кортежей в странице карты диапазона индекса BRIN. Например:test=# SELECT * FROM brin_revmap_data(get_raw_page('brinidx', 2)) LIMIT 5; pages --------- (6,137) (6,138) (6,139) (6,140) (6,141)
-
brin_page_items(page bytea, index oid) returns setof record
brin_page_items
возвращает данные, хранящиеся на странице данных BRIN. Например:test=# SELECT * FROM brin_page_items(get_raw_page('brinidx', 5), 'brinidx') ORDER BY blknum, attnum LIMIT 6; itemoffset | blknum | attnum | allnulls | hasnulls | placeholder | value ------------+--------+--------+----------+----------+-------------+-------------- 137 | 0 | 1 | t | f | f | 137 | 0 | 2 | f | f | f | {1 .. 88} 138 | 4 | 1 | t | f | f | 138 | 4 | 2 | f | f | f | {89 .. 176} 139 | 8 | 1 | t | f | f | 139 | 8 | 2 | f | f | f | {177 .. 264}
Возвращаемые столбцы соответствуют полям в структурах
BrinMemTuple
иBrinValues
. См.src/include/access/brin_tuple.h
для получения подробной информации.
F.30.5. Функции GIN
-
gin_metapage_info(page bytea) returns record
gin_metapage_info
возвращает информацию о метаплоскости индекса GIN. Например:test=# SELECT * FROM gin_metapage_info(get_raw_page('gin_index', 0)); -[ RECORD 1 ]----+----------- pending_head | 4294967295 pending_tail | 4294967295 tail_free_size | 0 n_pending_pages | 0 n_pending_tuples | 0 n_total_pages | 7 n_entry_pages | 6 n_data_pages | 0 n_entries | 693 version | 2
-
gin_page_opaque_info(page bytea) returns record
gin_page_opaque_info
возвращает информацию о непрозрачной области индекса GIN, такую как тип страницы. Например:test=# SELECT * FROM gin_page_opaque_info(get_raw_page('gin_index', 2)); rightlink | maxoff | flags -----------+--------+------------------------ 5 | 0 | {data,leaf,compressed} (1 row)
-
gin_leafpage_items(page bytea) returns setof record
gin_leafpage_items
возвращает информацию о данных, хранящихся на листовой странице GIN. Например:test=# SELECT first_tid, nbytes, tids[0:5] AS some_tids FROM gin_leafpage_items(get_raw_page('gin_test_idx', 2)); first_tid | nbytes | some_tids -----------+--------+---------------------------------------------------------- (8,41) | 244 | {"(8,41)","(8,43)","(8,44)","(8,45)","(8,46)"} (10,45) | 248 | {"(10,45)","(10,46)","(10,47)","(10,48)","(10,49)"} (12,52) | 248 | {"(12,52)","(12,53)","(12,54)","(12,55)","(12,56)"} (14,59) | 320 | {"(14,59)","(14,60)","(14,61)","(14,62)","(14,63)"} (167,16) | 376 | {"(167,16)","(167,17)","(167,18)","(167,19)","(167,20)"} (170,30) | 376 | {"(170,30)","(170,31)","(170,32)","(170,33)","(170,34)"} (173,44) | 197 | {"(173,44)","(173,45)","(173,46)","(173,47)","(173,48)"} (7 rows)
F.30.6. Функции GiST
-
gist_page_opaque_info(page bytea) returns record
gist_page_opaque_info
возвращает информацию из непрозрачной области страницы индекса GiST, такую как NSN, rightlink и тип страницы. Например:test=# SELECT * FROM gist_page_opaque_info(get_raw_page('test_gist_idx', 2)); lsn | nsn | rightlink | flags -----+-----+-----------+-------- 0/1 | 0/0 | 1 | {leaf} (1 row)
-
gist_page_items(page bytea, index_oid regclass) returns setof record
gist_page_items
возвращает информацию о данных, хранящихся на странице индекса GiST. Например:test=# SELECT * FROM gist_page_items(get_raw_page('test_gist_idx', 0), 'test_gist_idx'); itemoffset | ctid | itemlen | dead | keys ------------+-----------+---------+------+------------------------------- 1 | (1,65535) | 40 | f | (p)=("(185,185),(1,1)") 2 | (2,65535) | 40 | f | (p)=("(370,370),(186,186)") 3 | (3,65535) | 40 | f | (p)=("(555,555),(371,371)") 4 | (4,65535) | 40 | f | (p)=("(740,740),(556,556)") 5 | (5,65535) | 40 | f | (p)=("(870,870),(741,741)") 6 | (6,65535) | 40 | f | (p)=("(1000,1000),(871,871)") (6 rows)
-
gist_page_items_bytea(page bytea) returns setof record
То же самое, что и
gist_page_items
, но возвращает ключевые данные в виде сырого блобаbytea
. Поскольку он не пытается декодировать ключ, ему не нужно знать, с каким индексом связаны данные. Например:test=# SELECT * FROM gist_page_items_bytea(get_raw_page('test_gist_idx', 0)); itemoffset | ctid | itemlen | dead | key_data ------------+-----------+---------+------+------------------------------------------------------------------------------------ 1 | (1,65535) | 40 | f | \x00000100ffff28000000000000c064400000000000c06440000000000000f03f000000000000f03f 2 | (2,65535) | 40 | f | \x00000200ffff28000000000000c074400000000000c074400000000000e064400000000000e06440 3 | (3,65535) | 40 | f | \x00000300ffff28000000000000207f400000000000207f400000000000d074400000000000d07440 4 | (4,65535) | 40 | f | \x00000400ffff28000000000000c084400000000000c084400000000000307f400000000000307f40 5 | (5,65535) | 40 | f | \x00000500ffff28000000000000f089400000000000f089400000000000c884400000000000c88440 6 | (6,65535) | 40 | f | \x00000600ffff28000000000000208f400000000000208f400000000000f889400000000000f88940 7 | (7,65535) | 40 | f | \x00000700ffff28000000000000408f400000000000408f400000000000288f400000000000288f40 (7 rows)
F.30.7. Функции хеширования
-
hash_page_type(page bytea) returns text
hash_page_type
возвращает тип страницы данного индекса HASH. Например:test=# SELECT hash_page_type(get_raw_page('con_hash_index', 0)); hash_page_type ---------------- metapage
-
hash_page_stats(page bytea) returns setof record
hash_page_stats
возвращает информацию о странице корзины или переполнения HASH индекса. Например:test=# SELECT * FROM hash_page_stats(get_raw_page('con_hash_index', 1)); -[ RECORD 1 ]---+----------- live_items | 407 dead_items | 0 page_size | 8192 free_size | 8 hasho_prevblkno | 4096 hasho_nextblkno | 8474 hasho_bucket | 0 hasho_flag | 66 hasho_page_id | 65408
-
hash_page_items(page bytea) returns setof record
hash_page_items
возвращает информацию о данных, хранящихся в корзине или переполненной странице индексной страницы типа HASH. Например:test=# SELECT * FROM hash_page_items(get_raw_page('con_hash_index', 1)) LIMIT 5; itemoffset | ctid | data ------------+-----------+------------ 1 | (899,77) | 1053474816 2 | (897,29) | 1053474816 3 | (894,207) | 1053474816 4 | (892,159) | 1053474816 5 | (890,111) | 1053474816
-
hash_bitmap_info(index oid, blkno bigint) returns record
hash_bitmap_info
показывает статус бита в странице битовой карты для конкретной переполненной страницы индекса HASH. Например:test=# SELECT * FROM hash_bitmap_info('con_hash_index', 2052); bitmapblkno | bitmapbit | bitstatus -------------+-----------+----------- 65 | 3 | t
-
hash_metapage_info(page bytea) returns record
hash_metapage_info
возвращает информацию, хранящуюся на метастранице индекса HASH. Например:test=# SELECT magic, version, ntuples, ffactor, bsize, bmsize, bmshift, test-# maxbucket, highmask, lowmask, ovflpoint, firstfree, nmaps, procid, test-# regexp_replace(spares::text, '(,0)*}', '}') as spares, test-# regexp_replace(mapp::text, '(,0)*}', '}') as mapp test-# FROM hash_metapage_info(get_raw_page('con_hash_index', 0)); -[ RECORD 1 ]------------------------------------------------------------------------------- magic | 105121344 version | 4 ntuples | 500500 ffactor | 40 bsize | 8152 bmsize | 4096 bmshift | 15 maxbucket | 12512 highmask | 16383 lowmask | 8191 ovflpoint | 28 firstfree | 1204 nmaps | 1 procid | 450 spares | {0,0,0,0,0,0,1,1,1,1,1,1,1,1,3,4,4,4,45,55,58,59,508,567,628,704,1193,1202,1204} mapp | {65}