Commit 45e191e3 authored by Andres Freund's avatar Andres Freund

Improve scalability of md.c for large relations.

So far md.c used a linked list of segments. That proved to be a problem
when processing large relations, because every smgr.c/md.c level access
to a page incurred walking through a linked list of all preceding
segments. Thus making accessing pages O(#segments).

Replace the linked list of segments hanging off SMgrRelationData with an
array of opened segments. That allows O(1) access to individual
segments, if they've previously been opened.

Discussion: <20140331101001.GE13135@alap3.anarazel.de>
Reviewed-By: Peter Geoghegan, Tom Lane (in an older version)
parent 417fefaf
This diff is collapsed.
......@@ -174,7 +174,7 @@ smgropen(RelFileNode rnode, BackendId backend)
/* mark it not open */
for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
reln->md_fd[forknum] = NULL;
reln->md_num_open_segs[forknum] = 0;
/* it has no owner yet */
add_to_unowned_list(reln);
......@@ -379,7 +379,7 @@ smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
* Exit quickly in WAL replay mode if we've already opened the file. If
* it's open, it surely must exist.
*/
if (isRedo && reln->md_fd[forknum] != NULL)
if (isRedo && reln->md_num_open_segs[forknum] > 0)
return;
/*
......
......@@ -64,8 +64,12 @@ typedef struct SMgrRelationData
*/
int smgr_which; /* storage manager selector */
/* for md.c; NULL for forks that are not open */
struct _MdfdVec *md_fd[MAX_FORKNUM + 1];
/*
* for md.c; per-fork arrays of the number of open segments
* (md_num_open_segs) and the segments themselves (md_seg_fds).
*/
int md_num_open_segs[MAX_FORKNUM + 1];
struct _MdfdVec *md_seg_fds[MAX_FORKNUM + 1];
/* if unowned, list link in list of all unowned SMgrRelations */
struct SMgrRelationData *next_unowned_reln;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment