PHP a MYSQL ako udrzat spojenie

Programovacie jazyky, rady, poradňa...
Mek
Addict
Addict
Používateľov profilový obrázok
Príspevky: 4661
Registrovaný: 23 mar 2005, 23:00
Bydlisko: ZA <-> TN
Kontaktovať používateľa:

PHP a MYSQL ako udrzat spojenie

Príspevok od používateľa Mek »

Caute,
mam tu taky specificky problem, na ktory sa mi akosi nedari vygooglit riesenie.
Mam PHP skript, ktory bezi na serveri v prikazovom riadku (teda nie cez prehliadac), otvori na zaciatku spojenie k MySQL a obsluhuje svojich vlastnych klientov, pricom na to vyuziva toto spojenie s databazou. Problem je, ze ak sa nic nedeje dostatocne dlho - po uplynuti doby "wait_timeout" (co je konfiguracna hodnota MySQL, defaultne 8 hodin) MySQL toto spojenie zatvori a potom kazda dalsia query nevrati nic a PHP vyhodi warning:
Warning: Error while sending QUERY packet. PID=97763 in /.../....php on line xxx
Restart tohto skriptu pomoze. Wait_timeout som znizil na 60 sekund a skusil som to potom a podarilo sa mi tento problem zreprodukovat, preto som si isty, ze tu je pes zakopany.
Persistentne spojenie som tiez skusil vytvarat, ale nepomohlo to (prefix "p:" pred hostom pri volani new mysqli(...)).
Uvazujem, ze asi sa to neda inak, nez nejakym udrzovanim spojenia z tohto PHP skriptu. Ze by tam bezal thread, ktory spusti kazdu hodinu napriklad, nejaku lacnu query, len aby udrzal spojenie nazive. Kedze mysqli_ping z istych dovodov nefunguje. A je vobec zdielanie mysqli link-u (resource premennej) medzi threadmi bezpecne?
Ma niekto pls radu, ako by sa to dalo riesit?
audiotrack
VIP
VIP
Používateľov profilový obrázok
Príspevky: 25958
Registrovaný: 09 sep 2005, 18:39
Kontaktovať používateľa:

Re: PHP a MYSQL ako udrzat spojenie

Príspevok od používateľa audiotrack »

ja by som vôbec do perzistentného spojenia nešiel. Tvoja trieda na prácu s db by mohla obsahovať privátnu metodu reconnectIfOffline() ktorá zistí či padlo spojenie a ak hej, tak ho vytvorí znova.

Kód: Vybrať všetko

private function reconnectIfOffline(){
    if (false == $this->connection->ping()){
        $this->connection = $this->connect();
    }
}
nepochopil som, prečo ti ping nefunguje. On nepredlži ten timeout, iba ti povie či je spojenie aktívne. Ak si ho spúšťal v domnení, že ti udrží spojenie, tak chápem. Ale ak si ho spúšťal takýmto spôsobom aby ti povedal či je spojenie aktívne alebo neaktívne, tak neviem čo a prečo ti nefungovalo
Mek
Addict
Addict
Používateľov profilový obrázok
Príspevky: 4661
Registrovaný: 23 mar 2005, 23:00
Bydlisko: ZA <-> TN
Kontaktovať používateľa:

Re: PHP a MYSQL ako udrzat spojenie

Príspevok od používateľa Mek »

Dik za odpoved. Popravde, ping som ani neskusal, pretoze ako pisu tuto, nefunguje by design. Okrem toho by som stale potreboval tu infrastrukturu so zvlastnym threadom a jeho periodickym spustanim, ktore neviem ako spravit (a preto som sa opytal tu na fore). Namiesto pingu by mi aj tak stacilo spustit akukolvek lacnu query.
Metodu, ktoru navrhujes, by som pridat mohol, otazne je ale, kedy by sa mala volat. Pred kazdou operaciou s databazou by to bol asi zbytocny overhead. Preto som uvazoval nad tym threadom, ktory by periodicky volal tu lacnu query na databazu, len neviem nakolko je bezpecne taketo zdielanie spojenia medzi threadmi a neviem, ako ho volat periodicky. Na vsetko, co som vygooglil, bol odpovedou "cron", ale zo zjavnych dovodov to nie je v tomto pripade riesenie. Nemas s tym skusenosti, alebo niekto iny? :?:
audiotrack
VIP
VIP
Používateľov profilový obrázok
Príspevky: 25958
Registrovaný: 09 sep 2005, 18:39
Kontaktovať používateľa:

Re: PHP a MYSQL ako udrzat spojenie

Príspevok od používateľa audiotrack »

to čo píšu v tom bugu je jednak 6 rokov staré na starom php, jednak je to to čo som ti napísal aj ja že ping nereconectne, iba overí či je spojenie živé. Reconectnuť musíš sám.
Neviem ako vyzerá tvoj kod, čo presne a ako robí, ale classa na prácu s db by mohla byť singleton, a pri získavaní inštancie by sa toto vykonávalo. Ak to nie je možné, kľudne by som to dal do každej metody (ale nie priamo v tej tvojej triede, ale vytvoril by som predka alebo potomka ktorý by mal toto implementované). Ak ani toto nie je možné, tak je ešte možnosť neriešiť to preventívne, ale odchytiť chybu ak sa query nepodarilo kvoli mrtvemu spojeniu a reagovať na to otvorením spojenia a znovazavolaním poslednej query. To by ale vyžadovalo už väčšiu zmenu v logike

Skúsenosti s persistentne bežiacim cli skriptom v php nemám, a určite ani nikto iný, lebo je to zlo a ak aj vyriešiš tento problém, zachvílu budeš riešiť iné (napríklad že ti php vyžralo celú pamäť a pod.). Na konzolové veci je lepšie použiť iný jazyk ako php
Napísať odpoveď