arnal69130
Messages postés445Date d'inscriptionlundi 17 février 2003StatutMembreDernière intervention22 mars 2007
-
5 oct. 2005 à 17:54
RobertDeNiroZ -
9 sept. 2010 à 15:18
Bonjour à tous,
Je développe un site en php d'une dizaine de pages. Il tourne sous Apache2+php5 sur w2k. La plupart du temps tout fonctionne bien, mais de temps en temps, en ajoutant certaines instructions php (qui semblent vraiment anodines), Apache plante en affichant une fenêtre
Application popup : Apache.exe - Erreur d'application : L'instruction à "0x00837ca8" emploie l'adresse mémoire "0x05f71000". La mémoire ne peut pas être "read".
Cliquez sur OK pour terminer le programme.
Pas très explicite ! pas d'erreur php...
Alors je triture le code php pour ne pas utiliser telle ou telle syntaxe, et j'arrive à contourner comme ça le problème. Mais dès que j'implémente une nouvelle fonctionnalité, je retombe là-dessus.
Par exemple, tout fonctionnait bien, et j'ai ajouté ceci :
« while($ligneResultat=odbc_fetch_array($res)) { echo 'test'; }»
et maintenant ça plante ! pourtant le résultat est valide.
Dans le log d'erreur d'apache, il y a la ligne :
FATAL: emalloc(): Unable to allocate 892350769 bytes
J_G
Messages postés1406Date d'inscriptionmercredi 17 août 2005StatutMembreDernière intervention28 août 200710 6 oct. 2005 à 15:32
Salut,
Dis moi ... T'es dans un plan galère là !?!
Voyon voâr !
<hr size="2" width="100%">memory_limit = 8M ; Maximum amount of memory a script may consume (8MB)
+
le processus Apache ne prend jamais plus de 7 ou 8 Mo
=
Le php.ini sert bien à quelque chose. C'est pas apache qui demande 2 Go de RAM
ET
Ca pourrait être la raison de l'erreur, "Apache :Allouer 2 Go !!! T'es pas dingue... Moi j'me casse!"
Donc il n'y a pas d'erreur dans ton script... (ce qui n'arrange pas l'affaire)
<hr size="2" width="100%">J'aurai une piste de réflexion : l'erreur provient de ta requète... Donc du code SQL, c'est là que serait la "boucle infinie".
Je m'explique :
Ta base de données, et en particulier son analyseur de SQL, est un
process indépendant d'Apache. Donc qui ce fout roal de php.ini.
Si tu fais une requète de taré genre
SELECT *
FROM tablePouet as t1, tablePouet as t2
WHERE t1.id != t2.id
La tu auras tout les croisements possible des champs de la table. Soit
une table de taillle !N si tablePouet contient N champs. Truc ouf koi
!!!
Tu me vois venir ?
Bon... ODBC il s'en fout lui... Il n'a pas de limite d'allocation
configurée (si ce n'est la limite autorisée par windows). Donc il en
pose un peu partout... Bref il s'arrange et on s'en fout de comment.
Mais il renvoit un lien vers le resultat. "Voici votre numéro de compte
client à rapeller lors de toutee communication ;)"
Mais quand tu demande à Apache de récupérer les données pour les
parser, ligne par ligne. Il demande à ODBC "fille moi le paquet et je
m'arrange avec". ODBC répond : "pas de problème ça fait 2Go". La suite
tu la connais.
Voilà pourquoi ça plante quand tu fait odbc_fetch_array()
FhX
Messages postés2350Date d'inscriptionmercredi 13 octobre 2004StatutMembreDernière intervention18 avril 20153 6 oct. 2005 à 20:48
J'ai trouvé ca sur Google :
"
I have got a "solution" by finding many newsgroups and websites !! And
now I want to share with everyone who has encounter this problem.
If you have created a table in SQLServer has a data type "ntext" then
this problem (Fatal: emalloc() : unable to ....) will occur, please do
not use this data type.
malalam
Messages postés10839Date d'inscriptionlundi 24 février 2003StatutMembreDernière intervention 2 mars 201025 7 oct. 2005 à 10:01
Ahhh...SQLServer...puisque vous vous dites sur quoi vous bossez...moi
en ce moment, c'est le développement d'un SAE (système d'aide à
l'exploitation) sur les réseaux de transport, avec SQLServer, XMLRAD
2005 et Delphi (je suis sur la partie DB et DBGUI -gui => d'où
XMLRAD et delphi... ).
Ben je préfère mysql lol. Même en v3.x...les sous requêtes c'est bien, mais c'est lent, et c'est pas toujours super clair.
En tous cas, FhX t'as en effet peut-être donné une bonne piste :
vérifie tes types de champs...et ne mets que des "standards" SQL Ansi,
si possible.
Vous n’avez pas trouvé la réponse que vous recherchez ?
arnal69130
Messages postés445Date d'inscriptionlundi 17 février 2003StatutMembreDernière intervention22 mars 20072 6 oct. 2005 à 10:08
Merci à tous pour vos idées.
Je vais vérifier toutes mes boucles, et optimiser mon code selon les suggestions de J_G. C'est vrai que j'utilise très souvent foreach(), je ne savais pas qu'il fallait éviter...
Ce qui m'étonne, c'est que si j'avais fait une boucle infine, il devrait normalement y avoir une erreur php de max_execution_time, non ? Voici ma config à ce sujet (dans php.ini, c'est celle par défaut !)
;;;;;;;;;;;;;;;;;;;
; Resource Limits ;
;;;;;;;;;;;;;;;;;;;
max_execution_time = 30 ; Maximum execution time of each script, in seconds
max_input_time = 60 ; Maximum amount of time each script may spend parsing request data
memory_limit = 8M ; Maximum amount of memory a script may consume (8MB)
A croire qu'Apache n'en tient pas compte ?
En tout cas, c'est clair une telle demande de mémoire n'est pas acceptable par la machine, et encore, je suis en mode test et je suis le seul visiteur ! Ce qui est bizarre c'est que dans le gestionnaire de processus de Windows, le processus Apache ne prend jamais plus de 7 ou 8 Mo...
Sinon, j'utilise les sessions, alors j'avais pensé que je mémorisais trop de chose dans mes sessions, mais les fichiers créés dans le répertoire temporaires ne dépassent pas les 170 Ko !
J'ai aussi essayé en revenant à Apache 1, même problème.
Je ne pense pas avoir de virus, j'ai un AV à jour (SophosAV) et je teste toute la machine tous les jours...
FhX, j'utilise une connexion odbc et pas mysql, alors la fonction est odbc_fetch_array()... les arguments ne sont pas les mêmes que mysql_fetch_array(). Merci qd même.
J_G, odbc_fetch_assoc() ça n'existe pas ;o)
En fait, même si j'utilise odbc_fetch_object() ça plante...
arnal69130
Messages postés445Date d'inscriptionlundi 17 février 2003StatutMembreDernière intervention22 mars 20072 6 oct. 2005 à 10:41
Le plus pénible pour trouver la source de l'erreur, c'est que
- si j'enlève le bout de code en question, ça marche
- si je le mets avec tout le reste du code, ça plante
- mais si je ne mets que ce bout de code (plus la connexion à la base), ça ne plante pas !
Voici un peu plus de code, si jamais ça vous inspire :
$_SESSION['connexion']=odbc_connect("blablabla","","") or die("Erreur de connexion".odbc_errormsg());
$req="SELECT blablabla FROM blablabla WHERE blablabla ";
$res=odbc_exec($_SESSION['connexion'],$req);
if (!empty($res)) {
$nbChamps=odbc_num_fields($res);
echo '
---
';
while(odbc_fetch_row($res)) {
for ($i=1; $i<=$nbChamps; $i++)
echo odbc_field_name($res,$i).'='.odbc_result($res,$i).'
';
}
odbc_free_result($res);
}
exit;
et toujours les mêmes logs pour Apache (mais la mémoire requise a augmenté !) :
[Thu Oct 06 10:38:12 2005] [notice] Parent: child process exited with status 3221225477 -- Restarting.
[Thu Oct 06 10:38:13 2005] [notice] Apache/2.0.54 (Win32) PHP/5.0.5 configured -- resuming normal operations
[Thu Oct 06 10:38:13 2005] [notice] Server built: Apr 16 2005 14:25:31
[Thu Oct 06 10:38:13 2005] [notice] Parent: Created child process 872
[Thu Oct 06 10:38:14 2005] [notice] Child 872: Child process is running
[Thu Oct 06 10:38:14 2005] [notice] Child 872: Acquired the start mutex.
[Thu Oct 06 10:38:14 2005] [notice] Child 872: Starting 250 worker threads.
FATAL: emalloc(): Unable to allocate 1920220171 bytes
[Thu Oct 06 10:38:18 2005] [notice] Parent: child process exited with status 3221225477 -- Restarting.
...
malalam
Messages postés10839Date d'inscriptionlundi 24 février 2003StatutMembreDernière intervention 2 mars 201025 6 oct. 2005 à 14:08
De toutes évidences, il y a un truc qui bouffe BCP de ram, là... 1920220171 bytes, ça fait très très beaucoup...
Et si ça ne venait pas de ton script, mais de ton système ? Il y a
peut-être une tâche un peu bizarre qui tourne, et qui peut-être
interfère avec apache.
arnal69130
Messages postés445Date d'inscriptionlundi 17 février 2003StatutMembreDernière intervention22 mars 20072 6 oct. 2005 à 16:20
Alors là J_G, super ! ton explication est très claire et je suis vraiment content de pouvoir envisager une issue à ce problème. Honnêtement, je ne voyais pas bien vers où chercher, mais ton raisonnement est très logique.
J'utilise une base HyperFile, c'est la base de données livrée avec Windev, je n'ai pas le choix ! Et c'est vrai que j'ai déjà constaté plusieurs fois que c'est pas l'idéal comme système, car c'est une base dite "fichier", pas un sgbd ! Enfin bon, il faut que je fasse avec, alors je vais reprendre toutes mes grosses requêtes.
Cela dit, la requête en question ne retourne pas plus de 20-30 lignes et 22 colonnes.... Enfin en tout cas, je cherche dans cette direction.
Merci.
Malam, merci pour la suggestion. J'ai essayé en n'ayant que apache, iexplore et les trucs windows qui tournaient, mais ça plantait pareil...
J_G
Messages postés1406Date d'inscriptionmercredi 17 août 2005StatutMembreDernière intervention28 août 200710 6 oct. 2005 à 17:15
Hmmm...
Mauvaise nouvelles des étoiles !
"Cela dit, la requête en question ne retourne pas plus de 20-30 lignes et 22 colonnes"
Ca sent pas bon ça !!! J'ai peur de te faire bidouliler dans la mauvaise direction...
Cela dit: j'ai eu cette piste de réflexion car tu utilises ODBC ! Et
effectivement, les bases à wouinnedauze ne fonctionnent pas avec un
serveur résident, mais une API lancée à chaque fois que tu dois accéder
au fichier de la base.
La commande de lancemement de cette API dois certainement être
configurée dans le php.ini, ou faire partie des extentions php.
Peut-être un coup d'oeil dans ce coin te sauvera ta journée... (Là, je
parle sans regarder dans la doc)
Si tu y flaire un "bottle-neck", il existe des serveurs qui savent
accéder au bases type ADO et ODBC (peut-être même que IIS le fait !
Après, de là à demander à Apache et IIS de faire copain-copain... c'est
pas gagné !). Configure ton Apache pour faire des appels à ce serveur
plutôt que de lancer une API distincte!
Bonne chance, dis-moi si tu y arrive !
PS : Toutes les bases de données utilisent des fichiers !!! Ben oui, on
à rien inventé d'autre pour stocker des données sur un ordi quand y'a
plus de courant électrique ;)
PPS : Ne dis pas de mal de Windows sur ce forum !!! Où le modérateur-fou frappera encore ;)
Description
bool odbc_setoption ( resource id, int function, int option, int param )
odbc_setoption() donne accès aux options
ODBC pour une connexion particulière ou un résultat de
requête. Elle a été écrite pour aider à
la résolution de problèmes liés aux pilotes ODBC
récalcitrants. Vous aurez sûrement à utiliser
odbc_setoption() si vous êtes un programmeur
ODBC et que vous comprenez les divers effets des options disponibles.
Vous aurez aussi besoin d'un bon manuel de référence pour
comprendre les options et leur usage. Différentes versions de
pilotes supportent différentes versions d'options.
Etant donné que les effets peuvent varier d'un pilote à
l'autre, l'utilisation de odbc_setoption() dans
des scripts voués à être livrés au public
est très fortement déconseillée. De plus, certaines
options ODBC ne sont pas disponibles car elles doivent être
fixées avant l'établissement de la connexion. Cependant,
si dans un cas bien spécifique, odbc_setoption() vous permet d'utiliser PHP sans que votre patron ne vous pousse à
utiliser un produit commercial, alors cela n'a pas d'importance.
<var>id</var> est un identifiant de connexion, ou un identifiant
de résultat, pour lequel vous souhaitez modifier des options.
Pour SQLSetConnectOption(), c'est un identifiant de connexion.
Pour SQLSetStmtOption(), c'est un identifiant de résultat.
<var>function</var> est la fonction ODBC à utiliser.
La valeur doit être de 1 pour utiliser SQLSetConnectOption() et 2
pour SQLSetStmtOption().
Le paramètre <var>option</var> est l'option à
modifier.
Le paramètre <var>param</var> est la valeur de l'option
<var>option</var>.
Exemple 1. Exemple de modification d'option ODBC
<?php
// 1. L'option 102 de SQLSetConnectOption() est SQL_AUTOCOMMIT.
// 1 de SQL_AUTOCOMMIT est SQL_AUTOCOMMIT_ON.
// Cet exemple a le même effet que
// odbc_autocommit($conn, true);
odbc_setoption($conn, 1, 102, 1);
// 2. Option 0 de SQLSetStmtOption() est SQL_QUERY_TIMEOUT.
// Cet exemple fixe le délai d'expiration à 30 secondes.
$result = odbc_prepare($conn, $sql);
odbc_setoption($result, 2, 0, 30);
odbc_execute($result);
?>
arnal69130
Messages postés445Date d'inscriptionlundi 17 février 2003StatutMembreDernière intervention22 mars 20072 6 oct. 2005 à 17:35
En fait j'ai rien contre Windows, je parle de Windev ! et encore, j'ai rien contre Windev non plus, c'est juste contre leur base de données, Hyperfile. Ce n'est pas un "programme" ou un "service" attendant des requêtes SQL, ce sont juste des fichiers textes (en gros). Enfin de toute façon, comme je le disais plus haut, je n'ai pas le choix, alors ça sert à rien de me plaindre, ça ne fera pas avancer le problème ;o)
arnal69130
Messages postés445Date d'inscriptionlundi 17 février 2003StatutMembreDernière intervention22 mars 20072 6 oct. 2005 à 17:38
[HS]
Le format de fichiers HyperFile est proprietaire et non ouvert. Il a les inconvenients suivants...
1- Format non reconnu par tous les autres logiciels
2- Probleme de fragmentation et d'incoherence d'index
3- Obligation de reindexation frequente (lie au pb 2)
4- Probleme d'utilisation en reseau avec bcp d'utilisateurs (lie au pb 2)
5- Pas un vrai SGBD
6- ODBC non conforme
http://membres.lycos.fr/windev/souh064.htm
J_G
Messages postés1406Date d'inscriptionmercredi 17 août 2005StatutMembreDernière intervention28 août 200710 6 oct. 2005 à 18:20
Pour quelle entreprise ?
(Si ce n'est pas indiscret)
Moi je bosse avec une version 3.23 de MySQL
C-à-d. : PAS DE SOUS-REQUETES !!!!!!! C'est infernal :( :( :( :(
Alors ton ODBC mis-à-jour me ferait presque réver ;)
<maVie>
Ou alors je n'ai pas trouvé la bonne syntaxe pour MySQL 3.23.
Mais je ne trouve pas non-plus de doc pour cette version et la doc de
la version 5 te dit : "vas-y à la Jack ! Sous-requètes, imbriquées dans
le désordre... C'est bon c'est bon, si tu as mieux que la version 4.1"