Vous n'êtes pas identifié(e).

#1 09/03/2020 13:36:46

LudovicG
Membre

Lossy bitmaps et work_mem

Bonjour,


Je me tire un peu les cheveux après avoir lu :
https://paquier.xyz/postgresql-2/postgr … heap-scan/
https://www.postgresql.org/message-id/0 … .ntt.co.jp


En substance, il serait question d'avoir un indice du work_mem qu'il faudrait par rapport à une requête présentant des "lossy bitmaps".


La formule donnée est :
work_mem (bytes) = (Number of lossy pages + number of exact pages) *
  (MAXALIGN(sizeof(HASHELEMENT)) + MAXALIGN(sizeof(PagetableEntry))
  + sizeof(Pointer) + sizeof(Pointer))


J'ai une requête présentant des lossy bitmaps mais je n'arrive déjà pas à retrouver la valeur de 3.2 MB donnée dans l'exemple !


En supposant que :
Number of lossy pages + number of exact pages = 39709 (Heap Blocks: exact=338 lossy=39371)
MAXALIGN(sizeof(HASHELEMENT)) = 8 car MAXALIGN sur un 64-bit est à 8, et que le HASHELEMENT ici est un int4 à 4
sizeof(Pointer) = 4


j'en arrive à :
3.2 MB = 39709 * ( 16 + MAXALIGN(sizeof(PagetableEntry)) )
mais dire que MAXALIGN(sizeof(PagetableEntry)) = 84 ... je n'arrive pas à l'expliquer (je commençais à calculer le Page Header de 23+1 bytes ... )


Merci d'éclairer ma lanterne.


Ludovic

Hors ligne

#2 09/03/2020 14:17:21

rjuju
Administrateur

Re : Lossy bitmaps et work_mem

Vous voulez dire 84 - 16?

Mais j'imagine que Michael avait un pc 64 bits, et donc sizeof(Pointer) == 8 et non 4, et de plus :

typedef struct HASHELEMENT
{
	struct HASHELEMENT *link;	/* link to next entry in same bucket */
	uint32		hashvalue;		/* hash function result for this entry */
} HASHELEMENT;

(gdb) p sizeof(HASHELEMENT )
$1 = 16

Hors ligne

#3 09/03/2020 15:54:42

LudovicG
Membre

Re : Lossy bitmaps et work_mem

Merci pour ce rapide retour.


Oui pardon je voulais dire 84-16 évidemment.


Effectivement, je partais mal avec mon sizeof(HASHELEMENT) (je pensais que c'était la place du type de la colonne de la table, la colonne sur laquelle se faisait le Hash ...)
Et pour le sizeof(Pointer), je n'avais dû tomber que sur des exemples 32-bit ...


Bref, je repars avec :
MAXALIGN(sizeof(HASHELEMENT)) = 16
sizeof(Pointer) = 8


Et j'arrive à :
3.2 MB = 39709 * ( MAXALIGN(sizeof(HASHELEMENT)) + MAXALIGN(sizeof(PagetableEntry)) + sizeof(Pointer) + sizeof(Pointer))
3.2 MB = 39709 * ( 16 + MAXALIGN(sizeof(PagetableEntry)) + 8 + 8)
Donc MAXALIGN(sizeof(PagetableEntry)) = 52,5008 ? disons 52 (et cela se tient : 39709*(32+52) = 39709*84 = 3335556 == 3,181034088 MB)
mais 52 ce n'est pas un multiple de 8 ... (et 48 et 56 sont trop loin)
le MAXALIGN serait bien un multiple de 8 sur un 64-bit ?


J'ai lu/relu aussi cette page : https://stackoverflow.com/questions/135 … -row-sizes
et j'ai envie de croire que je peux calculer la taille ainsi :
   23   -- heaptupleheader
+  1   -- padding or NULL bitmap
+  4   -- 1 * integer (no alignment padding here)
+  4   -- padding (pour arriver à un multiple de 8)
= 32
+  0   -- no padding since tuple ends at multiple of MAXALIGN


mais je dois m'égarer car je ne suis pas à 52.
La seule chose que je remarque c'est que 52 ressemble à l'exemple : 48 (un multiple de 8) + un item pointer à 4 bytes (mais on a dit que sizeof(Pointer) == 8 )


Bref, je cale encore.

Dernière modification par LudovicG (09/03/2020 15:57:12)


Ludovic

Hors ligne

#4 09/03/2020 16:25:23

rjuju
Administrateur

Re : Lossy bitmaps et work_mem

sizeof(PagetableEntry) == 48 == MAXALIGN(sizeof(PagetableEntry))


Le calcul donne 3176720, ce qui est "approximately 3.2MB of work_mem", sachant qu'il faut bien évidemment arrondir au supérieur plutôt qu'à l'inférieur.  À mon avis il ne faut pas chercher plus loin.

Hors ligne

#5 09/03/2020 16:35:59

LudovicG
Membre

Re : Lossy bitmaps et work_mem

Hum ok smile
Du coup, afin de pouvoir poursuivre sur mon cas perso, qu'est-ce que "PagetableEntry" ?
Si c'est une valeur fixe à 48 qu'il ne faut pas chercher à comprendre ok (mais sinon ...)


Ludovic

Hors ligne

#6 09/03/2020 16:39:25

rjuju
Administrateur

Re : Lossy bitmaps et work_mem

Il s'agit de la structure utilisée par les bitmap pour stocker le coeur de l'information: soit la liste des lignes  dans le cas d'une page bitmap "exact", soit une liste de blocs dans le cas contraire:

/*
 * The hashtable entries are represented by this data structure.  For
 * an exact page, blockno is the page number and bit k of the bitmap
 * represents tuple offset k+1.  For a lossy chunk, blockno is the first
 * page in the chunk (this must be a multiple of PAGES_PER_CHUNK) and
 * bit k represents page blockno+k.  Note that it is not possible to
 * have exact storage for the first page of a chunk if we are using
 * lossy storage for any page in the chunk's range, since the same
 * hashtable entry has to serve both purposes.
 *
 * recheck is used only on exact pages --- it indicates that although
 * only the stated tuples need be checked, the full index qual condition
 * must be checked for each (ie, these are candidate matches).
 */
typedef struct PagetableEntry
{
	BlockNumber blockno;		/* page number (hashtable key) */
	char		status;			/* hash entry status */
	bool		ischunk;		/* T = lossy storage, F = exact */
	bool		recheck;		/* should the tuples be rechecked? */
	bitmapword	words[Max(WORDS_PER_PAGE, WORDS_PER_CHUNK)];
} PagetableEntry;

Cela se trouve dans le fichier src/backend/nodes/tidbitmap.c.

Hors ligne

#7 09/03/2020 17:15:56

LudovicG
Membre

Re : Lossy bitmaps et work_mem

Ok, merci pour tout !
Ma lanterne vient de s'éclairer !


Ludovic

Hors ligne

Pied de page des forums