[PHP/mySQL]Result raakt invalid tijdens opvragen records

Pagina: 1
Acties:
  • 169 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Gonadan
  • Registratie: Februari 2004
  • Laatst online: 21:31

Gonadan

Admin Beeld & Geluid, Harde Waren
Topicstarter
PHP: 4.4.0
mySQL: 4.1.22

Ik heb een vreemd probleem wat in mijn ogen niet mogelijk zou moeten zijn.
Helaas is de praktijk anders.

Hier een versimpelde versie van de code die ik gebruik:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    $sql1 = 'query';
    $sql2 = 'query';

    $res1=$object->query($sql1);
    if(!$res1) die;
    $res2=$object->query($sql2);
    if(!$res2) die;

    $fp = @fopen("file", "w");
    if(!$fp) {
      $object->loggen("Fout");
      return 0;
    }

    while($row=mysql_fetch_assoc($res1)) {
      fputs($fp, $row['veld']);
    }
    while($row=mysql_fetch_assoc($res2)) {
      fputs($fp, $row['veld']);
    }
    fclose($fp);


code:
1
$object->query()

Doet niets meer dan controleren of de databaseverbinding nog bestaat en dan een mysql_db_query uitvoeren waar hij het resultaat van retourneert.
Ik heb al het idee om de mysql_db_query te vervangen door mysql_query omdat hij deprecated is geraakt.

Wat is nou je probleem?
Ten eerste: Het probleem doet zich zeer zelden voor er is geen pijl op te trekken wanneer het gebeurt en dus ook niet te reproduceren.

Het probleem is dat de queries uitgevoerd worden, er komt dus een result terug.
Dan wordt de while-lus van $res1 uitgevoerd. Deze doet drie iteraties en geeft dan uit het niets:
code:
1
mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource

De resultset is dus op de één of andere manier maar deels goed.
Dit gebeurt echter heel sporadisch, als je het script nogmaals uitvoert gaat het wel goed en worden ook alle (ruim 1000) records geschreven in het bestand.

Het enige wat ik kon bedenken waar het aan kan liggen is dat de recordset in het geheugen van PHP op de één of andere manier corrupt raakt na het ophalen van de mySQL server. Of dat de fputs misschien iets raars doet waardoor de recordset beschadigd raakt.

Heeft iemand een idee waar ik moet zoeken? Ik heb me rotgezocht naar bugs in PHP of mySQL maar alles wat ik vind gaat over andere problemen helaas. :)

Look for the signal in your life, not the noise.

Canon R6 | 50 f/1.8 STM | 430EX II
Sigma 85 f/1.4 Art | 100-400 Contemporary
Zeiss Distagon 21 f/2.8


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 21-09 02:21

Janoz

Moderator Devschuur®

!litemod

Ik denk dat het, voor het begrip, handig zou zijn wanneer je ook een stukje code post van $object->query. Voor wat ik zo snel van je huidige code kan zien klopt deze gewoon. Kun je ook met deze versimpelde versie het probleem reproduceren?

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Gonadan
  • Registratie: Februari 2004
  • Laatst online: 21:31

Gonadan

Admin Beeld & Geluid, Harde Waren
Topicstarter
Janoz schreef op vrijdag 26 oktober 2007 @ 12:40:
Ik denk dat het, voor het begrip, handig zou zijn wanneer je ook een stukje code post van $object->query.
Bij deze.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
   function init_db() {
      if (!($this->link=mysql_connect('server','user','pass'))) {
        print ("Database bestaat niet.");
        exit;
      }
   }

   function query($sql) {
      if (!$this->link) $this->init_db();
      $res = mysql_db_query('database' , $sql, $this->link);
      return $res;
   }
Voor wat ik zo snel van je huidige code kan zien klopt deze gewoon.
Dat is dus het rare, de code klopt ook gewoon. Hij werkt tientallen keren goed. Eigenlijk bijna altijd. Maar dan gaat hij dus één keer fout, wanneer en waarom is niet te achterhalen. Erg vervelend want zo kan ik ook niet debuggen.
Kun je ook met deze versimpelde versie het probleem reproduceren?
Dit is een versimpelde met betrekking tot variabelenamen. Ik heb alles wat hernoemd om het simpel te houden.
In de 'echte' code staat niets meer dan bovenstaande code. Alleen zijn dan de variabelen en veldnamen uiteraard correct ingevuld. :)

Look for the signal in your life, not the noise.

Canon R6 | 50 f/1.8 STM | 430EX II
Sigma 85 f/1.4 Art | 100-400 Contemporary
Zeiss Distagon 21 f/2.8


Acties:
  • 0 Henk 'm!

Verwijderd

PHP:
1
2
3
//.....
    if(!$res1) die;
//....
Persoonlijk zou ik checken op is_resource in plaats van op !$res.
Als het dan niet een resource is een lekkere melding geven.

Zelfs bij mysql_fetch_assoc($res) even eerst kijken of die $res wel een resource is (je weet maar nooit)
Dat hij middenin, na 3 records afbreekt is mij met mysql_query nog niet overkomen.

Acties:
  • 0 Henk 'm!

  • kokx
  • Registratie: Augustus 2006
  • Laatst online: 13-09 20:30

kokx

WIN

Als je een query op een bepaalde database wilt toepassen, is het gebruiken van mysql_db_query niet echt handig. Hiervoor kun je beter gewoon mysql_query gebruiken. Als je dit in combinatie met mysql_select_db gebruikt, wordt het altijd op dezelfde database uitgevoerd. Maar je kunt ook de databasenaam in de query zelf zetten. Door i.p.v. alleen de tabelnaam er in te zetten, er database.tabelnaam in de query te zetten.

Acties:
  • 0 Henk 'm!

  • LuCarD
  • Registratie: Januari 2000
  • Niet online

LuCarD

Certified BUFH

Wat voor een queries zijn het?

simpel recht toe rechtaan.

of zijn het queries waar tijdelijke tabellen bij worden gemaakt? Zijn ze op dezelfde tabel?
Hoeveel records verwacht je?
Hoeveel krijg je terug als je dat opvraagt via mysql_num_rows?

Programmer - an organism that turns coffee into software.


Acties:
  • 0 Henk 'm!

  • Gonadan
  • Registratie: Februari 2004
  • Laatst online: 21:31

Gonadan

Admin Beeld & Geluid, Harde Waren
Topicstarter
Verwijderd schreef op vrijdag 26 oktober 2007 @ 13:20:
Persoonlijk zou ik checken op is_resource in plaats van op !$res.
Als het dan niet een resource is een lekkere melding geven.

Zelfs bij mysql_fetch_assoc($res) even eerst kijken of die $res wel een resource is (je weet maar nooit)
Dat hij middenin, na 3 records afbreekt is mij met mysql_query nog niet overkomen.
code:
1
if (!$res) die;

staat gelijk aan
code:
1
mysql_query($sql) or die;

welke ook vaak door php.net wordt gebruikt, ik zou dus niet weten waarom dat niet zou werken.
Ook het feit dat je wel records kunt opvragen maakt dat ik verwacht dat het wél een resource is. Maar ik ga het wel als extra check gebruiken. Extra output kan nooit kwaad. ;)
kokx schreef op vrijdag 26 oktober 2007 @ 13:22:
Als je een query op een bepaalde database wilt toepassen, is het gebruiken van mysql_db_query niet echt handig. Hiervoor kun je beter gewoon mysql_query gebruiken. Als je dit in combinatie met mysql_select_db gebruikt, wordt het altijd op dezelfde database uitgevoerd. Maar je kunt ook de databasenaam in de query zelf zetten. Door i.p.v. alleen de tabelnaam er in te zetten, er database.tabelnaam in de query te zetten.
Klopt. Het gebruik van deze is ook nog een erfenisje van 'vroeger'. Ik ga het ombouwen naar mysql_query maar in principe doet dat natuurlijk hetzelfde.
LuCarD schreef op vrijdag 26 oktober 2007 @ 13:24:
Wat voor een queries zijn het?

simpel recht toe rechtaan.

of zijn het queries waar tijdelijke tabellen bij worden gemaakt? Zijn ze op dezelfde tabel?
Hoeveel records verwacht je?
Hoeveel krijg je terug als je dat opvraagt via mysql_num_rows?
Simpele queries inderdaad. Een select met een join tussen twee tabellen.
Geef ongeveer 1000 records (zie TS).
Vergeet niet dat de code maar heel soms fout gaat, al wordt het de laatste tijd steeds meer.

Ik heb het gevoel dat het misschien een soort timeout is. Dat het result wel gemaakt wordt maar niet volledig gevuld. Dan zou de check op $res wel goed gaan maar het fetchen na een aantal records falen.

Look for the signal in your life, not the noise.

Canon R6 | 50 f/1.8 STM | 430EX II
Sigma 85 f/1.4 Art | 100-400 Contemporary
Zeiss Distagon 21 f/2.8


Acties:
  • 0 Henk 'm!

  • Gonadan
  • Registratie: Februari 2004
  • Laatst online: 21:31

Gonadan

Admin Beeld & Geluid, Harde Waren
Topicstarter
Ik heb weer wat extra informatie maar nog geen oplossing.
Toen het probleem zich weer voordeed ben ik in de systemen gaan graven en daar kwam uit dat het proces in 'sleep' staat. Met vaak 0.1% mem en 0.0% cpu, dus veel doet hij niet.
Met netstat zag ik dat de verbinding naar de mysqlserver open bleef staan, in de mysql processlist was hij echter niet te vinden.
Na twee uur faalde de mysql_db_query pas en ging het script verder.

Daarna heb ik mysql_db_query vervangen door mysql_select_db en mysql_query en dat ging een tijdje goed.
Nu staat hij echter weer vast, de situatie lijkt hetzelfde alleen zie ik nu geen verbinding naar de mysql server open staan.

Ik begin mij onderhand af te vragen of het wel een PHP probleem is en dat er misschien niet wat anders aan de hand is.
Vreemde netwerkproblemen of iets dergelijks misschien. Iemand een idee?

Look for the signal in your life, not the noise.

Canon R6 | 50 f/1.8 STM | 430EX II
Sigma 85 f/1.4 Art | 100-400 Contemporary
Zeiss Distagon 21 f/2.8


Acties:
  • 0 Henk 'm!

  • Gonadan
  • Registratie: Februari 2004
  • Laatst online: 21:31

Gonadan

Admin Beeld & Geluid, Harde Waren
Topicstarter
Het blijkt nu dat hij wél een mysql_error geeft, alleen geeft mysql_query nog steeds geen fout.
Ik ga nu proberen de errno te onderscheppen en eventueel de binarylogs van de mysqlserver napluizen.
Op deze pagina heb ik wel een aantal mogelijk opties gevonden.
Het begint nu een uitdaging te worden. :Y)

Look for the signal in your life, not the noise.

Canon R6 | 50 f/1.8 STM | 430EX II
Sigma 85 f/1.4 Art | 100-400 Contemporary
Zeiss Distagon 21 f/2.8


Acties:
  • 0 Henk 'm!

  • ToMaSZ
  • Registratie: Januari 2000
  • Laatst online: 22:13
Gonadan schreef op dinsdag 13 november 2007 @ 09:26:
Het blijkt nu dat hij wél een mysql_error geeft, alleen geeft mysql_query nog steeds geen fout.
Ik ga nu proberen de errno te onderscheppen en eventueel de binarylogs van de mysqlserver napluizen.
Op deze pagina heb ik wel een aantal mogelijk opties gevonden.
Het begint nu een uitdaging te worden. :Y)
Even helemaal gerelateerd op je link, minder op je vraag: ik kreeg de briljante 'mysql has gone away' error bij het wegschrijven van grote hoeveelheden binary data. Had in My.ini de max_allowed_packet al op 32M gezet, maar hij klapte er vaak (niet altijd) al eerder uit dan bij 32M... Als 'ie er dan uitvloog volgde ook af en toe geen melding. Heel onvoorspelbaar gedrag...
Ik heb dat toen heel smerig omzeild met een max_allowed_acket waarde van 100M, omdat het ging om lokale 1-user omgevinkjes die enkel vanaf de localhost benaderbaar waren. (usb stick servertje)

What the eyes see, and the ears hear, the mind believes...


Acties:
  • 0 Henk 'm!

  • Gonadan
  • Registratie: Februari 2004
  • Laatst online: 21:31

Gonadan

Admin Beeld & Geluid, Harde Waren
Topicstarter
Weer wat gevonden, hij geeft de 2013 error.
Daar heb ik op gezocht en dit lijkt te gebeuren als de server de verbinding verbreekt vanwege een probleem met de verbinding maar dat de client dat niet te horen krijgt.
Dan blijft hij wachten tot TCP een timeout geeft.

Nu eens kijken waarom dit gebeurt. :)

Look for the signal in your life, not the noise.

Canon R6 | 50 f/1.8 STM | 430EX II
Sigma 85 f/1.4 Art | 100-400 Contemporary
Zeiss Distagon 21 f/2.8

Pagina: 1