postgres源码解析41 btree索引文件的创建--1

上述小节讲解了索引文件的物理创建,本篇讲解btree索引元组填充至索引文件的操作。先从数据结构入手,后深入执行流程。
postgres源码解析37 表创建执行全流程梳理–1
postgres源码解析37 表创建执行全流程梳理–2
postgres源码解析37 表创建执行全流程梳理–3
postgres源码解析37 表创建执行全流程梳理–4

数据结构与页面图

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

btree handler

该函数记录了btree 的访问方法参数和支持的回调函数

/*
 * Btree handler function: return IndexAmRoutine with access method parameters
 * and callbacks.
 */
Datum
bthandler(PG_FUNCTION_ARGS)
{
	IndexAmRoutine *amroutine = makeNode(IndexAmRoutine);

	amroutine->amstrategies = BTMaxStrategyNumber;
	amroutine->amsupport = BTNProcs;
	amroutine->amoptsprocnum = BTOPTIONS_PROC;
	amroutine->amcanorder = true;
	amroutine->amcanorderbyop = false;
	amroutine->amcanbackward = true;
	amroutine->amcanunique = true;
	amroutine->amcanmulticol = true;
	amroutine->amoptionalkey = true;
	amroutine->amsearcharray = true;
	amroutine->amsearchnulls = true;
	amroutine->amstorage = false;
	amroutine->amclusterable = true;
	amroutine->ampredlocks = true;
	amroutine->amcanparallel = true;
	amroutine->amcaninclude = true;
	amroutine->amusemaintenanceworkmem = false;
	amroutine->amparallelvacuumoptions =
		VACUUM_OPTION_PARALLEL_BULKDEL | VACUUM_OPTION_PARALLEL_COND_CLEANUP;
	amroutine->amkeytype = InvalidOid;

	amroutine->ambuild = btbuild;
	amroutine->ambuildempty = btbuildempty;
	amroutine->aminsert = btinsert;
	amroutine->ambulkdelete = btbulkdelete;
	amroutine->amvacuumcleanup = btvacuumcleanup;
	amroutine->amcanreturn = btcanreturn;
	amroutine->amcostestimate = btcostestimate;
	amroutine->amoptions = btoptions;
	amroutine->amproperty = btproperty;
	amroutine->ambuildphasename = btbuildphasename;
	amroutine->amvalidate = btvalidate;
	amroutine->amadjustmembers = btadjustmembers;
	amroutine->ambeginscan = btbeginscan;
	amroutine->amrescan = btrescan;
	amroutine->amgettuple = btgettuple;
	amroutine->amgetbitmap = btgetbitmap;
	amroutine->amendscan = btendscan;
	amroutine->ammarkpos = btmarkpos;
	amroutine->amrestrpos = btrestrpos;
	amroutine->amestimateparallelscan = btestimateparallelscan;
	amroutine->aminitparallelscan = btinitparallelscan;
	amroutine->amparallelrescan = btparallelrescan;

	PG_RETURN_POINTER(amroutine);
}

下面简单介绍重点回调函数的功能:

functionsdescription
btbuild将生成的元组填充至索引文件中,会调用IndexBuildHeapScan函数扫描基表以获取表中的元组构建索引元祖
btbuildempty在INIT_FORKNUM分支构建一个空的btree 索引
btinsert向btree插入索引元组,如果是唯一索引,则插入过程会进行该索引元祖是否存在
btbulkdelete删除所有指向heaptuple集合的索引条目,该集合元组由回调函数负责判断是否删除
btvacuumcleanup该函数通常在vacuum操作之后调用,主要做一些额外工作,如更新索引页的meta信息
btcanreturn检查btree 索引是否支持 Index-only scans, btree中返回值为 true
btconstestimate用于估算一个索引扫描的代价
btoptions用于分析和验证一个索引的reloptions数组,仅当一个索引存在非空reloptions数组时才会被调用
btbeginscan在btree 索引上开启扫描,其功能是构建索引扫描描述符结构体IndexScanDesc,后续的执行借助该结构体信息
btrescan用于重新开启扫描,通过该函数可以使用一个新的扫描关键字
btgettuple在给定的扫描描述符中获取下一个元组(按照给定的方向移动),获取成功保存该元组的TID
btgetbimap获取所有匹配的元组,并将其加入至bitmap
btendscan结束扫描并释放相应的资源
btmarkpos保存当前扫描位点,挂载至扫描描述符的opaque字段
btrestrpos将扫描恢复至最近标记的位置,与btmarkpos对应
索引相关的系统表

1 pg_am

postgres=# select * from pg_am;

 oid  | amname |      amhandler       | amtype 
------+--------+----------------------+--------
    2 | heap   | heap_tableam_handler | t
  403 | btree  | bthandler            | i
  405 | hash   | hashhandler          | i
  783 | gist   | gisthandler          | i
 2742 | gin    | ginhandler           | i
 4000 | spgist | spghandler           | i
 3580 | brin   | brinhandler          | i
(7 rows)

说明:记录了每一种索引类型的访问函数句柄

2 pg_index

                                                Table "pg_catalog.pg_index"
       Column        |     Type     | Collation | Nullable | Default | Storage  | Compression | Stats target | Description 
---------------------+--------------+-----------+----------+---------+----------+-------------+--------------+-------------
 indexrelid          | oid          |           | not null |         | plain    |             |              | 
 indrelid            | oid          |           | not null |         | plain    |             |              | 
 indnatts            | smallint     |           | not null |         | plain    |             |              | 
 indnkeyatts         | smallint     |           | not null |         | plain    |             |              | 
 indisunique         | boolean      |           | not null |         | plain    |             |              | 
 indnullsnotdistinct | boolean      |           | not null |         | plain    |             |              | 
 indisprimary        | boolean      |           | not null |         | plain    |             |              | 
 indisexclusion      | boolean      |           | not null |         | plain    |             |              | 
 indimmediate        | boolean      |           | not null |         | plain    |             |              | 
 indisclustered      | boolean      |           | not null |         | plain    |             |              | 
 indisvalid          | boolean      |           | not null |         | plain    |             |              | 
 indcheckxmin        | boolean      |           | not null |         | plain    |             |              | 
 indisready          | boolean      |           | not null |         | plain    |             |              | 
 indislive           | boolean      |           | not null |         | plain    |             |              | 
 indisreplident      | boolean      |           | not null |         | plain    |             |              | 
 indkey              | int2vector   |           | not null |         | plain    |             |              | 
 indcollation        | oidvector    |           | not null |         | plain    |             |              | 
 indclass            | oidvector    |           | not null |         | plain    |             |              | 
 indoption           | int2vector   |           | not null |         | plain    |             |              | 
 indexprs            | pg_node_tree | C         |          |         | extended |             |              | 
 indpred             | pg_node_tree | C         |          |         | extended |             |              | 
Indexes:
    "pg_index_indexrelid_index" PRIMARY KEY, btree (indexrelid)
    "pg_index_indrelid_index" btree (indrelid)
Access method: heap
ColumnDescription
indexrelid此索引的pg_class项的OID
indrelidindrelid 此索引的基表的pg_class项的OID
indnatts索引中的总列数(与pg_class.relnatts重复),这个数目包括键和被包括的属性
indnkeyatts索引中键列的编号,不计入任何的内含列,它们只是被存储但不参与索引的语义
indisunique如为真, 这是唯一索引
indisprimary如为真,表示索引为表的主键(如果此列为真,indisunique也总是为真)
indisexclusion如为真,此索引支持一个排他约束
indimmediate如为真,唯一性检查在插入时立即被执行(如果indisunique为假,此列无关)
indisclustered如果为真,表示表最后以此索引进行了聚簇
indisvalid如果为真,此索引当前可以用于查询。为假表示此索引可能不完整:它肯定还在被INSERT/UPDATE操作所修改,但它不能安全地被用于查询。如果索引是唯一索引,唯一性属性也不能被保证。
indcheckxmin如果为真,直到此pg_index行的xmin低于查询的TransactionXmin事务之前,查询都不能使用此索引,因为表可能包含具有它们可见的不相容行的损坏HOT链
indisready如果为真,表示此索引当前可以用于插入。为假表示索引必须被INSERT/UPDATE操作忽略。
indislive如果为假,索引正处于被删除过程中,并且必须被所有处理忽略(包括HOT安全的决策)
indisreplident如果为真,这个索引被选择为使用ALTER TABLE … REPLICA IDENTITY USING INDEX …的“replica identity”
indkey这是一个indnatts值的数组,它表示了此索引索引的表列。 例如一个1 3值可能表示表的第一和第三列组成了索引项。键列出现在非键(内含)列前面。 数组中的一个0表示对应的索引属性是一个在表列上的表达式,而不是一个简单的列引用。
indcollation对于索引键(indnkeyatts值)中的每一列,这包含要用于该索引的排序规则的OID,如果该列不是一种可排序数据类型则为零。
indclass对于索引键中的每一列(indnkeyatts值),这里包含了要使用的操作符类的OID。详见pg_opclass。
indoption这是一个indnkeyatts值的数组,用于存储每列的标志位。位的意义由索引的访问方法定义。
indexprs非简单列引用索引属性的表达式树(以nodeToString()形式)。对于indkey中每一个为0的项,这个列表中都有一个元素。如果所有的索引属性都是简单引用,此列为空。
indpred部分索引谓词的表达式树(以nodeToString()形式)。如果不是部分索引,此列为空。

3 pg_opclass

                                        Table "pg_catalog.pg_opclass"
    Column    |  Type   | Collation | Nullable | Default | Storage | Compression | Stats target | Description 
--------------+---------+-----------+----------+---------+---------+-------------+--------------+-------------
 oid          | oid     |           | not null |         | plain   |             |              | 
 opcmethod    | oid     |           | not null |         | plain   |             |              | 
 opcname      | name    |           | not null |         | plain   |             |              | 
 opcnamespace | oid     |           | not null |         | plain   |             |              | 
 opcowner     | oid     |           | not null |         | plain   |             |              | 
 opcfamily    | oid     |           | not null |         | plain   |             |              | 
 opcintype    | oid     |           | not null |         | plain   |             |              | 
 opcdefault   | boolean |           | not null |         | plain   |             |              | 
 opckeytype   | oid     |           | not null |         | plain   |             |              | 
Indexes:
    "pg_opclass_oid_index" PRIMARY KEY, btree (oid)
    "pg_opclass_am_name_nsp_index" UNIQUE CONSTRAINT, btree (opcmethod, opcname, opcnamespace)
Access method: heap

pg_opclass定义索引访问方法的操作符类。每一个操作符类定义了一种特定数据类型和一种特定索引访问方法的索引列的语义。一个操作符类实际上指定了一个特定的操作符族可以用于一个特定可索引列数据类型。该族中可用于索引列的操作符能够接受该列的数据类型作为它们的左输入。

ColumnDescription
opcmethod操作符类所属的索引访问方法
opcname操作符类的名称
opcnamespace操作符类所属的名字空间
opcowner操作符类的拥有者
opcfamily包含此操作符类的操作符集合
opcintype操作符类索引的数据类型
opcdefault如果此操作符类为opcintype的默认值则为真
opckeytype存储在索引中的数据的类型,如果值为0表示与opcintype相同

4 pg_opfamily

                                      Table "pg_catalog.pg_opfamily"
    Column    | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description 
--------------+------+-----------+----------+---------+---------+-------------+--------------+-------------
 oid          | oid  |           | not null |         | plain   |             |              | 
 opfmethod    | oid  |           | not null |         | plain   |             |              | 
 opfname      | name |           | not null |         | plain   |             |              | 
 opfnamespace | oid  |           | not null |         | plain   |             |              | 
 opfowner     | oid  |           | not null |         | plain   |             |              | 
Indexes:
    "pg_opfamily_oid_index" PRIMARY KEY, btree (oid)
    "pg_opfamily_am_name_nsp_index" UNIQUE CONSTRAINT, btree (opfmethod, opfname, opfnamespace)
Access method: heap

pg_opfamily定义了操作符族。每一个操作符族是操作符和相关支持例程的集合,支持例程用于实现一个特定索引访问方法的语义。此外,按照访问方法指定的某种方式,一个族内的操作符都是“兼容的”。操作符族概念允许在索引中使用跨数据类型操作符,并可以使用访问方法语义的知识推导出。

ColumnDescription
opfmethod操作符族适用的索引访问方法
opfname name操作符系列的名字
opfnamespace操作符系列所属的名字空间
opfowner操作符系列的拥有者

5 pg_amop

                                           Table "pg_catalog.pg_amop"
     Column     |   Type   | Collation | Nullable | Default | Storage | Compression | Stats target | Description 
----------------+----------+-----------+----------+---------+---------+-------------+--------------+-------------
 oid            | oid      |           | not null |         | plain   |             |              | 
 amopfamily     | oid      |           | not null |         | plain   |             |              | 
 amoplefttype   | oid      |           | not null |         | plain   |             |              | 
 amoprighttype  | oid      |           | not null |         | plain   |             |              | 
 amopstrategy   | smallint |           | not null |         | plain   |             |              | 
 amoppurpose    | "char"   |           | not null |         | plain   |             |              | 
 amopopr        | oid      |           | not null |         | plain   |             |              | 
 amopmethod     | oid      |           | not null |         | plain   |             |              | 
 amopsortfamily | oid      |           | not null |         | plain   |             |              | 
Indexes:
    "pg_amop_oid_index" PRIMARY KEY, btree (oid)
    "pg_amop_fam_strat_index" UNIQUE CONSTRAINT, btree (amopfamily, amoplefttype, amoprighttype, amopstrategy)
    "pg_amop_opr_fam_index" UNIQUE CONSTRAINT, btree (amopopr, amoppurpose, amopfamily)
Access method: heap

pg_amop存储关于与访问方法操作符族相关的操作符信息。对于一个操作符族中的每一个成员即操作符都在这个目录中有一行。一个成员可以是一个搜索操作符或者一个排序操作符。一个操作符可以出现在多个族中,但在同一个组中既不能出现在多个搜索位置也不能出现在多个排序位置(虽然不太可能出现,但是允许一个操作符同时用于搜索和排序目的)。

ColumnDescription
amopfamily这个操作符所在的操作符集合
amoplefttype操作符的左输入数据类型
amoprighttype操作符的右输入数据类型
amopstrategy操作符策略号
amoppurpose操作符目的,s表示搜索,o表示排序
amopopr操作符的OID
amopmethod使用此操作符集合的索引访问方法
amopsortfamily如果是一个排序操作符,该项会根据这个 B树操作符族排序,如果是一个搜索操作符则为0

6 pg_amproc

                                           Table "pg_catalog.pg_amproc"
     Column      |   Type   | Collation | Nullable | Default | Storage | Compression | Stats target | Description 
-----------------+----------+-----------+----------+---------+---------+-------------+--------------+-------------
 oid             | oid      |           | not null |         | plain   |             |              | 
 amprocfamily    | oid      |           | not null |         | plain   |             |              | 
 amproclefttype  | oid      |           | not null |         | plain   |             |              | 
 amprocrighttype | oid      |           | not null |         | plain   |             |              | 
 amprocnum       | smallint |           | not null |         | plain   |             |              | 
 amproc          | regproc  |           | not null |         | plain   |             |              | 
Indexes:
    "pg_amproc_oid_index" PRIMARY KEY, btree (oid)
    "pg_amproc_fam_proc_index" UNIQUE CONSTRAINT, btree (amprocfamily, amproclefttype, amprocrighttype, amprocnum)
Access method: heap

pg_amproc存储关于访问方法操作符族相关的支持函数。属于一个操作符族的每一个支持函数在这个目录中都有一行。

ColumnDescription
amprocfamily使用这个操作符的操作符集合
amproclefttype相关操作符的左输入数据类型
amprocrighttype相关操作符的右输入数据类型
amprocnum支持的函数编号
amproc函数的OID
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值