栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

PostgreSQL数据库index——Index Access Method

PostgreSQL数据库index——Index Access Method

索引访问方法

src/backend/access/index/indexam.c 索引访问方法集合

  • INTERFACE ROUTINES
  •  index_open		- open an index relation by relation OID
    
  •  index_close		- close an index relation
    
  •  index_beginscan - start a scan of an index with amgettuple
    
  •  index_beginscan_bitmap - start a scan of an index with amgetbitmap
    
  •  index_rescan	- restart a scan of an index
    
  •  index_endscan	- end a scan
    
  •  index_insert	- insert an index tuple into a relation
    
  •  index_markpos	- mark a scan position
    
  •  index_restrpos	- restore a scan position
    
  •  index_parallelscan_estimate - estimate shared memory for parallel scan
    
  •  index_parallelscan_initialize - initialize parallel scan
    
  •  index_parallelrescan  - (re)start a parallel scan of an index
    
  •  index_beginscan_parallel - join parallel index scan
    
  •  index_getnext_tid	- get the next TID from a scan
    
  •  index_fetch_heap		- get the scan's next heap tuple
    
  •  index_getnext_slot	- get the next tuple from a scan
    
  •  index_getbitmap - get all tuples from a scan
    
  •  index_bulk_delete	- bulk deletion of index tuples
    
  •  index_vacuum_cleanup	- post-deletion cleanup of an index
    
  •  index_can_return	- does index support index-only scans?
    
  •  index_getprocid - get a support procedure OID
    
  •  index_getprocinfo - get a support procedure's lookup info
    

index_open函数通过relation OID打开一个index relation,主要是通过调用relation.c中函数获取RelationData结构体,PostgreSQL数据库RelationAM——relation related routines。

Relation index_open(Oid relationId, LOCKMODE lockmode) {
	Relation	r;
	r = relation_open(relationId, lockmode);
	if (r->rd_rel->relkind != RELKIND_INDEX &&
		r->rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
		ereport(ERROR,(errcode(ERRCODE_WRONG_OBJECT_TYPE),errmsg(""%s" is not an index",RelationGetRelationName(r))));
	return r;
}
void index_close(Relation relation, LOCKMODE lockmode) {
	LockRelId	relid = relation->rd_lockInfo.lockRelId;
	Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES);
	
	RelationClose(relation);
	if (lockmode != NoLock) UnlockRelationId(&relid, lockmode);
}

index_insert函数想relation中插入一个Index元组

bool index_insert(Relation indexRelation, Datum *values, bool *isnull, ItemPointer heap_t_ctid, Relation heapRelation, IndexUniqueCheck checkUnique, IndexInfo *indexInfo) {
	RELATION_CHECKS;
	CHECK_REL_PROCEDURE(aminsert);
	if (!(indexRelation->rd_indam->ampredlocks))
		CheckForSerializableConflictIn(indexRelation, (HeapTuple) NULL, InvalidBuffer);
	return indexRelation->rd_indam->aminsert(indexRelation, values, isnull, heap_t_ctid, heapRelation, checkUnique, indexInfo);
}
IndexAmRoutine

src/include/access/amapi.h

typedef struct IndexAmRoutine {
	NodeTag		type;
	
	uint16		amstrategies;
	
	uint16		amsupport;
	
	bool		amcanorder;
	
	bool		amcanorderbyop;
	
	bool		amcanbackward;
	
	bool		amcanunique;
	
	bool		amcanmulticol;
	
	bool		amoptionalkey;
	
	bool		amsearcharray;
	
	bool		amsearchnulls;
	
	bool		amstorage;
	
	bool		amclusterable;
	
	bool		ampredlocks;
	
	bool		amcanparallel;
	
	bool		amcaninclude;
	
	Oid			amkeytype;
	
	
	ambuild_function ambuild;
	ambuildempty_function ambuildempty;
	aminsert_function aminsert;
	ambulkdelete_function ambulkdelete;
	amvacuumcleanup_function amvacuumcleanup;
	amcanreturn_function amcanreturn;	
	amcostestimate_function amcostestimate;
	amoptions_function amoptions;
	amproperty_function amproperty; 
	ambuildphasename_function ambuildphasename; 
	amvalidate_function amvalidate;
	ambeginscan_function ambeginscan;
	amrescan_function amrescan;
	amgettuple_function amgettuple; 
	amgetbitmap_function amgetbitmap;	
	amendscan_function amendscan;
	ammarkpos_function ammarkpos;	
	amrestrpos_function amrestrpos; 
	
	amestimateparallelscan_function amestimateparallelscan; 
	aminitparallelscan_function aminitparallelscan; 
	amparallelrescan_function amparallelrescan; 
} IndexAmRoutine;

src/backend/access/index/amapi.c
GetIndexAmRoutine函数调用指定的access method handler routine获取IndexAmRoutine结构体。

IndexAmRoutine *GetIndexAmRoutine(Oid amhandler) {
	Datum		datum;
	IndexAmRoutine *routine;
	datum = OidFunctionCall0(amhandler);
	routine = (IndexAmRoutine *) DatumGetPointer(datum);
	if (routine == NULL || !IsA(routine, IndexAmRoutine))
		elog(ERROR, "index access method handler function %u did not return an IndexAmRoutine struct", amhandler);
	return routine;
}

GetIndexAmRoutineByAmId函数通过OID查找索引访问方法handler并获取其IndexAmRoutine结构体。

IndexAmRoutine *GetIndexAmRoutineByAmId(Oid amoid, bool noerror){
	HeapTuple	tuple;
	Form_pg_am	amform;
	regproc		amhandler;
	
	tuple = SearchSysCache1(AMOID, ObjectIdGetDatum(amoid));
	if (!HeapTupleIsValid(tuple)){
		if (noerror)
			return NULL;
		elog(ERROR, "cache lookup failed for access method %u",amoid);
	}
	amform = (Form_pg_am) GETSTRUCT(tuple);
	
	if (amform->amtype != AMTYPE_INDEX){
		if (noerror){
			ReleaseSysCache(tuple);
			return NULL;
		}
		ereport(ERROR,(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),errmsg("access method "%s" is not of type %s",NameStr(amform->amname), "INDEX")));
	}

	amhandler = amform->amhandler;
	
	if (!RegProcedureIsValid(amhandler)){
		if (noerror){
			ReleaseSysCache(tuple);
			return NULL;
		}
		ereport(ERROR,(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),errmsg("index access method "%s" does not have a handler",NameStr(amform->amname))));
	}

	ReleaseSysCache(tuple);

	
	return GetIndexAmRoutine(amhandler);
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/326625.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号