163 lines
9.3 KiB
Markdown
163 lines
9.3 KiB
Markdown
# Verifikation: isam-transaktionen-und-dateinummern
|
||
|
||
Nachprüfung am 05.09.2026, aktueller uncommitteter Arbeitsbaum auf `19804e0`.
|
||
Geprüft: Proposal, Design, Tasks, Delta-Specs, betroffene Hauptspec-Verträge,
|
||
Implementierung, Regressionstests und ursprüngliche Fehlerreproduktionen.
|
||
|
||
**Schlussabnahme: V01–V05 behoben und nachgeprüft. Keine offenen Befunde.
|
||
Die Hauptspecs sind synchronisiert; alle 11 Tasks sind abgeschlossen.**
|
||
|
||
| Dimension | Ergebnis |
|
||
|---|---|
|
||
| Vollständigkeit | 11/11 Tasks abgeschlossen |
|
||
| Korrektheit | 4 Anforderungen, 20 Szenarien zugeordnet; Neuanlage über Symlink zusätzlich abgesichert |
|
||
| Kohärenz | D1–D3 eingehalten; Dokumentation und Delta-Specs um die Korrekturen ergänzt |
|
||
| Befunde | 0 offen; V01–V05 behoben |
|
||
|
||
## V05 — Neuanlage über einen Symlink: behoben
|
||
|
||
**Vorher:** Bei `alias.db → target.db` mit noch fehlender Zieldatei gelang
|
||
das erste OPEN; das zweite OPEN derselben Datei meldete Fehler 88. Die erste
|
||
Anlage speicherte den Alias als Cache-Schlüssel, die nächste Auflösung ergab
|
||
den Zielpfad.
|
||
|
||
**Korrektur:** `db_oeffnen` bestimmt nach erfolgreicher Dateianlage die
|
||
endgültige kanonische Identität, speichert den Datenbankhandle darunter und
|
||
gibt diesen Pfad an OPEN beziehungsweise DELETETABLE zurück. Bindungen,
|
||
Transaktionen und Undo verwenden damit von Anfang an den Zielpfad.
|
||
|
||
**Nachweise:**
|
||
|
||
- `symlink_neuanlage_behaelt_die_dateiidentitaet` in
|
||
[isam/tests.rs](../../../../crates/tb-runtime/src/isam/tests.rs): relative und
|
||
absolute Symlinkziele, erneutes OPEN über Alias und Ziel, gemeinsamer
|
||
Transaktionsbestand, DELETETABLE über Alias, Sicherungspunkt-Rücknahme,
|
||
ROLLBACK ALL und persistierter Ausgangsbestand nach erneutem Öffnen.
|
||
- Ursprüngliche CLI-Reproduktion in einem frischen temporären Verzeichnis,
|
||
mit fünf Sekunden Frist: beide zusätzlichen Bindungen sehen einen Satz;
|
||
nach ROLLBACK ALL liefert LOF den Wert 0. Prozessstatus 0, keine Fehler 88/52.
|
||
- Vollständige Workspace-Suite: **391 bestanden, 0 fehlgeschlagen,
|
||
1 bewusst ignoriert**. Davon 135 Runtime-Tests und 16 aktive CLI-Korpus-/Harness-Tests.
|
||
|
||
## V01 — Datenbankidentität: behoben
|
||
|
||
**Vorher:** Nach CLOSE und CHDIR konnte OPEN mit demselben relativen Namen
|
||
in die alte Datei schreiben. OPEN über `./db` erkannte eine bereits laufende
|
||
Transaktion derselben Datei nicht und meldete Fehler 88.
|
||
|
||
**Korrektur:** [datenbank_pfad](../../../../crates/tb-runtime/src/isam.rs#L1560)
|
||
löst vorhandene Dateien kanonisch auf. Bei neuen Dateien wird ihr vorhandener
|
||
Elternpfad kanonisiert. OPEN und DELETETABLE verwenden diesen Schlüssel
|
||
durchgängig für Datenbanken, Transaktionen, Bindungen und Rücknahme.
|
||
|
||
**Nachweise:**
|
||
|
||
- [isamidentitaet.bas](../../../../tests/compat/isamidentitaet.bas): Nach Wechsel
|
||
von a nach b ist die zweite Datenbank leer; der Alias `./db` sieht innerhalb
|
||
einer Transaktion den gleichen Bestand. DELETETABLE über `../a/db` und
|
||
Rücknahme funktionieren ebenfalls.
|
||
- [pfadaliase_teilen_transaktion_und_ruecknahme](../../../../crates/tb-runtime/src/isam/tests.rs#L696):
|
||
absolute Pfade mit `..` und auf Unix auch ein Symlink teilen denselben Writer.
|
||
- Separate CLI-Prozesse lesen anschließend genau einen Satz mit Nr=1 aus
|
||
`a/db` und einen Satz mit Nr=2 aus `b/db`. Beide Dateien existieren.
|
||
|
||
## V02 — Prozessfristen: behoben
|
||
|
||
**Vorher:** Nur der besondere CLI-Unterprozess war geschützt; die direkten
|
||
ISAM-Aufrufe im Korpustest und in Runtime-Tests konnten weiterhin hängen.
|
||
|
||
**Korrektur:** [Prozessfrist](../../../../tests/support/prozessfrist.rs) überwacht
|
||
jeden Runtime-Datenbanktest über dessen TempDb sowie jeden Aufruf von
|
||
[run_corpus_file](../../../../crates/tb-cli/tests/compat.rs#L359), einschließlich
|
||
beider Korpusdurchläufe und des bewusst ignorierten Golden-Generators.
|
||
Nach 30 Sekunden beendet ein unabhängiger Watchdog den gesamten betroffenen
|
||
Testprozess mit Status 124. Beim regulären Abschluss wird die Frist aufgehoben.
|
||
Der spezielle CLI-Unterprozess behält seine eigene Fünf-Sekunden-Frist.
|
||
|
||
**Nachweis:** `frist_beendet_blockierten_testprozess` startet einen Kind-Test,
|
||
der absichtlich unbegrenzt blockiert. Dessen Watchdog beendet ihn mit Status 124
|
||
und benannter Fehlermeldung; der Elternprozess prüft beides und besitzt zusätzlich
|
||
eine unabhängige Fünf-Sekunden-Kill-Frist. Dieser Test besteht sowohl im Runtime-
|
||
als auch im CLI-Testbinary. Keine Änderung am Produktcode zur Simulation nötig.
|
||
|
||
## V03 — Bindungen nach DELETETABLE: behoben
|
||
|
||
**Vorher:** Ein alter Handle konnte nach DELETETABLE unbemerkt eine interne
|
||
Satztabelle ohne Layoutmetadaten wieder anlegen.
|
||
|
||
**Korrektur:** [tabelle_loeschen](../../../../crates/tb-runtime/src/isam.rs#L988)
|
||
löst nach erfolgreicher Löschung alle Bindungen genau dieser Tabelle und
|
||
Datenbank. Eine Rücknahme stellt den Bestand wieder her, öffnet aber keine
|
||
zuvor geschlossenen Bindungen. Ein neues OPEN bindet den restaurierten Bestand.
|
||
|
||
**Nachweise:**
|
||
|
||
- [deletetable_loest_alle_betroffenen_bindungen](../../../../crates/tb-runtime/src/isam/tests.rs#L725):
|
||
Beide alten Handles melden Fehler 52, eine andere Tabelle bleibt gebunden.
|
||
Rücknahme und Wiederöffnung stellen Sätze und eindeutigen Index wieder her.
|
||
Erneute Löschung und Neuanlage ergeben eine leere Tabelle ohne alten Index.
|
||
- Die ursprüngliche CLI-Reproduktion meldet jetzt Fehler 52 beim INSERT über
|
||
die alte Nummer und LOF=0 nach Neuanlage. RETRIEVE auf der leeren Tabelle
|
||
meldet erwartungsgemäß Fehler 85; es gibt keinen Geistersatz.
|
||
|
||
## V04 — DELETE bei ausgeschöpftem Puffer: behoben
|
||
|
||
**Vorher:** DELETE speicherte Undo und entfernte den Satz trotz Puffergröße 0.
|
||
|
||
**Korrektur:** [satz_loeschen](../../../../crates/tb-runtime/src/isam.rs#L1123)
|
||
prüft die alten Satzbytes gegen den noch verfügbaren Puffer, bevor Satz oder
|
||
Indizes verändert beziehungsweise Undo hinzugefügt werden.
|
||
|
||
**Nachweise:**
|
||
|
||
- [delete_pufferfehler_erhaelt_saetze_indizes_und_cursor](../../../../crates/tb-runtime/src/isam/tests.rs#L760):
|
||
Fehler 89 außerhalb und innerhalb einer Transaktion lässt Bestand, aktiven
|
||
Index, Cursor und Undo unverändert. Bei exakt passender Größe gelingt ein
|
||
DELETE; der nächste scheitert ohne Änderung. Rücknahme restauriert beide
|
||
Sätze und gibt den Puffer wieder frei.
|
||
- Ursprüngliche CLI-Reproduktion: `free=0`, `ERR=89`, `LOF=1`, `restored=1`.
|
||
|
||
## Szenarionachweise
|
||
|
||
| Delta-Szenario | Nachweis |
|
||
|---|---|
|
||
| Sequenzielles Schreiben und Lesen | `tests/compat/dateien.bas` |
|
||
| Doppeltes Öffnen derselben Nummer | `isamdateinummern.bas`: Fehler 55 in beiden Richtungen |
|
||
| Freie Dateinummer | `isamdateinummern.bas`: gemischte Modi und wiederbelegte Lücken |
|
||
| ISAM belegt eine Dateinummer | `isamdateinummern.bas`: FREEFILE=2 |
|
||
| Gleicher relativer Name nach Verzeichniswechsel | `isamidentitaet.bas` und separate Persistenzprüfung |
|
||
| Neuanlage über einen noch nicht auflösbaren Symlink | `symlink_neuanlage_behaelt_die_dateiidentitaet` und CLI-Reproduktion |
|
||
| Pfadalias in einer Transaktion | `isamidentitaet.bas`, Runtime-Pfadaliastest |
|
||
| Bindungen nach Tabellenlöschung und Rücknahme | Runtime-DELETETABLE-Bindungstest |
|
||
| Tabelle wird beim ersten Öffnen angelegt | `isamtabellen.bas` |
|
||
| Abweichendes Satzlayout | `isamtabellen.bas`: Fehler 88 |
|
||
| CLOSE lässt eine laufende Transaktion stehen | `close_beendet_keine_transaktion`, `isamopen.bas` |
|
||
| Entfernte Tabelle | `isamtabellen.bas`, `isamopen.bas`: Fehler 82 |
|
||
| Weitere Tabelle während einer Transaktion | `isamopen.bas` und CLI-Test mit Prozessfrist |
|
||
| Rücknahme stellt den Bestand wieder her | CLI-Probe der Erstprüfung: INSERT/DELETE und bare ROLLBACK ergeben LOF=1 und LOC=0; Rücknahmepfad unverändert |
|
||
| Rücknahme auf einen Sicherungspunkt | `isamtrans.bas`, `isamstruktur.bas`, Runtime-Strukturtests |
|
||
| ROLLBACK ALL beendet die Transaktion | `isamtrans.bas`; CLI-Probe der Erstprüfung mit zwei Savepoints und anschließendem Fehler 5 |
|
||
| Indexanlage nach Sicherungspunkt | `isamstruktur.bas`: Fehler 83; Runtime-Strukturtests |
|
||
| Geschlossene Tabelle rücknehmen | `isamstruktur.bas`, Runtime-Tests für CLOSE und Struktur-Rücknahme |
|
||
| Pufferfehler wird benannt | `isampuffer.bas`, `struktur_undo_prueft_puffer_vor_dem_loeschen` |
|
||
| DELETE bei ausgeschöpftem Puffer | Neuer Runtime-DELETE-Puffertest und ursprüngliche CLI-Reproduktion |
|
||
|
||
## Prüfungen einschließlich erneuter Verifikation
|
||
|
||
- `cargo test -p tb-runtime --quiet`: 135 bestanden.
|
||
- `cargo test -p tb-cli --test compat --quiet`: 16 bestanden, Golden-Generator ignoriert.
|
||
- Erneut `cargo test --workspace --quiet`: **391 bestanden, 0 fehlgeschlagen,
|
||
1 bewusst ignoriert**; einschließlich beider Watchdog-Selbsttests.
|
||
- Formatprüfung aller geänderten Rust-Dateien und des neuen Testhelfers bestanden.
|
||
- `git diff --check` und Whitespace-Prüfung der neuen Dateien bestanden.
|
||
- `openspec validate isam-transaktionen-und-dateinummern --strict`: bestanden.
|
||
- Ursprüngliche Reproduktionen und positive Zusatzproben erneut ausgeführt:
|
||
Index-Neuanlage mit geändertem Aufbau und Rücknahme, RESET/COMMIT,
|
||
Rücknahme über zwei Datenbankdateien, Programmende ohne COMMIT sowie
|
||
Persistenz über neue CLI-Prozesse. Alle externen Proben mit fünf Sekunden Frist.
|
||
|
||
Keine GUI-, Windows-/Linux-Abnahme, Speichererschöpfung oder simulierten
|
||
redb-I/O-Ausfälle ausgeführt. Keine neue Abhängigkeit, kein neues Datenbankformat.
|
||
Die vier geänderten Anforderungen wurden in die Hauptspecs datei-eio und
|
||
isam-datenbank synchronisiert; alle 15 Hauptspecs bestehen die strikte Validierung.
|