ooalbert
Goto Top

SQL Server - Logging verhindern oder stark minimieren?

Hallo,

ich hab den SQL Server 2008 und habe dort eine Datenbank mit einer Tabelle die sehr viele Datensätze enthält.

Ich importiere die Daten über einen Bulk Insert und nutzte das Kommando "Tablock", das führt dazu, das der Import in wenigen Minuten beendet ist und sich das Log nur unwesentlich vergrößert.
Ist der importiert beendet füge ich eine Auto-Id Spalte an die Tabelle an über "Alter Table". Dafür kann ich kein Tablock benutzen und die Zeit bis die Spalte erstellt ist mit den IDs bewegt sich etwa um die 15min und das Log quillt unheimlich (2GB Tabelle, 15GB Log) auf.

Hab ich irgendeine Chance das zu unterbinden, da die Aktionen keinesfalls rückgängig gemacht werden müssten, was ein Logging erübrigt.

Für das Löschen der Tabelleninhalte hatte ich zwischenzeitlich "TRUNCATE TABLE" gefunden aber das ist auch nicht immer einsetzbar, das ebenfalls kaum Log Daten erzeugt.

Das Wiederherstellungsmodell ist übrigens auf "Einfach" gesetzt.

Grüße

Content-Key: 179770

Url: https://administrator.de/contentid/179770

Printed on: April 26, 2024 at 23:04 o'clock

Member: Logan000
Logan000 Jan 30, 2012 at 13:03:04 (UTC)
Goto Top
Moin Moin

Das Wiederherstellungsmodell ist übrigens auf "Einfach" gesetzt.
Soweit ich mich erinnere bewirkt lediglich das Wiederherstellungsmodell "Massenprotokolliert" ein geringeres Transaktionsprotokoll aufkommen.

Aber warum die Mühe. Nach Vollsicherung und gegebenenfalls einen geschickten Wartungsplan hat sich das Problem doch erledigt.

Gruß L.
Member: ooAlbert
ooAlbert Jan 30, 2012 at 13:11:05 (UTC)
Goto Top
Nun je nach dem was man da tut explodiert das Log und die Anweisung wird nicht ausgeführt. Außerdem dauern die Anweisungen viel zu lange durch die ganze Protokoliererei. Beispielsweise hat ein "Delete" auf die Tabelle dazugeführt, das aus den 2GB Daten 50G Log gezaubert wurden und das ganze ca. 90min gedauert hat bis die Tabelleninhalte gelöscht waren. Das ist natürlich sinnfrei.
Der "TRUNCATE TABLE" Befehl hat dazu 1 Sekunde benötigt und keine erkennbare Vergrößerung des Logs verursacht.

Das andere Wiederherstellungsprofil hat zwar etwas weniger benötigt wie der vollständige Wiederherstellungsmodus aber immer noch viel merh als der Einfache.
Member: Pjordorf
Pjordorf Jan 30, 2012 at 15:52:03 (UTC)
Goto Top
Hallo,

Zitat von @ooAlbert:
Nun je nach dem was man da tut explodiert das Log und die Anweisung wird nicht ausgeführt.
Das das Log größer wird ist OK. Aber das die Anweisung nicht ausgeführt wird?!? Was willst du hier sagen?

Beispielsweise hat ein "Delete" auf die Tabelle dazugeführt, das aus den 2GB Daten 50G Log gezaubert wurden und das ganze ca. 90min gedauert hat bis die Tabelleninhalte gelöscht waren.
Da wir weder deine Datenbank, Tabellen, Aufbau der Datensätze, Relation zueinander, Trigger, Stored Procedures usw. hier nun nicht kennen, was möchtest denn dann von uns hören. Das du uns leid tust?

Der "TRUNCATE TABLE" Befehl hat dazu 1 Sekunde benötigt und keine erkennbare Vergrößerung des Logs verursacht.
Wenn ein Truncate Table = Delete wäre, warum gibt es dann diese zwei vorgehen? Die sind doch grundsätzlich unterschiedleicher Natur und Funktion. Die kannst du nicht miteinader vergleichen.

Wie viele Datensätze ist bei dir "sehr viele Datenätze"? Mehr als 1 Tausend? Mehr als 10 Tausend? Mehr als 100 Tausend? Mehr als 1 Million?

Gruß,
Peter
Member: ooAlbert
ooAlbert Jan 30, 2012 at 16:22:41 (UTC)
Goto Top
Das bedeutet, das das Log den gesamten verfügbaren Speicher auf dem Server einnimmt und es daher zu einem Abbruch der Anweisung kommt.

Die Tabelle hat keinerlei Verweise oder Abhängigkeiten und es handelt sich aktuell um 21 Millionen Datensätze. Die wenn sie drin sind ca. 2GB einnehmen. Nur sobald man die Daten Manipuliert werden unmengen Log Informationen erzeugt, die dann je nach dem alles unheimlich aufhalten oder dazuführen, das aben der Speicher erschöpft ist.

Beispielswesie war ein Bulk Insert ohne Tablock nicht durchführbar, das nachträgliche setzen einer ID Spalte ist wie schon beschreiben ebenfalls sehr grenzwertig. Das hat auch nichts mit der Verfügbaren Rechenleistung zu tun, sondern mit den Protokollen.

Abfragen gehen übrigens recht flott, unter 5 Sekunden.
Member: MadMax
MadMax Jan 30, 2012 at 17:03:49 (UTC)
Goto Top
Hallo ooAlbert,

das Transaktionslog einfach mal bei irgendeinem Befehl ausschalten geht nicht. Aber Du kannst die Identitätsspalte vor dem Import in die Tabelle setzen und dadurch gleich beim bulk insert hochzählen lassen. Das bekommst Du über eine Formatdatei gebacken.

Gruß, Mad Max
Member: Logan000
Logan000 Jan 31, 2012 at 07:53:30 (UTC)
Goto Top
Moin Moin

Das andere Wiederherstellungsprofil hat zwar etwas weniger benötigt wie der vollständige Wiederherstellungsmodus aber immer noch viel merh als der Einfache.
interessant.
Ich habe dein immer noch nicht verstanden was du eigentlich Vorhast bzw. wo genau das Problem liegt.
Du machst scheinbar einen Datenimport. OK soweit.
Du hast dich bereits in die Insert Problematik bei massenimportrn eingelesen (Tablock).
Genau so wie das evtl. Leeren der Tabellen ("TRUNCATE TABLE" um z.B. den Import zu wiederholen).
Wenn ich dich richtig verstehe funktioniert das ja wohl auch wie gewünscht.

das nachträgliche setzen einer ID Spalte ist wie schon beschreiben ebenfalls sehr grenzwertig.
Das hat auch nichts mit der Verfügbaren Rechenleistung zu tun, sondern mit den Protokollen.
Ganz genau. Aber das ist eher ein PEBCAK problem.
Denn das DB design erfolgt immer vor dem Import. Nicht hinterher oder wärend.

Gruß L.
Member: ooAlbert
ooAlbert Jan 31, 2012 at 11:33:54 (UTC)
Goto Top
Das mit der Format Datei hab ich mal ausprobiert, das funktioniert fast Fehlerfrei. Nur steigt der Vorgang bei ca. 1 Mio. Zeilen aus mit dem Fehler:

Meldung 8152, Ebene 16, Status 14, Zeile 5
Zeichenfolgen- oder Binärdaten würden abgeschnitten.

Bis zu der Grenze sind auch keine erkennbaren Fehler in der Tabelle, wenn man den Import da stopt.

Mache ich den Import wie bisher nur ohne ID Spalte, geht das fehlerfrei.

So sieht die Formatdatei übrigens aus:

10.0
11
1 SQLCHAR 0 0 ";" 1 Spalte1 ""
2 SQLCHAR 0 0 ";" 2 Spalte2 ""
3 SQLCHAR 0 0 ";" 3 Spalte3 ""
...
11 SQLCHAR 0 0 "\n" 11 Spalte11 ""


Ich hab auch mal den Bereich der SPlaten an die Tatsächlichen Größen der Datentypen angepasst, selbes Ergebnis.
Member: ooAlbert
ooAlbert Jan 31, 2012 at 16:17:01 (UTC)
Goto Top
So ich hab jetzt den Fehler gefunden, eine Spalte hatte doch ein Zeichen mehr als angegeben und deshalb kam es zum Abbruch mit der Meldung face-smile Deshalb hab ich die Datentypen auf "Max" gestellt und hab dann die Längen der einstelen Werte ausgeben lassen.

Jetzt hätte ich aber mal eine zusätzliche Frage kann ich über den "Insert" direkt schon Indizes erzeugen oder muss das nachher passieren, so mach ich das nämlich momentan?

Beispielswesie: create index idx_sp1 on tab1(sp1);
Member: MadMax
MadMax Jan 31, 2012 at 16:59:38 (UTC)
Goto Top
Hallo ooAlbert,

mit insert fügst Du Zeilen in die Tabelle ein, aber erzeugst keinen Index.

Und das "create index ..." kannst Du vorher oder nachher laufen lassen.

Gruß, Mad Max
Member: ooAlbert
ooAlbert Feb 01, 2012 at 09:55:50 (UTC)
Goto Top
Ich hab jetzt mal das Definieren der Indizes direkt nach dem Create Table gesetzt und dann importiert. Das hat dann 2min länger gedauert als wenn ich es erst nach dem Import definie.
für den SQL Server ist es vermutlich egal wo man das macht face-smile