|
|
#1 |
|
Registrierter Benutzer
|
Maximale Datenbankgrößen in OAIII
Hallo zusammen,
jetzt habe ich lange gesucht und doch nichts gefunden: wo finde ich die Limitierungen für Datenbanken unter OAIII/OA4 ? Es muss wohl eine maximale Dateigröße bei 32768 kB geben. Läßt sich das umgehen? Gibt es auch Einschränkungen bezüglich der Anzahl von Datensätzen? Gruß Hans Jürgen |
|
|
|
|
|
#2 |
|
Entwickler
|
EDIT: Lt. Handbuch hast du bei OA4 2048 Byte pro Datensatz bei max. 2.2.Milliarden Datensätzen = 4.0 TB für eine Datei wenn ich mich nicht verrechnet habe.
Über OA3 habe ich leider keine Angaben. |
|
|
|
|
|
#3 |
|
Moderator
|
Da stößt Du vorher aber auf das FAT-Limit von 2GB pro file
|
|
|
|
|
|
#4 |
|
Registrierter Benutzer
|
In welchem Handbuch und unter welchem Kapitel steht das? Ich habe ja die OA3 Unterlagen hier, finde aber nichts.
|
|
|
|
|
|
#5 |
|
Entwickler
|
Im Datenbankhandbuch ganz hinten (vor dem Inhaltsverzeichnis).
|
|
|
|
|
|
#6 |
|
Registrierter Benutzer
|
Ich habe das OAIII Datenbank-Handbuch, da steht dummerweise nichts. Und auch alle anderen Handbücher habe ich durchsucht.
Gibt es eigentlich außer dem OA4-Programmierer-Handbuch noch weitere Handbücher als PDF irgendwo? |
|
|
|
|
|
#7 |
|
Entwickler
|
Ich hab nur die OA4 Handbücher ...
|
|
|
|
|
|
#8 |
|
Moderator
|
Hallo zusammen,
Ich hab das jetzt mal verifiziert, OA3 hat tatsächlich ein 32MB Limit, es dürfte sich hierbei wohl um einen Design/Programmierfehler handeln. Ich würde es als Bug klassifizieren, nachdem keinerlei Sicherheitsüberprüfungen zu diesem Limit implementiert sind und der Fehler somit für die Datenintegrität gefährlich ist (u.A. zerschießt man sich bei der Reparatur das .IF file). Bevor wir zur weiteren Analyse schreiten gleich vorweg: Dieser Fehler wurde in OA4 behoben, dort kann man also ungestört mit großen Dateien operieren (bei der Netzwerkversion aber meinen Heap-Patch nicht vergessen, dort ist nämlich wiederum ein Speicherüberschreiber bug drinnen, aber das haben wir eh schon in einem anderen Thread abgehandelt). Aufgrund der Natur des Fehlers, ist es leider nicht möglich, das so einfach zu patchen, da hierfür umfangreiche Änderungen des Programmablaufs notwendig wären (Aufruf anderer Funktionen mit anderen Parametern, etc.). Nun zur Fehleranalyse: Schreibt man ein kleines Programm, welches in einer Schleife einfach versucht, die Datenbank zu befüllen und mit dem uns wohl bekannten TRACE-Utility mitprotokolliert, so erhält man kurz vor Abbruch Folgendes: 8 = Filehandle der .DF Datei Code:
42 3A3B:135D lseek(8, 0, 2) = 33551361 ; Länge der Datei? 42 3A3B:135D lseek(8, 33551360, 0) = 33551360 ; Gehen wir zur letzen Seite 3f 3A3B:1310 read(8, 29C0:675A, 4096) = 1 ; Seite Lesen -> Ups, die ist nicht da, nur 1 Byte gelesen 42 3A3B:135D lseek(8, 0, 1) = 33551361 ; Wo sind wir? -> Am Ende der Datei Hier kann man noch nicht ganz verstehen, was los ist, aber beim Reparieren der Datei offenbart sich das Ganze dann etwas detaillierter. Merken wir uns vorerst nur einmal die Adresse der hier zur Anwendung kommenden Funktion, welche lseek aufruft -> 3A3B:135D Repariert man die .DF Datei also mit dem Reparaturtool, so kann man schön sehen, wie die .IF Datei sich kurz vor Abbruch der Reparatur mit einem Fehler selbst zerstört. Auch hier können wir wieder den Trace betrachten (7 ist hier das handle zur .DF Datei, 8 ist das zur .IF Datei): Code:
26C4:24E7 lseek(8, 33550336, 0) = 33550336 26C4:251D read(8, 904A:0010, 2048) = 2048 3A3B:135D lseek(7, 0, 2) = 33551361 3A3B:135D lseek(7, 21398528, 0) = 21398528 3A3B:1310 read(7, 29C0:414A, 4096) = 4096 3A3B:135D lseek(7, 0, 1) = 21402624 26C4:24E7 lseek(8, 33550336, 0) = 33550336 26C4:251D write(8, 904A:0010, 2020) = 2020 3A3B:135D lseek(8, 2048, 0) = 2048 3A3B:1310 write(8, 29C0:FDB4, 0) = 0 3A3B:135D lseek(8, 0, 2) = 2048 Der Seek auf Position 2048 sieht wie ein 16bit Integer Überlauf aus, denn unter 16bit Systemen wie DOS ist ein INT nunmal so lang. Die Bestätigung dieser Theorie findet sich, wenn man die Seek-Funktion an der angegebenen Adresse zerlegt, ich habe sie hier dokumentiert und erläutert. Nachdem ich den Debugger in einer anderen Umgebung ausgeführt habe, als den Trace, bitte nicht darüber wundern, dass hier im Dump ein anderes Segment steht als im TRACE: Code:
2393:133A 8BEC mov bp,sp 2393:133C 8B5E08 mov bx,[bp+08] ss:[FE86]=0006 ; File handle 6 2393:133F 8B460A mov ax,[bp+0A] ss:[FE88]=0042 ; 42h = lseek 2393:1342 8AE0 mov ah,al 2393:1344 3C3E cmp al,3E ; Close file? 2393:1346 7415 je 0000135D ($+15) (no jmp) ; \_ Then do it 2393:1348 8B4E04 mov cx,[bp+04] ss:[FE82]=0000 ; Origin of move (0,1,2) 2393:134B 8AC1 mov al,cl 2393:134D 8B5606 mov dx,[bp+06] ss:[FE84]=13AA ; Block in file (0-32MB)! 2393:1350 33C9 xor cx,cx 2393:1352 8ACE mov cl,dh 2393:1354 8AF2 mov dh,dl 2393:1356 32D2 xor dl,dl 2393:1358 F8 clc 2393:1359 D1D2 rcl dx,1 2393:135B D1D1 rcl cx,1 ; Offset = 512*Sector no 2393:135D CD21 int 21 Stack: ------ 0-4 Return address 4-6 Origin of move (0,1,2) 6-8 Block to write 8-A File handle A-C DOS INT21h Function (42h=lseek, 3E=close file) Jetzt stellt sich noch die Frage, wo diese Funktion aufgerufen wird. Sieht man sich die Returnadresse am Stack an und folgt dieser, landet man nach Ausführen der Funktion wieder im UCSD-Pascal PCODE-Interpreter. Anhand der gelesenen Bytes lässt sich feststellen, wo im PCODE wir uns befinden. Es handelt sich um eine Stelle im PASCAL.IMAGE der OA3.SPI, also im PASCAL-Teil der Runtime. Sieht man sich die PCODE Opcodes dort an, so hat man zumindest eine Vermutung, was hier getan wird. Leider sind die PCODE Opcodes der Pascal Runtime für die hier verwendete DOS-Version scheinbar nirgends dokumentiert, sie dürften sich rein von der Logik her auch von der klassischen PCode-Machine für Apple II unterscheiden, leider ist es mir bis heute nicht gelungen heruaszufinden, welches UCSD Development-System hier verwendet wird. Eventuell ist das von SPI selbst gestrickt, oder sie haben es irgendwo zugekauft, es finden sich jedoch keine Spuren davon im Netz, man findet meist nur die alten Runtime-Systeme aus Ende der 70er Jahre. Hier mein "Interpretationsversuch" der Opcodes (alles Hex): Code:
------------------------------------------------------- PASCAL.IMAGE ------------------------------------------------------- 6B 00 - ? 80 42 - Push 42h (Dos function code number for lseek) 27 - Push file handle 7C - Push block number 25 00 - Push 0 (Origin of move) 91 2A - Execute Function 2A (our block lseek funct) ------------------------------------------------------- 68 00 - ? 80 3F - Push 3Fh (Dos function code number for read) 27 - Push Buffer of data 7C - Push file handle 24 - Push number of bytes to read 91 29 - Execute Function 29 (Do INT21h with params) ------------------------------------------------------- 68 23 - ? D4 - ? 09 - Return ------------------------------------------------------- SS.IMG ------------------------------------------------------- 20 00 B3 F1 05 01 ... von PASCAL.IMAGE an, so handelt es sich vermutlich um die UCSD Pascal BlockRead-Funktion: Code:
FUNCTION BLOCKREAD(FILEID: FILE, ARRAY, BLOCKS: INTEGER, [ RELBLOCK: INTEGER] ): INTEGER; Sieht man sich die Adresse der Schreiboperationen beim Datenfile über die 32MB-Grenze hinaus an, so wird man feststellen, dass beim .DF dort dieselbe BlockWrite-Funktion verwendet wird, womit man dort eben genauso in das Limit hineinläuft. Sieht man sich nun einen Trace von OpenAccess IV an derselben Stelle an und überprüft mit einem Debugger auch noch die aufgerufenen Funktionen, so sieht man, dass die BlockRead / BlockWrite Funktionen hier scheinbar nicht mehr verwendet werden, sondern welche, die diese Limitierung nicht mehr haben: Code:
26C4:23AE lseek(8, 33547588, 0) = 33547588 26C4:2257 lseek(8, 33550336, 0) = 33550336 26C4:239D read(8, 935F:0000, 2048) = 2048 26C4:23AE lseek(8, 33552384, 0) = 33552384 4656:148A lseek(7, 21398528, 0) = 21398528 4656:10B2 read(7, 29E6:3F82, 4096) = 4096 4656:148A lseek(7, 0, 1) = 21402624 26C4:2257 lseek(8, 33550336, 0) = 33550336 26C4:239D write(8, 935F:0000, 2020) = 2020 26C4:23AE lseek(8, 33552356, 0) = 33552356 4656:148A lseek(8, 33556480, 0) = 33556480 4656:10B2 write(8, 29E6:FCBA, 0) = 0 4656:148A lseek(8, 0, 2) = 33556480 Lg. |
|
|
|
|
|
#9 |
|
Registrierter Benutzer
|
Du bist wirklich ein absoluter Profi - danke für die Klärung! Bleibt wirklich nur OA4.
Gruß und schönen Sonntag Hans Jürgen |
|
|
|
Antwort schreiben... |
| Themen-Optionen | Thema durchsuchen |
|
|
Ähnliche Themen
|
||||
| Thema | Autor | Forum | Antworten | Letzter Beitrag |
| Nützliche Tips (Ergänzungen zum Handbuch von Heinz Richartz) | waldbauer.com | SPI OA4 Open Access II/III/IV (2,3,4) Anwender Forum | 204 | 08.11.2012 14:11 |