postgresql tuple introduction

Article directory

  • foreword
  • tuple structure
  • Introduction to tuple headers
  • tuple assembly
  • end

foreword

This article is based on the analysis and interpretation of the postgresql 14 code, and the demonstration is carried out on the centos8 system.


1. tuple structure

 

	 +---------------------+---------------+----------------+
	 | HeapTupleHeaderData |  nulls bitmap | padding        |
	 +------------+--------+---------------+----------------+
	 | object ID  |  value1 value2 value3 ...               |
	 +------------+-----------------------------------------+
  

  Each row of data seen in the data table is stored in the form of tuple in the page. The structure of tuple is:

 

(1) HeapTupleHeaderData 

(2)nulls bitmap; This is an option, when the t_infomask has the HEAP_HASNULL flag, this array will have a value;

(3) padding ; The length of the null bitmap in front is uncertain. In order to align the subsequent data, here is the byte alignment of HeapTupleHeaderData+nulls bitmap, and there will be a blank here.

(4) OID value, this is an option, when t_infomask has HEAP_HASOID_OLD, it will have this value;

(5) user data; that is, the data of each column;

 

 

2. Introduction to tuple headers

 

struct HeapTupleHeaderData

{

    union

    {

        HeapTupleFields t_heap;

        DateTupleFields t_date ;

    }           t_choice;

    ItemPointerData t_ctid;     /* current TID of this or newer tuple (or a

                                 * speculative insertion token) */

    /* Fields below here must match MinimalTupleData! */

#define FIELDNO_HEAPTUPLEHEADERDATA_INFOMASK2 2

    uint16      t_infomask2;    /* number of attributes + various flags */

#define FIELDNO_HEAPTUPLEHEADERDATA_INFOMASK 3

    uint16      t_infomask;     /* various flag bits, see below */

#define FIELDNO_HEAPTUPLEHEADERDATA_HOFF 4

    uint8       t_hoff;         /* sizeof header incl. bitmap, padding */

    /* ^ - 23 bytes - ^ */

#define FIELDNO_HEAPTUPLEHEADERDATA_BITS 5

    bits8       t_bits[FLEXIBLE_ARRAY_MEMBER];  /* bitmap of NULLs */

    /* MORE DATA FOLLOWS AT END OF STRUCT */

};

  • field description

(1) t_choice

The union composed of the HeapTupleFields structure and the DatumTupleFields structure can be selected and used in the two cases of tuple construction and tuple in the page respectively, and cannot exist at the same time.

 

  • t_data

This structure needs to be filled when a tuple is constructed in memory. At this time, there is no need for visibility judgment and concurrency control information.

Structure description:

typedef struct DatumTupleFields

{

    int32       datum_len_;     /* varlena header (do not touch directly!) */

    int32       datum_typmod;   /* -1, or identifier of a record type */

    Oid         datum_typeid;   /* composite type OID, or RECORDOID */

    /*

     * datum_typeid cannot be a domain over composite, only plain composite,

     * even if the datum is meant as a value of a domain-over-composite type.

     * This is in line with the general principle that CoerceToDomain does not

     * change the physical representation of the base type value.

     *

     * Note: field ordering is chosen with thought that Oid might someday

     * widen to 64 bits.

     */

} DatumTupleFields;

 

 

  • t_heap

This structure must be populated when the tuple is added to the table's page . Directly convert DatumTupleFields to HeapTupleFields structure for use.

 

Structure description:

typedef struct HeapTupleFields

{

    TransactionId t_xmin;       /* inserting xact ID */

    TransactionId t_xmax;       /* deleting or locking xact ID */

    union

    {

        CommandId   t_cid;      /* inserting or deleting command ID, or both */

        TransactionId t_xvac;   /* old-style VACUUM FULL xact ID */

    }           t_field3;

} HeapTupleFields;

3. Tuple assembly

A new tuple will be assembled during insert/update, and then a page with enough remaining space will be found and added to it. Of course, there are certain strategies for finding a page with enough space, which will be discussed later.

  • Create a new tuple

HeapTuple

heap_form_tuple(TupleDesc tupleDescriptor,

                Datum *values,

                bool *isnull);

Calculate the len of the tuple in this interface, including the size of the value of the tupleheader+ each attribute column,

In addition, len also needs to include the size of the HeapTupleData structure, which records the row pointer data and tuple data, as well as their total length;

 

typedef struct HeapTupleData

{

    uint32      t_len;          /* length of *t_data */

    ItemPointerData t_self;     /* SelfItemPointer */

    Oid         t_tableOid;     /* table the tuple came from */

#define FIELDNO_HEAPTUPLEDATA_DATA 3

    HeapTupleHeader t_data;     /* -> tuple header and data */

} HeapTupleData;

 

Then t_choice . t_datum of t_data will be assigned a value, and the length value is the tuple length shifted to the left by 2 bits;

  • tuple operation

Assignment operation to t_choice.t_datum in tupleheader _

HeapTupleHeaderSetDatumLength(td, len);

HeapTupleHeaderSetTypeId(td, tupleDescriptor->tdtypeid);

HeapTupleHeaderSetTypMod(td, tupleDescriptor->tdtypmod);

  • Limit on the number of attribute columns

#define MaxTupleAttributeNumber 1664    /* 8 * 208 */

When constructing tuple in memory, it will judge whether this upper limit is exceeded

#define MaxHeapAttributeNumber  1600    /* 8 * 200 */

The maximum number of columns here is 1600. When the column field is long, it will be smaller than this number; this number is a certain margin.


end

Author email: [email protected]
If there are any mistakes or omissions, please point them out and learn from each other.

Note: Do not reprint without consent!

Guess you like

Origin blog.csdn.net/senllang/article/details/123674067