MySQL, dxExpress, too many connections

0

Witam
Mam aplikacje pisaną w Delphi, która korzysta z bazy danych MySQL.
Początkowo pisząc aplikację korzystałem z komponentów BDE, później jednak zacząłem ją stopniowo przerabiać na komponenty dbExpress. No i pojawił się problem.

W starej wersji, gdy używałem komponentów TTable i TQuery, to nawet jak było ich jednocześnie otwartych kilkadziesiąt, to było tylko jedno połączenie z bazą danych (komenda "show processlist;" w mysqlowej konsoli wypluwała tylko jedną linijkę dla jednej uruchomionej aplikacji). Teraz w nowej wersji, gdy korzystam z TSQLDataSet (w połączeniu z TDataSetProvider i TClientDataSet) to każda otwarta tabelka to jedno połączenie, mimo że cała aplikacja (wszystkie TSQLDataSet'y) jest oparta tylko o jeden komponent TSQLConnection. W efekcie, gdy na jednej stacji roboczej uruchomię aplikację, to tych połączeń jest np. kilkadziesiąt. Gdy uruchamiałem na drugiej stacji roboczej, to ta liczba się podwaja. W efekcie standardowo ustawiony MySQL na max_connections=100 zapychał się już przy otwieraniu aplikacji przez drugiego użytkownika. Zwiększenie liczby max_connections z 100 do np. 10000 to nie jest rozwiązanie, bo prędzej czy później MySQL przestanie działać efektywnie, zapcha się, a może i nawet wysypie. Czy w takim razie jedynym rozwiązaniem jest przeprogramowanie aplikacji tak, aby nie miał nigdy jednocześnie otwartych tak wielu tabel i query? Czy też wystarczy coś gdzieś zmienić w opcjach, żeby każda otwierana tabelka nie była nowym połączeniem z bazą, tak jak to było w przypadku BDE, który ponoć w porównaniu z dbExpress to archaiczne narzędzie?

Z góry dzięki za pomoc.

0

Czy po post dajesz ApplyUpdates (zakończenie transakcji)? Dawno nie używałem ClientDataSet bo stosuję komponenty niebazodanowe, więc nie pamiętam dobrze tego.

0

Daję, ale to nie ma znaczenia, czy daję, czy nie. Już po samym włączeniu aplikacji, zanim cokolwiek w niej kliknę, już mam kilkadziesiąt połączeń.

1

Mam pewien pomysł. Raportowano bowiem o błędach w bibliotekach MySql i w Delphi. Spróbuj zmienić na chwilę rodzaj bazy danych (na interbase albo coś innego). Aplikacja powinna być skalowalna i powinno dać się to zrobić, jeśli nie używasz poleceń SQL spoza standardu. Jeśli błąd się powtórzy, to prawdopodobnie jest w twojej aplikacji a jeśli nie, to prawdopodobnie poza twoim kodem.

Miałem kiedyś problemy z używaniem poziomu izolacji transakcji xilREPEATABLEREAD gdy był wpisany do TSQLConnection (błąd w Delphi).

0

Nie próbowałem tego na innej bazie, bo nie mam za bardzo czasu na to. Ale czytając helpa w Delphi natknąłem się na właściwość MaxStmtsPerConn, która pokazuje limit "statements" (nie wiem, jak przetłumaczyć to słowo) dla jednego połączenia z bazą. Jeśli liczba ta jest równa 0, to nie ma limitu, a jeśli większa od 0, to jest limit. W moim przypadku liczba ta wynosi 1 i to może być powód tego, że z każda otwieraną tabelką, czy zapytaniem otwiera nowe połączenie (tak, jakby "klonował" te SQLConnection). Nie wiem tylko w jaki sposób zmienić te MaxStmtsPerConn. Z poziomu aplikacji w Delphi tego nie da się zrobić, bo jest ona read-only. Mam wrażenie, że to jest problem sterownika MySQL w Delphi, bo w samych ustawieniach MySQL-a też nigdzie takiej właściwości nie znalazłem. Wiecie może skąd można by było pobrać NAJNOWSZE biblioteki libmysql.dll i dbxmys.dll? Moja libmysql.dll jest z 1 marca 2010, a dbxmys.dll z 19 listopada 2009 więc teoretycznie nie takie stare... Może są nowsza? A może nie tędy droga do usunięcia tego limitu "statementsów" na jedno połączenie?

0
Mariusz Jędrzejowski napisał(a)

Mam pewien pomysł. Raportowano bowiem o błędach w bibliotekach MySql i w Delphi. Spróbuj zmienić na chwilę rodzaj bazy danych (na interbase albo coś innego). Aplikacja powinna być skalowalna i powinno dać się to zrobić, jeśli nie używasz poleceń SQL spoza standardu. Jeśli błąd się powtórzy, to prawdopodobnie jest w twojej aplikacji a jeśli nie, to prawdopodobnie poza twoim kodem.

Facet - nie masz pojęcia o czym piszesz.
Takie rady, możesz dawać dzieciom - OK? Prawdopodobnie to lub tamto - a jak już będzie prawdopodobne to lub tamto, to co on z tym dalej zrobić?
Skalowalna - pfff...
Poza tym - jak sobie wyobrażasz przenieść bazę danych składająca się z kilkuset/tysięcy tabel i innych obiektów na "interbase lub coś innego"? Na chwilę?!

Miałem kiedyś problemy z używaniem poziomu izolacji transakcji xilREPEATABLEREAD gdy był wpisany do TSQLConnection (błąd w Delphi).

Dobrze - miałeś inny poziom izolacji, ale co to ma wspólnego z tematem?

--
wloochacz

0

Może wystarczy przypisać AutoClone na True?
http://docwiki.embarcadero.com/VCL/en/SqlExpr.TSQLConnection.AutoClone

0
Mariusz Jędrzejowski napisał(a)

Może wystarczy przypisać AutoClone na True?
http://docwiki.embarcadero.com/VCL/en/SqlExpr.TSQLConnection.AutoClone

Jeśli już, to na False.
Poza tym - jeżeli OIDP, to nie wystarczy, gdyż błąd jest znany i występuje w sterowniku dbExpress producenta Delphi w wersji 2007.
A poza tym, to:
http://www.goldenline.pl/forum/2340622/mysql-dxexpress-too-many-connections

Tylko wiesz, czytać ze zrozumieniem to trzeba umieć - a nie opierać się na "wydaje mi się, że [...] bo inaczej to debilizm"; żeby była jasność - do pytacza kierowałem to zdanie.

0

Witam po urlopie.
Wróciłem i widzę niezłą dyskusję (szczególnie na goldenline), gdzie niestety znów nie obyło się bez zbędnego obrażania/wyśmiewania.
Na szczęście problem póki co został rozwiązany. Wystarczyło zmienić AutoClone na false i już nie klonuje połączeń. Teraz aplikacja działa wg zasady jedna stacja robocza = jedno połączenie. Dzięki temu nie dość, że nie zapycha mi liczby połączeń, to działanie aplikacji przyspieszyło wręcz niesamowicie. I o to mi chodziło. Od początku czułem, że wbrew temu, co niektórzy pisali, problem dotyczy jakiejś pierdołki, że wystarczyło zmienić wartość jednej właściwości. I chyba się nie myliłem.
Dzięki wszystkim za pomoc. Mam nadzieję, że w przyszłości mogę nadal na was liczyć, ale tym razem bez inwektyw ;)

PS. Da się jakoś zmienić wartość tego MaxStmtsPerConn?

1 użytkowników online, w tym zalogowanych: 0, gości: 1