AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Speicherüberlauf des MS SQL-Servers bei ADO-Verbindung
Thema durchsuchen
Ansicht
Themen-Optionen

Speicherüberlauf des MS SQL-Servers bei ADO-Verbindung

Ein Thema von windi · begonnen am 25. Nov 2009 · letzter Beitrag vom 28. Nov 2009
Antwort Antwort
Seite 1 von 2  1 2      
windi

Registriert seit: 22. Dez 2004
Ort: Chemnitz
21 Beiträge
 
RAD-Studio 2010 Arc
 
#1

Speicherüberlauf des MS SQL-Servers bei ADO-Verbindung

  Alt 25. Nov 2009, 17:33
Datenbank: Microsoft SQL-Server Express • Version: 2005 • Zugriff über: ADO
Hallo,

ich benötige dringend Hilfe bei einem Datenbankproblem mit einem Microsoft SQL-Server 2005 Express Edition. Ein von mir entwickeltes Delphi-Programm greift per ADOConnection + ADOQuery auf den SQL-Server zu. Das funktioniert bei Programmneustart auch wunderbar. Das Programm läuft ca. 1 1/2 bis 2 Wochen ohne Probleme, dann irgendwann bekomme ich von der ADOQuery-Komponente beim Ausführen einer Select-Abfrage die Fehlermeldung "Für diesen Vorgang ist nicht genügend Speicher verfügbar" Fehlercode: 1240640. Laut dem Taskmanager hat zu diesem Zeitpunkt die sqlsvr.exe die für den Server maximal zu verwendende Arbeitsspeichergröße erreicht. In Zahlen: ich habe im Microsoft SQL Server Managment Studio einen maximalen Serverarbeitsspeicher von 1GB eingestellt, der Arbeitspeicherverbrauch der sqlsvr.exe liegt im um ein paar Byte darunter.
Eine Suche nach dem Fehlercode bzw. der Fehlermeldung war bis jetzt wenig von Erfolg gekrönt. Ich bin echt langsam am verzweifeln, weil ich nicht jede Woche den Rechner neu starten kann. Hatte jemand schon mal ein ähnliches Problem und könnte mir in irgendeiner Form einen Tipp oder Ratschlag geben wie ich dem Grund des Ganzen auf die Spur kommen kann? Unser Kunde dreht mir langsam den Hals um, wenn ich dafür nich bald eine Lösung finde.

lg
windi
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#2

Re: Speicherüberlauf des MS SQL-Servers bei ADO-Verbindung

  Alt 25. Nov 2009, 23:14
Hast du dein Programm mal auf Speicherlecks kontrolliert?

Wenn deine Anwendung 2 Wochen läuft, solltest du sicherstellen, dass dort keine Speicherlecks entstehen. Binde doch einfach mal den FastMM-Speichermanager ein und aktiviere auch das Logfile, dann kannst du, nach einer gewissen Laufzeit, vielleicht schon mehr dazu sagen. Denn vielleicht liegt es nicht an MSSQL sondern eben doch an deinem Programm.

Falls du das schon alles durchgeführt hast, entschuldige bitte mein Kommentar.
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#3

Re: Speicherüberlauf des MS SQL-Servers bei ADO-Verbindung

  Alt 26. Nov 2009, 08:14
als kurzfristige Notlösung würde mir nur einfallen den Dienst in einem gewissen Interval neu zu starten.
Wenn du dein eigenes Programm beendest, bleibt dann der Speicherverbrauch des SQL-Servers weiterhin so hoch? Wenn nicht, speichert der Server eventuell während der Zeit der Verbindung Daten zwischen und ein einfaches Trennen der Verbindung vom Programm zur Datenbank bringt die Lösung.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
windi

Registriert seit: 22. Dez 2004
Ort: Chemnitz
21 Beiträge
 
RAD-Studio 2010 Arc
 
#4

Re: Speicherüberlauf des MS SQL-Servers bei ADO-Verbindung

  Alt 26. Nov 2009, 09:19
Zitat:
Hast du dein Programm mal auf Speicherlecks kontrolliert?
Ja das habe ich. Mein Programm bleibt konstant über die 2 Wochen bei ca. 15MB Arbeitsspeicherverbrauch. Hab auch mal EurekaLog eingebunden und mitlaufen lassen. Hat keine Speicherlecks gefunden. Es ist ja auch der SQL-Server, dessen Speicher konstant bei Zugriffen hochläuft. Laut Hilfe muss das aber so sein. Der Server verwaltet wohl intern den verwendbaren Arbeitspeicher.

Zitat:
Wenn du dein eigenes Programm beendest, bleibt dann der Speicherverbrauch des SQL-Servers weiterhin so hoch?
Ja. Ein Aufräumen des allokierten Arbeitsspeichers erfolgt vom SQL-Server anscheinend nicht.

Zitat:
als kurzfristige Notlösung würde mir nur einfallen den Dienst in einem gewissen Interval neu zu starten.
Habe ich bis jetzt noch nicht probiert und mich davor gescheut, weil auf die Datenbank auch noch eine andere Applikation zugreift.

In einem Forum habe ich noch gelesen, dass es eventuell am verwendeten ADO-Treiber liegen kann. Derzeit verwende ich den "Microsoft OLE DB Provider for SQL Server"-Treiber. Mit dem bei der Installation vom MS SQL-Server 2005 zusätzlich installierten "SQL Server Native Client"-Treiber hatte ich Probleme eine Verbindung zur Datenbank aufbauen zu können. Hatte eventuell jemand schon mal mit dem Treiber ein Problem??
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#5

Re: Speicherüberlauf des MS SQL-Servers bei ADO-Verbindung

  Alt 26. Nov 2009, 09:43
Hallo,

wie greift Dein Programm auf den Server zu?

Beim Programmstart die Verbindung aufbauen und beim Programmende wieder abbauen.

Oder:

Bei Bedarf wird die Verbindung aufgebaut und "baldmöglichst" wieder geschlossen.

Egal welchen Weg Du nimmst, versuche es mal mit dem Anderen.

Bei einem Programm, das noch auf 'nen SQL-Server 2000 zugreift, hatte ich ein ähnliches Problem, dies konnte ich durch "bedarfsgesteuertes" Öffnen und Schließen der Verbindungen reduzieren und per Taskplaner des Nachts durchgeführte Neustarts des Serverdienstes auf ein erträgliches Maß reduzieren. Zugegeben: Keine elegante Lösung.

Gibt es an den Wochenenden ein Zeitfenster, in dem Du den Dienst "gefahrlos" neustarten kannst: Sprich: Gibt es Zeiten, in denen keine Zugriffe auf den Datenbankserver erfolgen? Dein Programm muss dann allerdings damit zurecht kommen und die Verbindung neu aufbauen. Oder: Den Dienst aus Deinem Programm heraus neustarten, wenn sichergestellt ist, dass zu diesem Zeitpunkt kein anderes Programm auf die Datenbank zugreifen muss. Ja: auch das sind nur Krücken und keine wirklichen Problemlösungen.
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#6

Re: Speicherüberlauf des MS SQL-Servers bei ADO-Verbindung

  Alt 26. Nov 2009, 09:46
Hallo,

lasse dir dch den Connection-String zusammenbauen.

Dazu eine leere Text-Datei conn.udl anlegen (Ebdung ist wichtig.
Doppelklick drauf, die benötigten Daten (Provider, DB) einstellen,
Verbindung testen.

Mit OK raus.

Die Datei mit dem Editor öffnen und die Connection-String kopieren.

Der DB-Pfad / Alias ... kann ja variabler gemacht werden (%s + Format)


Heiko
Heiko
  Mit Zitat antworten Zitat
windi

Registriert seit: 22. Dez 2004
Ort: Chemnitz
21 Beiträge
 
RAD-Studio 2010 Arc
 
#7

Re: Speicherüberlauf des MS SQL-Servers bei ADO-Verbindung

  Alt 26. Nov 2009, 10:02
Zitat:
Beim Programmstart die Verbindung aufbauen und beim Programmende wieder abbauen.
Genauso ist es implementiert. Eine Verbindung nur bei Bedarf aufbauen möchte ich nicht, in die Datenbank pro Sekunde ca. 1-7 Datensätze geschrieben werden müssen. Aller 20 Sekunden wird eine Select-Abfrage ausgeführt. Hintergrund ist die Aufzeichnung von Betriebsdaten einer Fertigungsanlage. Ich habe das Programm schon dahingehend erweitert, dass bei Fehlern die durch eine Datenbankabfrage entstehen die Verbindung zur Datenbank getrennt und anschließend neu aufgebaut wird. Leider ist das nicht wirklich hilfreich, da danach die ADOQuery Speicherzugriffsverletzungen meldet: "Zugriffsverletzung bei Adresse 7C9118D0 in Modul 'ntdll.dll'". Das Einzige was kurzzeitig hilft ist das Programm komplett zu beenden und anschließend neu zu starten.
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#8

Re: Speicherüberlauf des MS SQL-Servers bei ADO-Verbindung

  Alt 26. Nov 2009, 10:10
Hallo,

dann ist doch etwas faul.
Wie schließt die die Verbindung ?

Was passiert mit den angehängten Queries ?
Beendest du die auch (Free, (Re)Create ? )

Ich würde mal den Native Client per meinem UDL-Thread anbinden.


Heiko
Heiko
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#9

Re: Speicherüberlauf des MS SQL-Servers bei ADO-Verbindung

  Alt 26. Nov 2009, 10:14
Hallo,

das heißt schlicht und einfach: Dein Programm und die Datenbank müssen dauerhaft stabil laufen, da ist dann nix mit irgendwelchen Krücken.

Momentan habe ich leider keine Idee, wie Du das Problem wegbekommen könntest.

Gibt es hier eventuell einen Ansatz? http://entwickler-forum.de/showthread.php?t=58388
  Mit Zitat antworten Zitat
windi

Registriert seit: 22. Dez 2004
Ort: Chemnitz
21 Beiträge
 
RAD-Studio 2010 Arc
 
#10

Re: Speicherüberlauf des MS SQL-Servers bei ADO-Verbindung

  Alt 26. Nov 2009, 16:44
Die Datenbankverbindung wird über folgende Funktion geöffnet:
Delphi-Quellcode:
function TADODatabase.OpenDatabase: Boolean;
 begin
  Result := True;
  try
   ADOConnection.Open;
   if (Assigned(OnDBConnection)) then
    OnDBConnection(csCONNECTED);
  except
   on E: Exception do
    begin
     Result := False;
     ShowErrorMessage('Fehler beim Verbindungsaufbau mit "' + ConnectionString + '"! Grund: ' + E.Message);
    end;
  end;
 end;
... und wieder geschlossen:
Delphi-Quellcode:
function TADODatabase.CloseDatabase: Boolean;
 begin
  Result := True;
  try
   if (ADOQuery.Active) then
    ADOQuery.Active := False;
   ADOConnection.Close;
   if (Assigned(OnDBConnection)) then
    OnDBConnection(csDISCONNECTED);
  except
   on E: Exception do
    begin
     Result := False;
     ShowErrorMessage('Fehler beim Verbindungsabbau mit der Datenbank! Grund: ' + E.Message);
    end;
  end;
 end;
Eine Abfrage erfolgt im Programm über:
Delphi-Quellcode:
try
  FBDE_DB.DoSelectQuery('SELECT * FROM [dbo].[PQ25Parts_T] WHERE [TeileID]=' + IntToStr(FLastReadedMessage.TeileID));

  // ... mach irgendwas damit ...

finally
  FBDE_DB.CloseQuery;
end;
Die Funktion DoSelectQuery sieht so aus:
Delphi-Quellcode:
function TADODatabase.DoSelectQuery(Query: String): Boolean;
var StartTime: Double;
 begin
  if (ADOConnection.Connected) then
   begin
    StartTime := Now;
    try
     ADOQuery.SQL.Clear;
     ADOQuery.SQL.Add(Query);
     ADOQuery.Open;
     ADOQuery.First;
     Result := True;
    except
     on E: Exception do
      begin
       ShowErrorMessage('SQL Fehler in: "' + Query + '" auf ' + ServerName
                        + ' Grund: ' + IntToStr(E.HelpContext) + ' "' + E.Message + '"');
       Result := False;
      end;
    end;
    if (FUseQueryActivityTimer) then
     FQueryActivity.NewQueryExecution(Query, Now - StartTime);
   end
  else
   Result := False;
 end;
Die Funktion CloseQuery sieht folgendermaßen aus:
Delphi-Quellcode:
procedure TADODatabase.CloseQuery;
 begin
  if (ADOQuery.Active) then
   ADOQuery.Close;
 end;
Die Funktionen DoSelectQuery und CloseQuery sind in einem Datenmodul angelegt, welches eine TADOConnection- und eine TADOQuery-Komponente enthält.

Was ist der Vorteil, wenn ich einen UDL-Thread verwende bzw. wie geht sowas? Ich verwende derzeit einen Arbeitsthread, der neue Meldungen von der Anlage entgegennimmt und entsprechend Querys an die Datenbank sendet. Die Vorgehensweise verwende ich so nun schon im vierten Projekt mit unterschiedlichsten Datenbanken. Leider hatte ich es bis jetzt noch nie mit derartigen Problemen zu kämpfen (aber auch noch nie mit solchen Datenmengen).
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:20 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz