DevProTalk

DevProTalk (http://www.devprotalk.com/index.php)
-   SQL baze podataka - Sponzor: Baze-Podataka.net (http://www.devprotalk.com/forumdisplay.php?f=10)
-   -   gremlini na serveru (http://www.devprotalk.com/showthread.php?t=972)

ivanhoe 05. 05. 2006. 04:25

gremlini na serveru
 
Odrzavam jedan server koji je postao prilicno popularan u poslednje vreme i zbog toga na momente vrlo (pre)opterecen, i verovatno zbog toga, krenule su da mi se desavaju neke jako cudne stvari.

PHP kôd:

$sql "SELECT * FROM members WHERE (email='$email' OR username='$email')";
    
$db->query($sql);
    if(
$db->next_record()) {
        
$processed $db->f("processed");
        
$member_id $db->f("id");
    }
    
    if (
$processed=='y') { 
        
$error USER_EXISTS;
    } else {
        
        if(
$member_id) {// just update existing record
            
$sql "UPDATE members SET first_name='$first_name', last_name='$last_name', pword='$password', source=".HUB_SOURCE_ID." WHERE id='$member_id'";
            
$db->query ($sql);
            
$last_id $member_id;
            
        }else {
// insert a new one
            
$sql "INSERT INTO members (email, first_name, last_name, pword, active, processed, source, first_contact)  VALUES ('$email', '$first_name', '$last_name', '$password', 'n', 'n', ".HUB_SOURCE_ID.", NOW())";
            
$db->query ($sql);
            
$sql "SELECT * FROM members WHERE email='$email' AND pword='$password'";
            
$db->query ($sql);
            
$db->next_record();
            
$last_id $db->f('id');
        } 

Ovaj komad koda koji sluzi da kreira usera i onda se dalje korisnik salje na paypal. Bitna stvar ovde je $last_id, tj. id pod kojim je user upisan u bazu, jer se to koristi da se kad uplata prodje aktivira taj nalog. I ovo je sve normalno radilo godinama, ali kad se mysql server (i ceo server) nadje pod opterecenjem, pocelo je da se desava da se paypalu prosledi pogresna vrednost za $last_id...

Proveravao sam u bazi i postoji samo jedan user record sa tim emailom, ali poslednji upit na neku foru vrati pogresan ID ??? Jel ima neko ideju kako je to moguce da se desi???

Ovaj $db objekat je iz phplib, i da je bilo neke mysql greske desio bi se die() odmah, tako je namesteno. Znaci nije bilo greske, ali je vracen pogresan podatak (npr. 487522 umesto 487556, pri cemu record sa ID=487522 ima skroz drugaciji email i pass znaci nikako nije smeo da se nadje u rezultatu)

Da li postoji neki nacin da se zastitim od ovakvih stvari? Uradicu uskoro load-balancing, cim klijenta ubedim da da kintu za dodatni server, ali ipak bih voleo i da ovo predupredim za ubuduce, ako je moguce..

Gruja 05. 05. 2006. 09:44

Verovatno ovo nema veze sa mozgom posto nemam pojma sa php-om:

Kakva vrsta promenljive je taj $db? Ako je to neka deljena globalna promenljiva koju dele sve strane onda moze da ti se desi da je jedna stranica poslala upit, a druga da cita rezultate.

ivanhoe 05. 05. 2006. 17:03

ne, nema toga kod php-a..
$db je lokalni objekat koji kreira phplib, pre ovoga nema drugih upita u skripti, i ne koriste se perzistentne konekcije, tako da nikako ne bi smelo da dodje do "mesanja" podataka, AFAIK...

misk0 27. 07. 2006. 20:12

I sta si uradio sa ovim Ivane?

ivanhoe 27. 07. 2006. 20:48

nesto se bilo zeznulo interno u apache-u, pojavljivale su se jos neke chudne stvari u log fajlovima....rebildovao sam apache i php, i onda je sve magicno proradilo... kazem vam ja gremlini..:D

zextra 28. 07. 2006. 03:50

kontam da si to vec izmenio, ali ako nisi, zameni tu proceduru za trazenje poslednjeg id-a funkcijom mysql_insert_id().

ivanhoe 29. 07. 2006. 02:22

da u pravu si, nisam ni primetio.... nije ovo moj kod, pisan je jos za php3, verovatno zato ni nema te mysql fore...

Dušan Dželebdžić 29. 07. 2006. 10:52

U MySQL-u (3.23 pa na dalje) postoji jako korisna funkcija LAST_INSERT_ID(), nezavisna od implementacije mysqla u nekom programskom jeziku.

godza 29. 07. 2006. 13:19

jel moguce da imas dve niti procesa koji pokusavaju da insertuju 2 korisnika paralelno?

MorenoArdohain 29. 07. 2006. 14:20

Godza, bas bih voleo da znam kako je to izvodljivo u PHP? :)

Inace, mysql_insert_id() bi trebalo da radi bez problema ako se ne koriste persistant konekcije..

dinke 29. 07. 2006. 16:21

Citat:

Originalno napisao MorenoArdohain
Godza, bas bih voleo da znam kako je to izvodljivo u PHP? :)

man pcntl :)

MorenoArdohain 29. 07. 2006. 18:05

Dinke: da li svaki proces nasledjuje sve iz parent procesa? Konkretno ciljam na mysql konekciju. Ja mislim da ne, zbog toga nije ni moguce paralelno insertovanje u okviru jedne konekcije.

Neka me neko ispravi ako gresim., ipak je moje znanje o procesima iz Perla :)

ivanhoe 29. 07. 2006. 19:04

kad se forkuje u perlu nasledjuju se i FD, tako da bi trebalo i konekcije da se naslede... ali mislim da su takve stvari opasne da se rade, cisto sumnjam da je mysql konekcija thread-safe, ko zna sta bi se desilo kad bi krenuo paraleno da pises iz vise procesa u istu konekciju...

Uzgred mislim da je Godza mislio na situaciju kad dva korisnika istovremeno pokrenu dve skripte (odvojene procese) koji su konkurentni, a ne da jedna skripta kreira 2 procesa... a to nije problem, eventualno treba odradti lockovanje ako se proveravaju neki uslovi pre akcije (tipa da li postoji neki record, mora prvo da se lokuje, proveri, pa doda novi record, inace bi moglo da se desi da se paralelno urade 2 provere, obe ne nadju nista i onda obe dodaju record... imao sam taj problem sa PayPalom posto on posalje ponekad u periodu od par sekundi po 5-6 IPN notifikacija za istu transakciju... imao sam stalno dupikate u bazi zbog toga, dok nisam shvatio sta se desava...)

MorenoArdohain 29. 07. 2006. 19:34

Nope, mysql konekcije se ne nasledjuju u perlu

godza 29. 07. 2006. 19:50

Citat:

Originalno napisao ivanhoe
kad se forkuje u perlu nasledjuju se i FD, tako da bi trebalo i konekcije da se naslede... ali mislim da su takve stvari opasne da se rade, cisto sumnjam da je mysql konekcija thread-safe, ko zna sta bi se desilo kad bi krenuo paraleno da pises iz vise procesa u istu konekciju...

Uzgred mislim da je Godza mislio na situaciju kad dva korisnika istovremeno pokrenu dve skripte (odvojene procese) koji su konkurentni, a ne da jedna skripta kreira 2 procesa... a to nije problem, eventualno treba odradti lockovanje ako se proveravaju neki uslovi pre akcije (tipa da li postoji neki record, mora prvo da se lokuje, proveri, pa doda novi record, inace bi moglo da se desi da se paralelno urade 2 provere, obe ne nadju nista i onda obe dodaju record... imao sam taj problem sa PayPalom posto on posalje ponekad u periodu od par sekundi po 5-6 IPN notifikacija za istu transakciju... imao sam stalno dupikate u bazi zbog toga, dok nisam shvatio sta se desava...)

Da mislio sam na 2 apache thread-a (srpski receno 2 lika insertuju korisnika u isto vreme)


Vreme je GMT +2. Trenutno vreme je 17:51.

Powered by vBulletin® Verzija 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Copyright © DevProTalk. All Rights Reserved.

Mišljenja, saveti, izjave, ponude ili druge informacije ili sadržaji nastali na Sajtu su vlasništvo onoga ko ih je kreirao, a ne DevProTalk.com, tako da ne morate da se oslanjate na njih.
Autori poruka su jedini odgovorni za ovakve sadržaje. DevProTalk.com ne garantuje tačnost, kompletnost ili upotrebnu vrednost informacija, stavova, saveta ili datih izjava. Ne postoje uslovi pod kojima bi mi bili odgovorni za štetu ili gubitak koji je posledica bilo čijeg oslanjanja na nepouzdane informacije, ili bilo kakve informacije nastale kroz komunikaciju između registrovanih članova.
Web sajt može sadržavati linkove na druge web sajtove na Internetu ili neke druge sadržaje. Ne kontrolišemo niti podržavamo te druge web sajtove, niti smo pregledali bilo kakve sadržaje na takvim sajtovima. Mi nećemo biti odgovorni za legalnost, tačnost ili prikladnost bilo kog sadržaja, oglasa, proizvoda, usluga ili informacije lociranim na ili distribuiranih kroz druge web sajtove, niti za bilo kakvu štetu nastalu kao posledica takvih informacija. DevProTalk.com drži i čuva druga prava vlasništva na web sajtu. Web sajt sadrže materijale zaštićene copyright-om, zaštitne znakove i druge informacije o pravu vlasništva ili softver. Članovi mogu poslatu informacije zaštićene pravima vlasništva njihovih nosilaca i ona ostaju zaštićena bez obzira da li su oni koji prenose te informacije to naveli ili ne. Osim informacija koje su u javnom vlasništvu ili za koje dobijete dozvolu, nemate pravo da kopirate, modifikujete ili na bilo koji način menjate, objavljujete, prenosite, distribuirate, izvršavate, prikazujete ili prodajte bilo koju informaciju zaštićenu pravima vlasništva. Slanjem informacija ili sadržaja na bilo koji deo DevProTalk.com, Vi automatski dozvoljavate i predstavljate garanciju da imate pravo da dozvolite DevProTalk.com ili članovima DevProTalk.com bespovratnu, kontinualnu, neograničenu, globalnu dozvolu da koriste, kopiraju, izvršavaju, prikazuju i distribuiraju takve informacije i sadržaje i da iz takvih sadžaja koriste bilo koji deo u bilo koje svrhe, kao i pravo i dozvolu da koriste gore navedene sadržaje. Svi zaštitni znakovi (trademarks), logotipi, oznake usluga, firme ili imena proizvoda koji se pominju na ovom web sajtu su vlasništvo kojim raspolažu njihovi vlasnici.