Project

General

Profile

Anomalie #16925

[PDO] les requêtes préparées ne sont pas libérées

Added by Quentin RIBAC about 1 year ago. Updated 8 months ago.

Status:
Prêt à développer
Priority:
2-Sérieux
Assignee:
-
Target version:
Start date:
04/23/2021
Due date:
Tags Courrier:

Description

Maarch Courrier 20.10.10

Pour mon problème de script qui prenait toute la RAM, j’ai avancé. Voir l’image jointe pour se rendre compte de la gravité du problème, toute la mémoire vive et le swap sont occupés, soit plus de 20Go.

Ce sont des process postgres qui prennent la mémoire, pas php. En coupant mon script PHP la mémoire n’est pas libérée, ni en redémarrant PostgreSQL, mais en faisant un restart d’apache ça libère la mémoire. Donc pour moi le problème vient de Courrier. J’ai été voir dans les sources qui gèrent le PDO et j’ai fait cette petite modification :

diff --git a/src/core/models/DatabasePDO.php b/src/core/models/DatabasePDO.php
index 7328049bc5..08deb5b045 100755
--- a/src/core/models/DatabasePDO.php
+++ b/src/core/models/DatabasePDO.php
@@ -20,6 +20,10 @@ class DatabasePDO
     private static $type            = null;
     private static $preparedQueries = [];

+   public function __destruct() {
+       self::$preparedQueries = [];
+   }
+
     public function __construct(array $args = [])
     {
         if (!empty(self::$pdo)) {

et ça semble fonctionner.

J’ai testé en mettant self::reset(); dans le destructeur mais la recherche ne fonctionnait alors plus vu qu’il y a apparemment des tables temporaires dans la connexion.

Cette solution intermédiaire de détruire les requêtes préparées semble améliorer grandement l’utilisation de la mémoire, peut-être au détriment de la vitesse d’exécution, mais pas d’une façon que j’ai pu ressentir en tant qu’utilisateur.

Pouvez-vous valider que cette modification n’aura pas d’impact fonctionnel bloquant pour les utilisateurs, hormis un léger ralentissement ?
La modification ne serait à appliquer que le temps d’exécution d’un script de reprise de données à usage unique.

ram99pct.png (166 KB) ram99pct.png Quentin RIBAC, 04/23/2021 11:03 AM
7979

History

#1 Updated by Emmanuel DILLARD about 1 year ago

  • Status changed from A qualifier to A étudier
  • Assignee changed from EDI PO to Florian AZIZIAN
  • Target version changed from Inscription Backlog Courrier to 20.10 (Support actif)

#2 Updated by Quentin RIBAC about 1 year ago

Nouvelle suggestion de git diff :

diff --git a/rest/index.php b/rest/index.php
index e8314ba876..09ffeb1dd8 100755
--- a/rest/index.php
+++ b/rest/index.php
@@ -661,3 +661,4 @@ $app->put('/registeredMails/import', \RegisteredMail\controllers\RegisteredMailC
 $app->put('/registeredMails/{resId}', \RegisteredMail\controllers\RegisteredMailController::class . ':update');

 $app->run();
+\SrcCore\models\DatabasePDO::clearPreparedQueries();
diff --git a/src/core/models/DatabasePDO.php b/src/core/models/DatabasePDO.php
index 7328049bc5..b83a8ac19d 100755
--- a/src/core/models/DatabasePDO.php
+++ b/src/core/models/DatabasePDO.php
@@ -20,6 +20,10 @@ class DatabasePDO
     private static $type            = null;
     private static $preparedQueries = [];

+   public function clearPreparedQueries() {
+       self::$preparedQueries = [];
+   }
+
     public function __construct(array $args = [])
     {
         if (!empty(self::$pdo)) {

Ici on supprime les requêtes préparées une fois par appel REST et non à chaque destruction de DatabasePDO.

#3 Updated by Florian AZIZIAN about 1 year ago

  • Status changed from A étudier to Complément d'Informations
  • Assignee changed from Florian AZIZIAN to Quentin RIBAC

Cette deuxième suggestion me semble mieux.

Cependant, je trouve ça dangereux de l'intégrer dans le standard, car les requêtes SQL sont le cœur absolu de l'application.
Cela peut effectivement réduire les performances.

Je te propose de l'intégrer dans le code de ton client le temps de lancer le script de reprise (ne pas oublier supprimer le code quand c'est terminé).
Ou sinon, il est peut être possible d'optimiser ton script pour lancer le batch par lot de 1000 (c'est un chiffre au hasard car je ne connait pas ce que fait ton script). Comme ça la variable static $preparedQueries se videra tous les 1000 et ne grossira pas (et donc pas d'augmentation de la RAM).

#4 Updated by Emmanuel DILLARD about 1 year ago

  • Priority changed from 1-Majeur to 2-Sérieux

#5 Updated by Emmanuel DILLARD about 1 year ago

  • Status changed from Complément d'Informations to 17

#6 Updated by Quentin RIBAC about 1 year ago

  • Assignee changed from Quentin RIBAC to EDI PO
  • Priority changed from 2-Sérieux to 0-Bloquant

Lors de la mise en place de cette modification sur Maarch Courrier 20.03 sur le serveur, puis au lancement du script, le serveur est tombé : Out of Memory.

Je peux fournir le code de mon script pour que nous testions ensemble sur une instance locale.

Lors des essais sans modification du code de l’application, le serveur était out of memory à cause de postgres ; ici c’est le système de fichier répliqué glusterfs qui a été tué automatiquement pour libérer de la mémoire, coupant l’accès aux fichiers de configuration (custom) et stockage (docservers) pour les clients.

Il faut fournir une optimisation, sans quoi le script, que nous avons interrompu avant sa fin, ne pourra pas être exécuté entièrement ni les fois suivantes prévues.

C’est surtout un signe que l’API REST de Maarch Courrier ne supporte pas les appels massifs.

#7 Updated by Emmanuel DILLARD about 1 year ago

  • Status changed from 17 to A étudier
  • Assignee changed from EDI PO to Florian AZIZIAN
  • Priority changed from 0-Bloquant to 1-Majeur

#8 Updated by Emmanuel DILLARD about 1 year ago

  • Project changed from Backlog to CURRENT SPRINT
  • Status changed from A étudier to En cours de dev (S)

#9 Updated by Emmanuel DILLARD about 1 year ago

  • Due date set to 06/01/2021

#11 Updated by Florian AZIZIAN about 1 year ago

  • Assignee deleted (Florian AZIZIAN)

#12 Updated by Emmanuel DILLARD 12 months ago

  • Project changed from CURRENT SPRINT to Backlog
  • Status changed from En cours de dev (S) to Prêt à développer

#13 Updated by Florian AZIZIAN 12 months ago

  • Due date deleted (06/01/2021)

#14 Updated by Emmanuel DILLARD 12 months ago

  • Priority changed from 1-Majeur to 2-Sérieux

#15 Updated by Emmanuel DILLARD 12 months ago

  • Project changed from Backlog to Backlog Courrier
  • Target version changed from 20.10 (Support actif) to 20.10 (Actif)

Also available in: Atom PDF