Projet

Général

Profil

Anomalie #16925

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

Ajouté par Quentin RIBAC il y a environ 3 ans. Mis à jour il y a 9 mois.

Statut:
Résolu
Priorité:
2-Sérieux
Assigné à:
-
Version cible:
Début:
23/04/2021
Echéance:
Version applicable MC:
2301
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 ko) ram99pct.png Quentin RIBAC, 23/04/2021 11:03
7979

Historique

#1 Mis à jour par Emmanuel DILLARD il y a environ 3 ans

  • Statut changé de A qualifier à R&D - A étudier
  • Assigné à changé de EDI PO à Florian AZIZIAN
  • Version cible changé de Inscription Backlog Courrier à 20.10 (Fin de vie)

#2 Mis à jour par Quentin RIBAC il y a environ 3 ans

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 Mis à jour par Florian AZIZIAN il y a environ 3 ans

  • Statut changé de R&D - A étudier à Complément d'Informations
  • Assigné à changé de Florian AZIZIAN à 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 Mis à jour par Emmanuel DILLARD il y a presque 3 ans

  • Priorité changé de 1-Majeur à 2-Sérieux

#5 Mis à jour par Emmanuel DILLARD il y a presque 3 ans

  • Statut changé de Complément d'Informations à 17

#6 Mis à jour par Quentin RIBAC il y a presque 3 ans

  • Assigné à changé de Quentin RIBAC à EDI PO
  • Priorité changé de 2-Sérieux à 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 Mis à jour par Emmanuel DILLARD il y a presque 3 ans

  • Statut changé de 17 à R&D - A étudier
  • Assigné à changé de EDI PO à Florian AZIZIAN
  • Priorité changé de 0-Bloquant à 1-Majeur

#8 Mis à jour par Emmanuel DILLARD il y a presque 3 ans

  • Projet changé de Backlog à CURRENT SPRINT
  • Statut changé de R&D - A étudier à R&D - En cours

#9 Mis à jour par Emmanuel DILLARD il y a presque 3 ans

  • Echéance mis à 01/06/2021

#11 Mis à jour par Florian AZIZIAN il y a presque 3 ans

  • Assigné à Florian AZIZIAN supprimé

#12 Mis à jour par Emmanuel DILLARD il y a presque 3 ans

  • Projet changé de CURRENT SPRINT à Backlog
  • Statut changé de R&D - En cours à R&D - A planifier

#13 Mis à jour par Florian AZIZIAN il y a presque 3 ans

  • Echéance 01/06/2021 supprimé

#14 Mis à jour par Emmanuel DILLARD il y a presque 3 ans

  • Priorité changé de 1-Majeur à 2-Sérieux

#15 Mis à jour par Emmanuel DILLARD il y a presque 3 ans

  • Projet changé de Backlog à Backlog Courrier
  • Version cible changé de 20.10 (Fin de vie) à 20.10

#18 Mis à jour par Emmanuel DILLARD il y a 12 mois

  • Statut changé de R&D - A planifier à R&D - A étudier

#20 Mis à jour par Emmanuel DILLARD il y a 9 mois

  • Statut changé de R&D - A étudier à Résolu
  • Version applicable MC mis à 2301

Pas de changement notables.
Risques potentiels élevés selon GHE

Formats disponibles : Atom PDF