Suche/Eine Indexerweiterung für Datenbanken entwickeln, die Tests besteht und Abstürze übersteht

Eine Indexerweiterung für Datenbanken entwickeln, die Tests besteht und Abstürze übersteht

Nutze dies, wenn eine KI eine Datenbank-Indexerweiterung baut oder ändert. Sie nimmt jeden Testfehler ernst, hält vor dem Einchecken eine feste Abfolge ein und protokolliert jede Seitenänderung, damit Wiederherstellung und Standby-Server funktionieren.

Diese KI-Regeln verwenden
## Nach dem Neuinstallieren den Server neu starten und zuerst die Speicherspezifikation lesen Du arbeitest an einer Datenbankerweiterung, die eine Indexzugriffsmethode bereitstellt, gestützt auf eine geschichtete Ablage auf dem Datenträger innerhalb der Relationsdateien der Datenbank selbst. Die Arbeit liegt nahe an Dauerhaftigkeit, Wiederherstellung und Nebenläufigkeit, deshalb wiegt Korrektheit in jeder Abwägung schwerer als die Geschwindigkeit der Auslieferung. Annahmen, die jederzeit gelten: - Die Erweiterung wird beim Start des Servers geladen. Bevor die Erweiterung angelegt werden kann, muss sie in die Konfiguration der vorab geladenen Bibliotheken eingetragen und der Server neu gestartet werden; nach einer erneuten Installation des übersetzten Programms während der Entwicklung ist ein weiterer Neustart nötig. Ein veraltetes geladenes Programm liefert irreführende Testergebnisse; widerspricht das Verhalten dem gerade übersetzten Quelltext, verdächtige zuerst einen ausgelassenen Neustart. - Installiere die Objekte der Erweiterung in ein eigenes Schema statt in den voreingestellten öffentlichen Namensraum, wann immer das Projekt es zulässt, damit der Namensraum sauber bleibt. - Bevorzuge die kleinste Änderung, die das Problem vollständig löst. Baue benachbarten Quelltext nicht um, wenn die Aufgabe es nicht verlangt. - Entwurfsspezifikationen im Projektarchiv sind bindend. Lies die Speicherspezifikation, bevor du den Schreibweg, den Leseweg oder den Auslagerungsweg anfasst, und aktualisiere die Spezifikation in derselben Änderung, sobald sich der Entwurf selbst verschiebt. ## Jeden Testfehler untersuchen, statt ihn als unabhängig abzutun Der Hauptzweig bleibt durchgehend grün. Jeder fehlgeschlagene Test ist von Bedeutung. - Tue einen Fehlschlag niemals als bereits vorhanden oder als nicht zugehörig ab. In der Praxis ist er das fast nie. - Wenn du ernsthaft glaubst, ein Fehlschlag habe nichts mit deiner Änderung zu tun, weise das nach: wechsle auf den Hauptzweig und führe denselben Test dort aus. - Dass sich der Fehlschlag auf dem Hauptzweig wiederholen lässt, entschuldigt ihn nicht. Er muss trotzdem untersucht und behoben werden, statt abgelegt oder als bekannt vermerkt zu werden. - Markiere niemals einen Test als übersprungen, lockere niemals eine Zusicherung und ändere niemals eine Datei mit erwarteter Ausgabe, nur damit ein roter Lauf grün wird. Ändere eine Erwartung erst, wenn du genau benennen kannst, warum die neue Ausgabe richtig ist. - Melde Fehlschläge ehrlich und früh, auch die von dir verursachten. Einen roten Lauf zu verschweigen ist schlimmer als der Fehler selbst. ## Vor jedem Einchecken die Regressionstests ausführen und die Differenzdatei lesen Führe jeden der folgenden Schritte aus, bevor du eine Änderung eincheckst. Ordne die Schritte nicht um und lasse keinen aus, weil eine Änderung „belanglos aussieht“. 1. Übersetze die Erweiterung. 2. Führe die beschreibende Regressionstestreihe gegen eine installierte Fassung aus. 3. Sieh dir die vom Lauf erzeugte Datei mit den Regressionsunterschieden an, nicht nur die Zusammenfassung mit bestanden oder gescheitert. Eine Testreihe kann Erfolg melden und dabei einen von dir eingeschleppten Unterschied verdecken. 4. Hast du eine für Anwender sichtbare Meldung geändert, passe die zugehörigen Dateien mit erwarteter Ausgabe entsprechend an und begründe im Eincheckvermerk, warum sich die Meldung geändert hat. 5. Führe die Formatprüfung aus. 6. Führe die Regressionstestreihe nach dem Anpassen einer Erwartungsdatei erneut aus, damit der zuletzt aufgezeichnete Lauf dem eingecheckten Stand entspricht. Über die übliche Testreihe hinaus führe die Stufen für Nebenläufigkeit, Wiederherstellung nach Absturz, mehrere Serverprozesse und Dauerbelastung immer dann aus, wenn eine Änderung Sperren, den Schreibweg, die Wiederherstellung oder den Lebenszyklus von Segmenten berührt. Sage klar, welche Stufen du ausgeführt hast und welche nicht. ## Jede Änderung in der untersten Codeschicht ablegen, die das Problem löst Der Quelltext ist in Schichten gegliedert, und jede Änderung gehört in die unterste Schicht, die sie vollständig löst. Lass keine Einzelheiten der Ablage nach oben in die Datenbankschnittstelle durchsickern und greife nicht an einer Abstraktion vorbei nach unten, um eine Behebung abzukürzen. - Schicht eins, Datenbankschnittstelle: die Behandlungsroutine der Zugriffsmethode, die Einsprungpunkte für Indexaufbau, Durchlauf und Aufräumvorgang; eigene Datentypen; Einhängepunkte des Anfrageplaners und Kostenschätzung. - Schicht zwei, Indexsteuerung: Rangfolge und Bewertung, Optimierung für die besten k Treffer, Lebenszyklus des Indexzustands, Verzeichnis, Behandlung der Metaseite und die Abstraktion über die Trefferquellen. - Schicht drei, Ablage: der Schreibpuffer der Ebene null, unveränderliche Segmente, Zusammenführung und Verdichtung. - Querschnittlich: Werkzeuge zur Fehlersuche und zur Ausgabe innerer Zustände sowie die Initialisierung der Module. Erstreckt sich eine Änderung über mehrere Schichten, beschreibe den Grenzübertritt ausdrücklich in der Änderungsbeschreibung. Eine Behebung, die stillschweigend eine Schnittstelle erweitert, ist eine Entwurfsänderung und muss auch als solche begutachtet werden. ## Vor Änderungen am Speicher Schreibpuffer und unveränderliche Segmente verstehen Der Index folgt einem protokollstrukturierten, geschichteten Ablageansatz. Verstehe das Modell, bevor du irgendeinen Teil davon änderst. - Ebene null ist ein Schreibpuffer: eine anhängend geführte Kette von Seiten, die innerhalb der Indexrelation selbst liegt und an einer Metaseite verankert ist. Schreibvorgänge hängen an die letzte Seite Sätze an, die die Zeilenkennung, eine Länge und gepackte Nutzdaten tragen. Alle Änderungen geschehen unter den üblichen Puffersperren und werden vorausschauend protokolliert. - Segmente sind unveränderliche, blockweise aufgebaute Strukturen auf dem Datenträger, die Sprungeinträge tragen, damit ein Durchlauf zu einem Block springen kann, ohne jeden Treffer abzuschreiten. - Die Auslagerung vom Schreibpuffer in ein neues Segment wird über einen Schwellenwert ausgelöst, und Segmente werden je Ebene verdichtet, sobald sich auf einer Ebene genügend davon angesammelt haben. - Abfragen nach den besten k Treffern nutzen obere Schranken auf Blockebene, sodass Blöcke, die nichts zum Ergebnis beitragen können, vollständig übersprungen werden, mit vorzeitigem Abbruch, sobald die verbleibende Schranke die aktuelle Ergebnismenge nicht mehr schlagen kann. Ein Zwischenspeicher im Arbeitsspeicher darf Lesevorgänge von Abfragen aus Geschwindigkeitsgründen bedienen, doch die dauerhafte Kette auf dem Datenträger bleibt die einzige verbindliche Quelle, und nur lesende Bereitschaftsserver lesen stets die dauerhafte Kette statt eines Zwischenspeichers. ## Jede Seitenänderung über das Standard-Write-Ahead-Log erfassen, nicht über ein eigenes Protokolliere jede Änderung an einer Seite über die allgemeine Einrichtung der Datenbank zur vorausschauenden Protokollierung, statt für die Erweiterung einen eigenen Ressourcenverwalter anzumelden. Warum diese Vorgabe besteht: Mit der allgemeinen Protokollierung baut die mitgelieferte Wiedereinspielung der Datenbank jede Seite bei der Wiederherstellung nach einem Absturz und auf einem fortlaufend versorgten Bereitschaftsserver neu auf, einschließlich der Seiten der Schreibpufferkette, der Segmentseiten und der Metaseite. Genau das ermöglicht es, dass Hilfsmittel zum Wiedereinspielen einzelner Seiten und jeder andere Zusammenhang der Wiedereinspielung, der die gemeinsame Bibliothek der Erweiterung nicht laden kann, richtig arbeiten. Zu beachtende Folgen: - Einen eigenen Ressourcenverwalter einzuführen ist eine große Entwurfsentscheidung und keine Kleinigkeit der Umsetzung. Er zerbricht jeden Zusammenhang der Wiedereinspielung, der die Erweiterung nicht laden kann. Führe ihn niemals beiläufig im Rahmen einer unabhängigen Änderung ein; bringe ihn als eigenen Vorschlag mit eigener Begutachtung ein. - Jede neue Struktur auf dem Datenträger muss allein aus den protokollierten Sätzen durch die mitgelieferte Wiedereinspielung wiederherstellbar sein. Lässt sich eine Struktur nur durch den Quelltext der Erweiterung neu aufbauen, ist der Entwurf falsch. - Umgehe niemals die Pufferverwaltung und schreibe niemals Seiten außerhalb einer protokollierten Änderung, selbst nicht bei einer Struktur, die du für entbehrlich hältst. ## Durch eine Zusammenführung frei gewordene Seiten zurückhalten, bis Abfragen auf Standby-Servern sie nicht mehr lesen Eine Zusammenführung darf die verdrängten Ausgangsseiten nicht sofort an die Freiraumkarte zurückgeben. Auf dem Primärserver ist das gefahrlos, für laufende Leseabfragen auf einem im Lesebetrieb geöffneten Bereitschaftsserver jedoch nicht, denn ohne eigenen Ressourcenverwalter gibt es keinen Weg, Konflikte während der Wiedereinspielung aufzulösen: Der Bereitschaftsserver würde Seiten wiederverwenden, die eine laufende Abfrage noch liest. Das geforderte Muster: - Lege verdrängte Seiten in einer protokollierten Kette von Grabsteinen ab, die an der Metaseite verankert und mit der Transaktionskennung der Zusammenführung gestempelt ist. - Gib abgelegte Seiten erst dann an die Freiraumkarte zurück, wenn ein späterer Aufräumvorgang oder die nächste Zusammenführung feststellt, dass der Stempel vor der ältesten noch nicht entfernbaren Transaktionsgrenze liegt. Diese Grenze ist die für Bereitschaftsserver sichere Schwelle der Rückgewinnung. - Verlange, dass in der Installation die Rückmeldung der im Lesebetrieb geöffneten Bereitschaftsserver eingeschaltet ist. Deren ältester Schnappschuss hält die Grenze des Primärservers dann so lange zurück, bis sie das Lesen der abgelegten Seiten beendet haben. - Stelle eine Diagnosefunktion bereit, die meldet, wie viele Seiten gerade abgelegt sind, damit Betreiber das Anwachsen des Rückstaus beobachten können, statt zu raten. Verallgemeinere das Prinzip: Wenn ein Bestandteil eine gemeinsam genutzte Ressource freigibt, die ein entfernter oder verzögerter Leser noch halten könnte, verschiebe die Freigabe hinter eine beobachtbare Grenze und gib den Betreibern ein Mittel, die aufgeschobene Menge zu messen. ## Nach dem Bewertungswert sortieren, statt danach zu filtern Bewertungswerte dienen der Sortierung, nicht der Filterung. Ihre Zahlenwerte sind undurchsichtig und tragen keinen sinnvollen Schwellenwert, deshalb ist der Vergleich eines Bewertungswertes mit einer Konstanten ein Fehlmuster, sobald er in Tests, Beispielen oder der Dokumentation als bequeme Filterung eingesetzt wird. Regeln: - Schreibe keine Filterbedingung, die einen Bewertungswert mit einer Zahl vergleicht, um „passende“ Zeilen auszuwählen. - Eine Filterbedingung, die den Bewertungsoperator enthält, löst eine eigenständige Bewertung über einen vollständigen Tabellendurchlauf statt über einen Indexdurchlauf aus. Indexdurchläufe setzen eine Sortierklausel voraus. - Das richtige Muster ist, nach dem Bewertungsausdruck zu sortieren und eine Obergrenze für die Zeilenzahl anzugeben. - Um passende Dokumente zu zählen, umschließe eine sortierte Unterabfrage und zähle deren Zeilen, statt nach dem Bewertungswert zu filtern. - Ausnahme: Ein Test, dessen ausdrückliches Ziel der Weg der eigenständigen Bewertung ist, etwa einer, der Ergebnisse eines Indexdurchlaufs mit eigenständig berechneten Ergebnissen vergleicht, darf den Operator in einer Filterbedingung verwenden. Solche Tests müssen diese Absicht in einem Kommentar festhalten, damit ein späterer Leser das Muster nicht versehentlich übernimmt. Die allgemeine Lehre: Hat eine Schnittstelle genau eine vorgesehene Form, dann mache die falsche Form in jedem ausgelieferten Beispiel sichtbar falsch und lasse Ausnahmen nur mit dokumentierter Absicht zu. ## Jede Einstellung mit sicherem Standardwert in einer Tabelle dokumentieren Jede zur Laufzeit einstellbare Größe ist in einer einzigen Tabelle mit Name, Beschreibung und Voreinstellung dokumentiert. Eine undokumentierte Stellgröße gilt als Mangel. - Wähle Voreinstellungen, die für eine gewöhnliche Installation gefahrlos und verhaltensneutral sind. Verwende die Null für „abgeschaltet“ bei Einstellungen mit Schwellenwert und für „unbegrenzt“ bei Einstellungen mit Budgetcharakter, und sage das in der Beschreibung. - Einstellungen, die Störungen einschleusen oder Fehlschläge erzwingen, gibt es allein zum Testen, sie müssen auf besonders berechtigte Benutzer beschränkt sein und in ihrer Beschreibung als reine Testeinstellung gekennzeichnet werden. - Schalter zur Protokollierung von Bewertungsdetails, Optimierungsstatistiken und Ergebnissen des Zwischenspeichers sind voreingestellt aus; sie sind Hilfen zur Diagnose, nicht Teil des Normalbetriebs. - Speicherbudgets sind gestuft statt eine einzige harte Mauer: Eine weiche Obergrenze je Index führt diesen Index auf den dauerhaften Ausweichweg zurück, eine weiche Obergrenze über alles verdrängt den größten Verbraucher außer dem Aufrufer, und eine harte Obergrenze über alles verweigert neue Zuteilungen rundweg. Jede Stufe muss in den Protokollen beobachtbar sein. - Optionen auf Indexebene, etwa die Konfiguration der Textanalyse sowie die Werte für Sättigung und Längennormierung des Bewertungsmodells, werden mit derselben Sorgfalt dokumentiert, und erforderliche Optionen werden als erforderlich gekennzeichnet, statt ihnen eine stille Voreinstellung zu geben. ## Tote Dokumente markieren und festhalten, dass die Statistik bis zur nächsten Zusammenführung veraltet ist Der Aufräumvorgang kennzeichnet tote Dokumente in einem Bitfeld der lebenden Dokumente je Segment, ein Bit je Dokument, statt das Segment neu aufzubauen. Der Aufwand richtet sich nach der Zahl der toten Dokumente und nicht nach dem gesamten Bestand. Tote Dokumente werden bei der Bewertung herausgefiltert und bei der nächsten Zusammenführung der Segmente körperlich entfernt. Der bekannte Zielkonflikt muss dokumentiert bleiben statt verborgen zu werden: Das Kennzeichnen von Dokumenten als tot aktualisiert weder die Gesamtzahl der Dokumente eines Segments noch die Statistik zur Gesamtlänge noch die Dokumenthäufigkeit je Begriff. Die Rangfolge stützt sich daher auf leicht veraltete Bestandsstatistiken, bis die nächste Zusammenführung oder Verdichtung sie berichtigt. Bei wenigen Löschungen ist die Wirkung vernachlässigbar; eine Massenlöschung kann die Güte der Rangfolge bis zur nächsten Zusammenführung sichtbar beeinträchtigen. Nimm das als Vorlage. Wenn eine Optimierung Genauigkeit oder Aktualität gegen Aufwand eintauscht, schreibe den Zielkonflikt dort nieder, wo die betreuende Person ihn findet, nenne die Bedingungen, unter denen er bedeutsam wird, und benenne das Ereignis, das ihn auflöst. Aus einer undokumentierten Näherung wird später ein unerklärlicher Fehlerbericht. ## Getrennte Teststufen und eingebaute Diagnosefunktionen pflegen Halte klar getrennte Teststufen vor und wisse, was jede davon schützt: - Beschreibende Regressionstests für die Kernfunktionen, die Richtigkeit der Bewertung, Ablage und Segmente, die Wege der Abfrageoptimierung, Tabellenspielarten wie aufgeteilte und vererbte Tabellen sowie Grenzfälle, mit Vergleichsausgaben unter Versionsverwaltung. - Über Skripte gesteuerte Tests für Nebenläufigkeit über mehrere Sitzungen, Wiederherstellung nach Absturz, das Verhalten von Segmenten bei mehreren Serverprozessen und lang laufende Dauerbelastung. Die fortlaufende Integrationsprüfung deckt jede unterstützte Hauptversion der Datenbank ab, dazu Übersetzungen mit Laufzeitprüfern, die Prüfung der Formatierung, Tests der Versionsaktualisierung, die Paketierung für Veröffentlichungen, Leistungsmessungen sowie einen nächtlichen Dauerlauf mit Erkennung von Speicherlecks. Liefere Diagnose als vollwertige Funktionen aus, nicht als beiläufige Ausgaben: Gib die innere Struktur mit ihrem Begriffswörterbuch, ihren Trefferlisten und ihren Dokumenteinträgen aus; schreibe den vollständigen Index in eine Datei; fasse übergeordnete Statistiken zusammen; erzwinge eine Auslagerung und melde, wie viele Einträge verschoben wurden; melde die Zahl der abgelegten Seiten; und stelle den Aufbau einer Seite bildlich dar. Halte Leistungsmessungen wiederholbar: eine kleine klassische Sammlung aus der Informationsrückgewinnung für ein schnelles Signal, größere öffentliche Datenbestände für den Maßstab, ein Skript zur Belastung von Speicher und Kapazität sowie einen Vergleich mit einer etablierten fremden Suchmaschine, um zu bestätigen, dass die Ergebnisse nicht bloß in sich stimmig sind. ## Den automatischen Formatierer nutzen und vor dem Push auf main rebasen - Die Formatierung ist automatisiert. Stelle Befehle bereit und benutze sie, um den gesamten Baum zu formatieren, die Formatierung ohne Änderung zu prüfen, die Unterschiede anzuzeigen und eine einzelne Datei zu formatieren. Formatiere niemals von Hand gegen das Werkzeug. - Folge den Schreibgewohnheiten und den Mustern der Speicherzuteilung des zugrunde liegenden Datenbankprojekts, statt eigene zu erfinden, und brich Zeilen an der im Projekt festgelegten Breite um. - Zusicherungen zur Nebenläufigkeit: Jede gemeinsam genutzte Struktur ist durch eine passende Sperre geschützt, Strukturen zur Vereinheitlichung von Werten werden über Sperren der Streuwerttabelle abgesichert, und die Abgrenzung der Transaktionen wird durch diszipliniertes Aufräumen sowohl beim Bestätigen als auch beim Abbrechen gewahrt. - Nachdem ein Änderungsantrag zusammengeführt wurde, prüfe stets, ob sich der Hauptzweig bewegt hat, auch wenn jemand anders die Zusammenführung vorgenommen hat. Hole den neuen Stand und setze aktive Zweige auf den aktualisierten Hauptzweig neu auf, damit sich keine Konflikte anhäufen. - Vergewissere dich vor dem Hochladen, dass der Zweig auf dem Stand des Hauptzweigs ist, damit auseinandergelaufene Verläufe aus einer kleinen Änderung keine konfliktreiche Zusammenführung machen. - Folge dem dokumentierten Veröffentlichungsverfahren des Projektarchivs, statt Markierungen oder Erzeugnisse aus dem Stegreif zu erstellen.