Announcement

Collapse
No announcement yet.

Zuwenig Arbeitsspeicher IB6.5

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Zuwenig Arbeitsspeicher IB6.5

    Hallo,
    ich habe seit einigen Monaten massive Probleme mit IB 6.5.
    Interbase 6.5 mit IBX 6.03, läuft auf einen Rechner unter Windows NT Server, Die Server Aplikation wurde mit Delphi 6 SP.2 geschrieben.
    Der Ablauf ist wie folgt: In einer IBTransaction wird aus einer Verketten Liste (aus Externen Programm)werden Datensätze geschrieben / upgedatet. Dazu werden aus der lokalen IB Datensätze aus einer anderen Tabelle hinzugelesen. Dabei passiert es ab und zu das beim Zulesen der Datensätze (eingeschränkter Select Befehl über IB Delphi SQL komponente) der fehler zuwenig Arbeitspeicher auftritt. Der physische frei Speicher ist jedoch vorhanden in diesem Moment ca. 900MB !!
    Der Server und die Aplikation laufen durch dh. das Problem tritt erst nach ca. 10 bis 15 Tagen auf. Die Datenbank hat ca. 70 MB und ziemlich viel Traffic). Die Aplikation stürzt nicht ab lediglich das zulesen (select Befehl) wird nicht ausgeführt. Es scheint als das die Delphi IBquery Komponente da nicht auf den vorhanden Speicher zugreifen kann. Ich habe schon alles mögliche probiert (zum Teil aufrufe über StorageProceduren, ForceWrites auf TRUE usw.) das half nur bedingt.
    Inserts und updates werden jedoch über die Delpi IBquery komponente korrekt gemacht.
    Weiß da jemand Rat? Oder hat jemand schon ein ähnliches Problem gehabt.
    Grüße
    Thomas Absmann

  • #2
    Hallo!<br>
    <br>
    Blöde Frage: Die Transaktion wird schon in regelmässigen Abständen Committed? Wenn ja, mit einem "harten" Commit oder "nur" CommitRetaining?<br>
    Siehe hierzu einige Beiträge von A. Kosch in Delphi | IBX.<br>
    <br>
    Christia

    Comment


    • #3
      Hallo Christian,
      ja, es wird Commited "hart". Die Einstellungen dieser IBTransaktion sind: "write, consistency, wait". da hab ich mich auch schon ziemlich lang gespielt und diese scheint mir die Beste. Es sind auch noch 20 Clients auf der Datenbank mit mehreren Transaktion mit der Einstellung "Schnappschuß". Mir fehlen auch keine neu anzulegenden Datensätze. Auch die Updates werden korrekt gemacht, nur das zulesen aus einer anderen Tabelle über IBQuery (select) funktioniert nicht. Sogar wenn der Fehler auftritt wird der eigentlich anzulegende Datensatz (Insert, update) Fehlerfrei in die DB geschrieben (hart Commited).
      Thoma

      Comment


      • #4
        Hallo Ingemar,<br><br>
        - Tritt die Fehlermeldung "Zu wenig Arbeitsspreicher" am Server oder am Client auf?<br><br>
        - Führ mal gstat.exe -h auf der Datenbank aus<br><br>
        - Welchen Wert besitzt der Parameter <b>Page Buffers</b> der Datenbank und welche Page Size verwendest Du. Sollte Dir der Parameter nichts sagen, dann ist dieser vermutlich 0, und es wird der serverweite Wert (AFAIK 2048) verwendet. In InterBase 6.5 und höher sollte ein Bug beseitigt sein, der einen Page Buffers Wert von > 10000 erlauben sollte, ohne dass die Performance darunter leidet. Mit folgender Formel kannst Du für die SuperServer Architektur berechnen, wieviel Hauptspeicher InterBase für diese eine Datenbank fürs Caching maximal verwendet. <b>Hauptspeicher_Caching = Page Size * Page Buffers</b>. D.h. mit einer PageSize von 4K und Page Buffers von 10000, wird für diese DB maximal 40 MB Hauptspeicher fürs Caching verwendet.<br><br>
        - Wie groß (Anzahl der Datensätze) ist die Ergebnismenge, die von diesem Select zurückkommt? Was soll am Client dann mit dieser Ergebnismenge passieren? Wenn sie nur dafür dient, dass man vom ersten bis zum letzten Datensatz drüberiteriert, dann sollte man die IBQuery im Unidirektionalen Modus betreiben, da dies am Client erheblich ressourcenschonender ist, allerdings verlierst Du die Möglichkeit, dass man den Datensatzzeiger zurückpositionieren kann.<br><br>
        Schöne Grüße,<br>
        Thoma
        Thomas Steinmaurer

        Firebird Foundation Committee Member
        Upscene Productions - Database Tools for Developers
        Mein Blog

        Comment


        • #5
          Hallo Thomas,
          danke für Deine Nachricht. Zu der Frage ..tritt der Fehler am Server oder Client, der Fehler tritt ausnahmslos am Server auf der Client merkt nichts davon,
          Die Werte aus gstat.exe:
          Flags=0, Checksum=12345, Generation=116294, Page Size=4096, ODS version=10.1, Oldest transaktion 113512, Oldest active=113513, Oldest snapshot=113513, Next transaction=116286, Bumped transaktion=1, Sequence number=0, Next attachment ID=0, Implementation ID=16, Shadow count=0, Page buffers=0, Next header page=0, Dataset dialect=1, Creation date Apr 8 2003 16:43:08, Attributes=force write, Sweep interval=20000;
          ...anzahl Datensätze in Ergebnissmenge, 1 bis max 300, ca 200 bis 330 Byte pro Datensatz. Wenn der Fehler auftritt tritt er bei allen selects unterschiedlicher Tabellen auf dh. das Problem bezieht sich nicht auf eine einzelne Tabelle. Zur Frage was soll am Client mit Ergebnismenge passieren...Eigentlich nichts unmitelbar. Kurz zum Systemablauf: Der Server bzw. die ServerAplikation empfängt über Remote Datensätze und stellt diese über die lokal liegende InterbaseDatenbank den Clients zur Verfügung. Diese lesen und updaten dann irgendwann einmal. Am Server habe ich nun die IBQuery auf Unidirektional=true gesetzt auf den Clients ist das leider nicht Möglich. Ich möchte betonen, daß wir die letzten Wochen damit verbracht haben so resourcen schonend wie möglich die Programmarchitektur zu schreiben. So gibt es am Server bzw Clients kein einzige uneingeschränktes select * from...; Vielleicht kann jemdand aus den obigen Infos was ungewöhnliches herauslesen.
          Grüße Thoma

          Comment


          • #6
            Hallo,
            mir ist da noch was aufgefallen in meinem source:

            dm.quHVerp.Close;

            dm.quHVerp.SQL.Clear;

            dm.quHVerp.SQL.Add('select * from HVerp where VBELN = "' + dm.KEY10 + '";');

            try

            dm.quHVerp.Open;

            except

            RfcLog('F-2073 HVERP Select Open kann nicht durchgeführt
            werden KEY: ' + String(dm.KEY10));

            end;

            if not (<B>dm.quHVerp.Eof </B>and <B>dm.quMaterial.Bof</B>) then
            begin

            .....;

            bei der bedingung if not query.eof wird vorher die query dm.quHVerp geöffnet jedoch die query dm.quMaterial nicht die aber in der bedingungsanweisung angesprochen wird. Warum das überhaupt funktioniert ist mir unklar. Tatsache ist das an dieser Stelle die query dm.quMaterial nicht explizit geöffnet wurde. Ich hab dies nun korrigiert, kann das mit dem Arbeitspeicherproblem zu tun haben?
            Thoma

            Comment


            • #7
              Hallo Thomas oder doch Ingemar?,<br><br>
              bzgl. DB-Statistik. Der Abstand von OIT und Next Transaction ist immerhin > 2700, d.h. entweder hast Du eine langlaufende Transaktion, oder eine lange Transaktion wurde zurückgesetzt (rolled back). Ich hab allerdings schon Datenbanken gesehen, wo dieser Abstand um ein vielfaches größer war. Verwendest Du eine eigene Transkationsstrategie? Mit "Hard" Commits oder CommitRetaining?<br><br>
              Dies ist etwas die Suche nach der berühmten Nadel im Heuhaufen. Wie siehts am Server mit freien Festplattenspeicher aus? Vor allem mit der Partition, wo InterBase temporäre Dateien ablegt? Wenn Du viel Hauptspeicher am Server hast, dann würd ich unbedingt die <b>Page Buffers</b> der Datenbank hinaufdrehen (derzeit bei dir 0 => serverweite Einstellung wird verwendet; AFAIK 2048) auf z.B. 10.000 oder ab IB 6.5 kann dieser Wert auch größer sein. Auswirkungen durch diesen Parameter siehe oben (die Berechnungsformel).<br><br>
              Gruss,<br>
              Thoma
              Thomas Steinmaurer

              Firebird Foundation Committee Member
              Upscene Productions - Database Tools for Developers
              Mein Blog

              Comment


              • #8
                hallo thomas,<p>

                try
                dm.quHVerp.Open;
                except
                RfcLog('F-2073 HVERP Select Open kann nicht durchgeführt werden KEY: ' + String(dm.KEY10));
                end;
                <p>
                wo ist denn das Close ?
                <p>
                ich würde das so schreiben

                try
                dm.quHVerp.Open;
                try
                finally
                dm.quHVerp.Close;
                end;
                except
                RfcLog('F-2073 HVERP Select Open kann nicht durchgeführt werden KEY: ' + String(dm.KEY10));
                end;
                <p>
                Heik

                Comment


                • #9
                  Hallo,
                  nach 1 Monatiger Beobachtung der Datenbank, kann ich nun sagen, daß der Fehler "zu wenig Arbeitsspeicher" behoben ist. An dieser Stelle möchte ich allen danken die mir zu diesem Problem Lösungsansätze geliefert haben. Besonders möchte ich Thomas Steinmaurer danken, der den Tipp mit der Page Size hatte und bei der ich die Ursache des Fehler's glaube, da es zutrifft, daß unsere Transaktionen ziemlich "lang" sind und der DB einfach dafür der Speicher nicht zugewiesen wurde.

                  Thoma

                  Comment

                  Working...
                  X