Vous n'êtes pas identifié(e).
Bonjour
J'ai un fonctionnement lors de la réindexation d'une base sur une instance PostgreSQL (V12.6) que j'ai du mal à expliquer.
Avec un maintenance_work_mem positionné à '3MB', j'ai des fichiers base/pgsql_tmp/pgsql_tmp??????.? qui sont créés. Jusque la pas de souci.
Avec un maintenance_work_mem positionné à '10MB', je n'ai aucun fichier pgsql_tmp de créé. Ma base est très petite...
Avec un maintenance_work_mem positionné à '63MB', je n'ai aucun fichier pgsql_tmp de créé.
Par contre, en positionnant le maintenance_work_mem à '64MB' ou plus, il y a la création de fichiers base/pgsql_tmp/pgsql_tmp??????.?.sharedfileset/?.?
Pouvez-vous m'expliquer ce comportement de PostgreSQL s'il vous plait ?
Merci pour vos explications
Hors ligne
work_mem influe aussi sur l'usage de fichiers temporaires.
Sinon il faudrait positionner log_temp_files et consulter les logs pour avoir la corrélation entre l'usage disque et les requêtes SQL.
@DanielVerite
http://blog-postgresql.verite.pro/
Hors ligne
Merci pour ce retour.
J'ai le log_temp_file à 0, de façon a tracer l'ensemble des fichiers temp créés.
Mon interrogation est lors d'une réindexation complète d'une base. Donc work_mem ne doit pas jouer dans ce cas il me semble.
Hors ligne
Ce que voulais dire Daniel est que les fichiers "sharedfileset" pourraient être lié à l'activité d'autres requêtes, par forcément votre réindex.
Ces fichiers sont liés au parallélisme, donc il est cependant possible qu'avec un maintenance_work_mem assez haut et un max_parallel_maintenance_workers supérieur à 1 postgres choisisse un reindex utilisant le parallélisme.
Julien.
https://rjuju.github.io/
En ligne
Avec le log_temp_file, on a justement la trace qui me permet de savoir avec certitude que les fichiers générés le sont par la réindexation.
COMMAND:REINDEX - LOG: temporary file:...
Le max_parallel_maintenance_workers est la valeur par défaut, c'est à dire à 2.
Je suis aussi d'accord avec le fait que ces fichiers soient liés au parallélisme.
Je viens de tester en passant max_parallel_maintenance_workers à 0, et effectivement plus de fichier sharedfileset.
Est-ce qu'on pourrait dire qu'avec un maintenance_work_mem inférieur à 64MB, mon reindex est exécuté par un seul thread, alors qu'à partir de 64MB, Postgresql l'exécuterait en mode parallèle ? Dans ce cas pourquoi l'augmentation de maintenance_work_mem aurait un impact sur l'utilisation ou non du mode parallèle ?
Je tatillonne, mais ce n'est vraiment pas clair pour l'instant.....
Hors ligne
maintenance_work_mem se trouve partagé entre les processus parallèles, donc N processus en parallèle se retrouvent potentiellement avec maintenance_work_mem/N chacun. On peut penser effectivement que ça peut provoquer l'usage de disque temporaire qui n'aurait pas lieu sans parallélisme.
Pour la question de savoir si la valeur de maintenance_work_mem influe sur le choix du moteur de paralléliser ou pas, je ne vois rien dans ce sens. C'est même plutôt le contraire, d'après certains commentaires du code source: (fonction plan_create_index_workers)
/*
* If parallel_workers storage parameter is set for the table, accept that
* as the number of parallel worker processes to launch (though still cap
* at max_parallel_maintenance_workers). Note that we deliberately do not
* consider any other factor when parallel_workers is set. (e.g., memory
* use by workers.)
*/
if (rel->rel_parallel_workers != -1)
{
parallel_workers = Min(rel->rel_parallel_workers,
max_parallel_maintenance_workers);
goto done;
}
@DanielVerite
http://blog-postgresql.verite.pro/
Hors ligne
Sauf erreur cette partie du code n'est utilisée qu'en cas de ALTER TABLE SET (parallel_worker ...) non ?
Pour le cas "standard", maintenance_work_mem est bien pris en compte :
/*
* Cap workers based on available maintenance_work_mem as needed.
*
* Note that each tuplesort participant receives an even share of the
* total maintenance_work_mem budget. Aim to leave participants
* (including the leader as a participant) with no less than 32MB of
* memory. This leaves cases where maintenance_work_mem is set to 64MB
* immediately past the threshold of being capable of launching a single
* parallel worker to sort.
*/
while (parallel_workers > 0 &&
maintenance_work_mem / (parallel_workers + 1) < 32768L)
parallel_workers--;
Le seuil de 32MB en dur explique donc très bien le comportement constaté avec 64MB de maintenance_work_mem.
Julien.
https://rjuju.github.io/
En ligne
Oui je dis que "je ne vois rien dans ce sens" alors que c'est 10 lignes en-dessous dans la même fonction
Donc effectivement l'exécuteur évite le parallélisme si maintenance_work_mem est trop petit, avec le paradoxe que peut-être maintenance_work_mem plus grand => parallélisme => moins de mémoire par processus => écritures disque temporaires = moins d'efficacité
@DanielVerite
http://blog-postgresql.verite.pro/
Hors ligne
Certes, mais un tri à bien plus de chance d'être CPU bound qu'autre chose, et du coup le passage par un fichier temporaire pour partager des données entre les workers devrait en général apporter un gain. Surtout que le fichier a quand même de forte chance de rester en RAM, voire même ne jamais passer finir sur disque.
Julien.
https://rjuju.github.io/
En ligne
Merci à vous deux pour ces explications.
Je comprends mieux maintenant ce seuil de 64MB (32+32 pour 2 process parallèles). On en apprend tous les jours....
Malgré la parallélisation, le seuil des 2GB pour le maintenance_work_mem est bien toujours d'actualité ?
Hors ligne