ZEOS Postgres SIGSEGV

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: ZEOS Postgres SIGSEGV

Beitrag von Michl »

Interessant! Werde mal verschiedene Tests machen. Das könnte erklären, warum es mir auch eine Master-Detail-Verbindung an nachfolgender Stelle kappt - hatte ich bisher auch auf den SIGSEGV geschoben (da half die Connnection trennen/verbinden bisher nicht).

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

hde
Beiträge: 556
Registriert: Mi 11. Aug 2010, 02:56

Re: ZEOS Postgres SIGSEGV

Beitrag von hde »

von dem Master-Detail-Problem hast du hier bisher nichts gesagt. Näheres?
Sollte ich heute Nachmittag mal etwas Luft haben werd ich dein Prob mal mit anderen DBs checken, je nach dem wissen wir dann, wo zu suchen ist.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: ZEOS Postgres SIGSEGV

Beitrag von Michl »

hde hat geschrieben:von dem Master-Detail-Problem hast du hier bisher nichts gesagt. Näheres?
Sollte ich heute Nachmittag mal etwas Luft haben werd ich dein Prob mal mit anderen DBs checken, je nach dem wissen wir dann, wo zu suchen ist.
Von dem konnt ich bisher noch nicht berichten, da zuvor immer erst de SIGSEGV auftrat. Dieses Problem trat erst auf, als ich den vermeintlichen Workaround mit dem Connection.Reconnect gefunden hatte.

Der Fehler schleicht sich bei TZPostgreSQLResultSet.Open ein, meld mich, wenn ich genaueres weiss...

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: ZEOS Postgres SIGSEGV

Beitrag von Michl »

Ich denke, ich habs jetzt in etwa verstanden:
unter Unit ZDbcPostgreSql werden alle schon mal geöffneten Tabellen in dem Array

Code: Alles auswählen

 FTblInfo: Array of TZPGTableInfo;   
zwischengespeichert. Das wird sicherlich aus Performance-Gründen notwendig sein. Wahrscheinlich nutzen SQLdb bzw. ältere Zeos-Versionen diese Zwischenspeicherung nicht, daher tritt das Verhalten dort nicht auf.

Unter (unit ZDbcPostgreSql)

Code: Alles auswählen

function TZPGTableInfoCache.GetTableInfo(const TblOid: Oid): PZPGTableInfo;
var Idx: Integer;
begin
  Idx := GetTblPos(TblOid);
  if (Idx = -1) then
  begin
    if (TblOid <> InvalidOid) and (LoadTblInfo(TblOid, Idx)) then
      Result := @FTblInfo[Idx]
    else
      Result := nil;
  end
  else
    Result := @FTblInfo[Idx];
end; 
wird die gleiche TblOid (gleiche Tabelle) verwendet, daher wird LoadTblInfo(TblOid, Idx) nicht aufgerufen. Daher wird bei

Code: Alles auswählen

TZPostgreSQLResultSet.Open;  
...
        SchemaName := TableInfo^.Schema;
        TableName := TableInfo^.Name;
//        ColumnName := 'Column'+IntToStr(i);  //hier würde der Fehler nicht auftreten
        ColumnName := TableInfo^.ColNames[FplainDriver.GetFieldTableColIdx(FQueryHandle, I) - 1];
 
der ColumnName aus einem nicht vorhandenen Wert aus dem Array of String (TZPGTableInfo) bezogen, daher gibts den SIGSEGV.

Nicht schön, aber mir hilfts jetzt erstmal weiterzuarbeiten. Ich lösche einfach diesen Cache, damit ist dieses Verhalten erstmal unterbunden, mal sehen, ob das Perfomance-mäßig vertretbar ist:

Code: Alles auswählen

function TZPGTableInfoCache.GetTableInfo(const TblOid: Oid): PZPGTableInfo;
var Idx: Integer;
begin
  SetLength(FTblInfo, 0);
  Idx := GetTblPos(TblOid);
  if (Idx = -1) then
  begin
    if (TblOid <> InvalidOid) and (LoadTblInfo(TblOid, Idx)) then
      Result := @FTblInfo[Idx]
    else
      Result := nil;
  end
  else
    Result := @FTblInfo[Idx];
end;
 
Vielen Dank an Dich hde, für die viele Mühe!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

hde
Beiträge: 556
Registriert: Mi 11. Aug 2010, 02:56

Re: ZEOS Postgres SIGSEGV

Beitrag von hde »

das ist absolut einleuchtend. Danke für die Info.

Da ich in anderenProbs stecke konnte ich dieses Verhalten mit anderen DBs leider noch nicht testen, könnte dort aber genausogut so sein.

Wir alle sollten deshalb bis zurm nächsten Release von zeos sehr vorsichtig sein wenn im laufenden Betrieb Metadaten verändert werden,
und uns an dein Workaround erinnern.

Wäre gut, wenn das Zeos-Team den Bug beseitigen würde. Melde ihn mal als Bug.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: ZEOS Postgres SIGSEGV

Beitrag von Michl »

Hab schon ne Idee für einen Patch (würde dann diesen mitsenden), muss aber erst noch ein paar andere Dinge erledigen...

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: ZEOS Postgres SIGSEGV

Beitrag von Michl »

Für die, die es evtl. interessiert.

Ich habe verschiedene Versuche gemacht und verschiedene Varianten ausprobiert. Letztlich bin ich bei der Variante hängengeblieben, dass ich einfach vergleiche, ob die Spaltenzahl (neu in PZPGTableInfo eingefügt) mit der aktuellen Spaltenzahl übereinstimmt. Falls nicht wird ein Update des FTableInfoCache vorgenommen.

Da nur sowieso ausgelesen Werte verglichen werden, gibt es quasi kein Perfomance-Verlust. Einzig, falls sich statt der Anzahl der Spalten, z.B. sich deren Namen ändern (oder wenn eine Spalte eingefügt wird und eine andere gelöscht wird, die dann eine anderen Inhalt z.B. String/Integer/Datum etc.), werden diese Informationen nicht aktualisiert. Da ich selber in keiner einzigen Anwendung eine Spalte umbenennen lasse und mir auch dafür kein wirklicher Grund einfällt (die Gefahr, dass man die gleiche Zahl Spalten hinzufügt und wieder löscht ist ebenfalls recht gering), finde ich dieses "Fehlerverhalten" vernachlässigbar, zumal bei dem nächsten Reconnect der richtige Name dann übernommen wird.

Ich hab dafür einen Patch für Zeos 7.2 gemacht. Da mir ein Bug-Tracker für Zeos nicht bekannt ist, habe ich diesen Patch einfach im Zeos-Forum hochgeladen, mal sehen, ob der so oder so ähnlich übernommen wird...

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

hde
Beiträge: 556
Registriert: Mi 11. Aug 2010, 02:56

Re: ZEOS Postgres SIGSEGV

Beitrag von hde »

Danke für die Info, hab mir den Patch schon geholt. Ich hffe, dass Zeos-Dev-Team reagiert.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: ZEOS Postgres SIGSEGV

Beitrag von Michl »

Im Eifer des Gefechts, hatte ich einen Eintrag vergessen (unit ZDbcPostgreSql):

Code: Alles auswählen

function TZPostgreSQLConnection.GetTableInfo(const TblOid: Oid; Refresh: Boolean
  ): PZPGTableInfo;
begin
  Result := FTableInfoCache.GetTableInfo(TblOid, Refresh);  //hier das "Refresh" einzutragen
end;
Müsstest also nochmal den Patch laden oder einfach dort eintragen, sorry :wink:

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: ZEOS Postgres SIGSEGV

Beitrag von Michl »

Bug ist beseitigt, Danke EgonHugeist!

http://zeoslib.sourceforge.net/viewtopi ... 190#p30190

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Antworten