IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

mon script est stoppé


Sujet :

Langage PHP

  1. #1
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 828
    Points
    5 828
    Billets dans le blog
    1
    Par défaut mon script est stoppé
    Bonjour,

    mon script s'est arrêté et je ne vois pas pour quelle raison.
    Pas de message d'erreur.
    En gros, il s'agit de lire un fichier CSV et à chaque ligne lue, faire un traitement. Pour suivre l'évolution, j'affiche le numéro de la ligne lue :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $nb_line = 0;
    while (($line_csv = fgetcsv(CSVParser::getHandle(), $buffer, CSVParser::getSeparator(),
                    CSVParser::getEnclosure(),"")) !== false) {
                   $nb_line++;  echo "csvimportcontroller 106 nbline=".$nb_line."<br/>";
                   ...
    Il a lu 7652 lignes mais le fichier en contient 110751. Comment puis-je trouver la cause de ce blocage ?

  2. #2
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 200
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 200
    Points : 8 425
    Points
    8 425
    Billets dans le blog
    17
    Par défaut
    Regarde si les lignes du CSV à partir de la 7651e sont bien formées

    Rien d'autre dans ta boucle qui pourrait arrêter le parcours du CSV ?

  3. #3
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 828
    Points
    5 828
    Billets dans le blog
    1
    Par défaut
    Après examen du CSV, les lignes suivantes semblent correctes.

    Pour chaque ligne lue, le traitement est d'abord une analyse de la ligne, et si correcte, écriture en bdd. Afin de savoir où se trouve le blocage, j'ai commenté l'écriture en bdd et en quelques minutes, il a déjà atteint la ligne, il a parcouru tout le fichier CSV. Je vais continuer à chercher ainsi. OK ?

  4. #4
    Membre expert
    Avatar de cavo789
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2004
    Messages
    1 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 785
    Points : 3 048
    Points
    3 048
    Par défaut
    Citation Envoyé par laurentSc Voir le message
    j'ai commenté l'écriture en bdd et en quelques minutes, il a déjà atteint la ligne, il a parcouru tout le fichier CSV. Je vais continuer à chercher ainsi. OK ?
    Du coup, si je comprends bien, ton script va faire plus de 110.000 INSERT en base de données. A mon avis ton souci est donc un goulot d'étranglement au niveau de ton système de base de données. Faudrait voir avec un dba (database admin) s'il peut identifier un quelconque blocage à ce niveau.

    Note aussi, quand tu fais ton insert; valides-tu que cela a fonctionné ? Est-ce que tu as p.ex. un try catch pour garantir que l'insertion a fonctionnée ?

  5. #5
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 200
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 200
    Points : 8 425
    Points
    8 425
    Billets dans le blog
    17
    Par défaut
    Je vais continuer à chercher ainsi. OK ?
    Tu sais que la requête vers ta base provoque un plantage.
    Maintenant, pour en connaitre la cause, il suffit d'afficher l'erreur, avec PDO::errorInfo() par exemple.

  6. #6
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 828
    Points
    5 828
    Billets dans le blog
    1
    Par défaut
    Ta remarque (Cavo789) m'a débloqué. Il y avait bien des try/catch mais avant de te répondre, j'ai regardé en détail, et si je démarrais bien une transaction, je faisais jamais de commit !

    Maintenant, le code pour traiter une ligne est le suivant :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
     
                        self::createLicensesObjects();
     
                        $this->errors = Record::analyze_license($this->refTableLicense);
     
                        //on effectue les analyses. Si une
                        // erreur est détectée, on renseigne la chaîne des erreurs ($this->errors)
                        if (Record::getLastError() == "no error")
                        {
                            try
                            {
                                $this->refPPP = CSVImport::startPPP();  //connexion
                                CSVImport::startTransaction();
                                CSVImport::putInDBLicense($this->refTableLicense,
                                    $this->refPPP);
                                CSVImport::commit();
                            }
                            catch (\Exception $e) {
                            }
                        }

    J'ai relancé. Bon, mon code n'étant pas du tout optimisé, il n'a traité en quelques minutes que 72000 lignes, mais c'est déjà pas mal. J'attends la fin avant de passer en

    Au fait, ne serait-il pas utile de faire après chaque itération de la boucle un closeCursor ?

  7. #7
    Membre expert
    Avatar de cavo789
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2004
    Messages
    1 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 785
    Points : 3 048
    Points
    3 048
    Par défaut
    Pour être sûr : tu lances combien de startTransaction ? Une seule fois, en dehors de la boucle ou dans la boucle et donc 110.000 fois ?

    (la bonne approche est de ne le faire qu'une fois, soit tout passe correctement soit rien du tout)

  8. #8
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 828
    Points
    5 828
    Billets dans le blog
    1
    Par défaut
    Je prendrai en compte ta remarque demain.

    En fait, à l'heure actuelle, je démarre 110000 fois une transaction . J'ai voulu modifier cela mais y avait plus aucune écriture en bdd. J'ai réussi à revenir en arrière et je ferai ça proprement demain.

  9. #9
    Membre expert
    Avatar de cavo789
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2004
    Messages
    1 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 785
    Points : 3 048
    Points
    3 048
    Par défaut
    L'objectif d'une transaction est de protéger la base de données d'un état instable et donc de conserver son intégrité.

    Démarrer 110.000 transactions est quelque chose de coûteux en ressources et, je le suppose, lorsque tu n'auras plus qu'une seule transaction (avant la boucle), je pense que ton script s'exécutera bien plus vite. Toutefois, d'expérience, je sais que les serveurs de bases de données commencent à être étranglé lorsqu'ils reçoivent des requêtes à n'en plus finir. Les premières s'exécuteront très vite puis, comme sur une autoroute, tu auras un embouteillage et il y aura un goulot d'étranglement à un moment donné. Ton script sera donc plus rapide avec une seule transaction mais tant que tu feras des INSERT à la queue-leu-leu, il ne faut pas s'attendre à une vitesse éclair.

  10. #10
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 828
    Points
    5 828
    Billets dans le blog
    1
    Par défaut
    si je commente l'écriture en bdd, le fichier CSV avec ses 110000 lignes est lu et traité (donc juste analyse des erreurs pour chaque ligne) en quelques minutes. Par contre, là, je viens de remettre l'accès en bdd (donc environ 110000 INSERT ou UPDATE) et ai relancé le script (y a environ 4h30) et il n'a lu et traité que 3900 lignes... A ce rythme, d'après mon calcul, y en a pour 5 jours...(4h30->270 minutes et 270*110000/3900=7615 minutes, soit 126 heures, soit 5,2 jours)

    J'ai d'abord testé le script sur un fichier CSV léger (63 lignes), donc il est correct. Mon script est le suivant :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    try
    {
            $this->refPPP = CSVImport::startPPP();  //connexion
            CSVImport::startTransaction(); //on lance la transaction avant la boucle
     
            $buffer= 4096;
            while (($line_csv = fgetcsv(CSVParser::getHandle(), $buffer, CSVParser::getSeparator(),
                    CSVParser::getEnclosure(),"")) !== false) {
                    ...
                    switch (CSVParser::getCSVType())
                    {
     
                    case "license":
     
                        // analyses
     
                        self::createLicensesObjects();
     
                        $this->errors = Record::analyze_license($this->refTableLicense);
     
                        //on effectue les analyses. Si une
                        // erreur est détectée, on renseigne la chaîne des erreurs ($this->errors)
                        if (Record::getLastError() == "no error")
                        {
                            CSVImport::putInDBLicense($this->refTableLicense,
                                $this->refPPP);
                        }
     
                       break;
                       ...
                    } // fin du switch
     
           } //fin de la boucle
     
           CSVImport::commit(); //on fait le commit en fin de boucle
    } // fin du try
    catch (\Exception $e) {
    }
    Je me savais pas si mauvais en codage...

  11. #11
    Membre expert
    Avatar de cavo789
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2004
    Messages
    1 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 785
    Points : 3 048
    Points
    3 048
    Par défaut
    Donc comme je l'ai déjà dit deux fois plus haut, ta base de données souffre d'un embouteillage. Elle est pépère et puis tu lui envoies; paf! prends ça dans la tronche, des milliers d'instructions.

    Tu t'es rapproché d'un administrateur pour qu'il te guide dans une meilleure approche ?

    (c'est quoi comme SGBD ?)

  12. #12
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 470
    Points : 5 828
    Points
    5 828
    Billets dans le blog
    1
    Par défaut
    Mon problème d'optimisation n'ayant plus rien à voir avec un blocage, je clos cette discussion et en démarre une nouvelle avec un titre plus approprié.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Mon script est-il juste ?
    Par DienF dans le forum Shell et commandes GNU
    Réponses: 3
    Dernier message: 27/04/2020, 17h36
  2. [MCD] Mon script est-il correct ?
    Par batchi dans le forum Schéma
    Réponses: 1
    Dernier message: 16/02/2011, 15h50
  3. Mon script est-il correcte ?
    Par neufrdb dans le forum Débuter avec Java
    Réponses: 6
    Dernier message: 01/02/2011, 11h13
  4. Mon script est "mal formé" & recherche de script
    Par Msieurduss dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 07/09/2010, 18h58
  5. Réponses: 3
    Dernier message: 23/02/2006, 08h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo