49.3. Emplacement des pages de la base de donn�es

Cette section fournit un aper�u du format des pages utilis�es par les tables et index de PostgreSQL.[1] Les s�quences et les tables TOAST tables sont format�es comme des tables standards.

Dans l'explication qui suit, un octet contient huit bits. De plus, le terme �l�ment fait r�f�rence � une valeur de donn�es individuelle qui est stock�e dans une page. Dans une table, un �l�ment est une ligne ; dans un index, un �l�ment est une entr�e d'index.

Chaque table et index est stock� comme un tableau de pages d'une taille fixe (habituellement 8 Ko, bien qu'une taille de page diff�rente peut �tre s�lectionn�e lors de la compilation du serveur). Dans une table, toutes les pages sont logiquement �quivalentes pour qu'un �l�ment (ligne) particulier puisse �tre stock� dans n'importe quelle page. Dans les index, la premi�re page est g�n�ralement r�serv�e comme m�tapage contenant des informations de contr�le, et il peut exister diff�rents types de pages � l'int�rieur de l'index, suivant la m�thode d'acc�s � l'index.

Tableau 49-2 affiche le contenu complet d'une page. Il existe cinq parties pour chaque page.

Tableau 49-2. Disposition g�n�rale d'une page

�l�mentDescription
PageHeaderDataLongueur de 20 octets. Contient des informations g�n�rales sur la page y compris des pointeurs sur les espaces libres.
ItemIdDataTableau de paires (d�calage,longueur) pointant sur les �l�ments r�els. Quatre octets par �l�ment.
Free spaceL'espace non allou�. Les pointeurs de nouveaux �l�ments sont allou�s � partir du d�but de cette r�gion, les nouveaux �l�ments � partir de la fin.
ItemsLes �l�ments eux-m�mes.
Special spaceDonn�es sp�cifiques des m�thodes d'acc�s aux index. Diff�rentes m�thodes stockent diff�rentes donn�es. Vide pour les tables ordinaires.

Les vingt premiers octets de chaque page consistent en un en-t�te de page (PageHeaderData). Son format est d�taill� dans Tableau 49-3. Les deux premiers champs traquent l'entr�e WAL la plus r�cente relative � cette page. Ils sont suivis par trois champs d'entiers sur deux octets (pd_lower, pd_upper et pd_special). Ils contiennent des d�calages d'octets � partir du d�but de la page jusqu'au d�but de l'espace non allou�, jusqu'� la fin de l'espace non allou�, et jusqu'au d�but de l'espace sp�cial. Les deux derniers octets de l'en-t�te de page, pd_pagesize_version, stockent � la fois la taille de la page et un indicateur de versoin. A partir de la version 8.0 de PostgreSQL, le num�ro de version est 2 ; PostgreSQL 7.3 et 7.4 ont utilis� le num�ro de version 1 ; les versions pr�c�dentes utilisaient le num�ro de version 0. (La disposition fondamentale de la page et le format de l'en-t�te n'ont pas chang� dans ces versions mais la disposition de l'en-t�te des lignes de t�te a chang�.) La taille de la page est seulement pr�sente comme v�rification crois�e ; il n'existe pas de support pour avoir plus d'une taille de page dans une installation.

Tableau 49-3. Disposition de PageHeaderData

ChampTypeLongueurDescription
pd_lsnXLogRecPtr8 octetsLSN : octet suivant le dernier octet de l'enregistrement xlog pour la derni�re modification de cette page
pd_tliTimeLineID4 octetsTLI de la derni�re modification
pd_lowerLocationIndex2 octetsD�calage jusqu'au d�but de l'espace libre
pd_upperLocationIndex2 octetsD�calage jusqu'� la fin de l'espace libre
pd_specialLocationIndex2 octetsD�calage jusqu'au d�but de l'espace sp�cial
pd_pagesize_versionuint162 octetsTaille de la page et disposition de l'information du num�ro de version

Tous les d�tails se trouvent dans src/include/storage/bufpage.h.

Apr�s l'en-t�te de la page se trouvent les identificateurs d'�l�ment (ItemIdData), chacun n�cessitant quatre octets. Un identificateur d'�l�ment contient un d�calage d'octet vers le d�but d'un �l�ment, sa longueur en octets, et quelques bits d'attributs qui affectent son interpr�tation. Les nouveaux identificateurs d'�l�ments sont allou�s si n�cessaire � partir du d�but de l'espace non allou�. Le nombre d'identificateurs d'�l�ments pr�sents peut �tre d�termin� en regardant pd_lower, qui est augment� pour allouer un nouvel identificateur. Comme un identificateur d'�l�ment n'est jamais d�plac� tant qu'il n'est pas lib�r�, son index pourrait �tre utilis� sur une base � long terme pour r�f�rencer un �l�ment, m�me quand l'�l�ment lui-m�me est d�plac� le long de la page pour compresser l'espace libre. En fait, chaque pointeur vers un �l�ment (ItemPointer, aussi connu sous le nom de CTID), cr�� par PostgreSQL consiste en un num�ro de page et l'index de l'identificateur d'�l�ment.

Les �l�ments eux-m�mes sont stock�s dans l'espace allou� en marche arri�re, � partir de la fin de l'espace non allou�. La structure exacte varie suivant le contenu de la table. Les tables et les s�quences utilisent toutes les deux une structure nomm�e HeapTupleHeaderData, d�crite ci-dessous.

La section finale est la <<�section sp�ciale�>> qui pourrait contenir tout ce que les m�thodes d'acc�s souhaitent stocker. Par exemple, les index b-tree stockent des liens vers les enfants gauche et droit de la page ainsi que quelques autres donn�es sur la structure de l'index. Les tables ordinaires n'utilisent pas du tout de section sp�ciale (indiqu�e en configurant pd_special � la taille de la page).

Toutes les lignes de la table sont structur�es de la m�me fa�on. Il existe un en-t�te � taille fixe (occupant 27 octets sur la plupart des machines), suivi par un bitmap NULL optionnel, un champ ID de l'objet optionnel et les donn�es de l'utilisateur. L'en-t�te est d�taill� dans Tableau 49-4. Les donn�es r�elles de l'utilisateur (les colonnes de la ligne) commencent �u d�calage indiqu� par t_hoff, qui doit toujours �tre un multiple de la distance MAXALIGN pour la plateforme. Le bitmap NULL est seulement pr�sent si le bit HEAP_HASNULL est initialis� dans t_infomask. S'il est pr�sent, il commence juste apr�s l'en-t�te fixe et occupe suffisamment d'octets pour avoir un bit par colonne de donn�es (c'est-�-dire t_natts bits ensemble). Dans cette liste de bits, un bit 1 indique une valeur non NULL, un bit 0 une valeur NULL. Quand le bitmap n'est pas pr�sent, toutes les colonnes sont suppos�es non NULL. L'ID de l'objet est seulement pr�sent si le bit HEAP_HASOID est initialis� dans t_infomask. S'il est pr�sent, il appara�t juste avant la limite t_hoff. Tout ajout n�cessaire pour faire de t_hoff un multiple de MAXALIGN appara�tra entre le bitmap NULL et l'ID de l'objet. (Ceci nous assure en retour que l'ID de l'objet est convenablement align�.)

Tableau 49-4. Disposition de HeapTupleHeaderData

ChampTypeLongueurDescription
t_xminTransactionId4 octetsins�re le tampon XID
t_cminCommandId4 octetsins�re le tampon CID
t_xmaxTransactionId4 octetssupprime le tampon XID
t_cmaxCommandId4 octetssupprime le tampon CID (surcharge avec t_xvac)
t_xvacTransactionId4 octetsXID pour l'op�ration VACUUM d�pla�ant une version de ligne
t_ctidItemPointerData6 octetsTID en cours pour cette version de ligne ou pour une version plus r�cente
t_nattsint162 octetsnombre d'attributs
t_infomaskuint162 octetsdiff�rents bits d'options (flag bits)
t_hoffuint81 octetd�calage vers les donn�es utilisateur

Tous les d�tails sont disponibles dans src/include/access/htup.h.

Interpr�ter les donn�es r�elles peut seulement se faire avec des informations obtenues � partir d'autres tables, principalement pg_attribute. Les valeurs cl�s n�cessaires pour identifier les emplacements des champs sont attlen et attalign. Il n'existe aucun moyen pour obtenir directement un attribut particulier, sauf quand il n'y a que des champs de largeur fixe et aucune colonne NULL. Tout ceci est emball� dans les fonctions heap_getattr, fastgetattr et heap_getsysattr.

Pour lire les donn�es, vous avez besoin d'examinez chaque attribut � son tour. Commencez par v�rifier si le champ est NULL en fonction du bitmap NULL. S'il l'est, allez au suivant. Puis, assurez-vous que vous avez le bon alignement. Si le champ est un champ � taille fixe, alors tous les octets sont plac�s simplement. S'il s'agit d'un champ � taille variable (attlen = -1), alors c'est un peu plus compliqu�. Tous les types de donn�es � longueur variable partagent la m�me structure commune d'en-t�te, varattrib, qui inclut la longueur totale de la valeur stock�e et quelques bits d'option. Suivant les options, les donn�es pourraient �tre soit dans la table de base soit dans une table TOAST ; elles pourraient aussi �tre compress�es (voir Section 49.2).

Notes

[1]

En r�alit�, les m�thodes d'acc�s par index n'ont pas besoin d'utiliser ce format de page. Toutes les m�thodes d'indexage existantes utilisent ce format de base mais les donn�es conserv�es dans les m�tapages des index ne suivent habituellement pas les r�gles d'emplacement des �l�ments.