1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-26 12:21:12 +03:00

tableam: Don't assume that every AM uses md.c style storage.

Previously various parts of the code routed size requests through
RelationGetNumberOfBlocks[InFork]. That works if md.c is used by the
AM, but not otherwise.

Add a tableam callback to return the size of the table. As not every
AM will use postgres' BLCKSZ, have it return bytes, and have
RelationGetNumberOfBlocksInFork() round the byte size up into blocks.

To allow code outside of the AM to determine the actual relation size
map InvalidForkNumber the total size of a relation, as not every AM
might just need the postgres defined forks.

A few users of RelationGetNumberOfBlocks() ought to be converted away
from that. One case, the use of it to determine whether a tid is
valid, will be fixed in a follow up commit. Others will have to wait
for v13.

Author: Andres Freund
Discussion: https://postgr.es/m/20190423225201.3bbv6tbqzkb5w7cw@alap3.anarazel.de
This commit is contained in:
Andres Freund
2019-05-17 18:06:18 -07:00
parent 6630ccad7a
commit 7f44ede594
4 changed files with 110 additions and 3 deletions

View File

@ -33,6 +33,7 @@
#include <sys/file.h>
#include <unistd.h>
#include "access/tableam.h"
#include "access/xlog.h"
#include "catalog/catalog.h"
#include "catalog/storage.h"
@ -2789,14 +2790,50 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln)
/*
* RelationGetNumberOfBlocksInFork
* Determines the current number of pages in the specified relation fork.
*
* Note that the accuracy of the result will depend on the details of the
* relation's storage. For builtin AMs it'll be accurate, but for external AMs
* it might not be.
*/
BlockNumber
RelationGetNumberOfBlocksInFork(Relation relation, ForkNumber forkNum)
{
/* Open it at the smgr level if not already done */
RelationOpenSmgr(relation);
switch (relation->rd_rel->relkind)
{
case RELKIND_SEQUENCE:
case RELKIND_INDEX:
case RELKIND_PARTITIONED_INDEX:
/* Open it at the smgr level if not already done */
RelationOpenSmgr(relation);
return smgrnblocks(relation->rd_smgr, forkNum);
return smgrnblocks(relation->rd_smgr, forkNum);
case RELKIND_RELATION:
case RELKIND_TOASTVALUE:
case RELKIND_MATVIEW:
{
/*
* Not every table AM uses BLCKSZ wide fixed size
* blocks. Therefore tableam returns the size in bytes - but
* for the purpose of this routine, we want the number of
* blocks. Therefore divide, rounding up.
*/
uint64 szbytes;
szbytes = table_relation_size(relation, forkNum);
return (szbytes + (BLCKSZ - 1)) / BLCKSZ;
}
case RELKIND_VIEW:
case RELKIND_COMPOSITE_TYPE:
case RELKIND_FOREIGN_TABLE:
case RELKIND_PARTITIONED_TABLE:
default:
Assert(false);
break;
}
return 0; /* keep compiler quiet */
}
/*