Warum erhöht sich @@ dbts nach dem Sichern / Wiederherstellen?

7

Ich habe eine SQL Server 2005-Datenbank, die einige Tabellen enthält, die eine Timestamp- (oder RowVersion-) Spalte haben. Ich muss den Wert des aktuellen Zeitstempels kennen, daher verwende ich die folgende Abfrage:SELECT CAST(@@dbts AS BIGINT);

Dies gibt beispielsweise 10505 zurück .

Unmittelbar danach, ohne zu aktualisieren, einzufügen, ... irgendetwas, mache ich a BACKUP DATABASEund a RESTORE DATABASEund führe die SELECTAbfrage erneut aus. Nur dieses Mal ist das Ergebnis 14000 , während keiner der Zeitstempel in den Tabellen erhöht wurde.

Warum / wie passiert das?

Stijn
quelle
Microsoft garantiert nur, dass @@ DBTS eindeutig ist . Es gibt keine Zusagen darüber, was mit dem Wert nach einer Sicherung / Wiederherstellung oder einer anderen Operation auf Datenbankebene geschehen kann oder nicht. Wofür verwenden Sie diesen Wert? Warum kümmert es dich, wenn es sich ändert? Können Sie Ihre Baseline nach der letzten erfolgreichen Wiederherstellung nicht festlegen und jederzeit zurücksetzen? Es ist nicht so, dass eine Produktionsdatenbank diese Sequenz sehr oft durchlaufen sollte ...
Aaron Bertrand

Antworten:

13

Der Wert für dbi_maxDbTimestampwird auf der Datenbankstartseite gespeichert. (Seite 9 in der Primärdatendatei).

Dies wird nicht jedes Mal geschrieben, wenn ein Zeitstempelwert zugewiesen wird. Stattdessen reserviert SQL Server jeweils einige Tausend.

Wenn beispielsweise @@DBTSis 2000und the dbi_maxDbTimestampis ist, 2000aktualisiert SQL Server den auf der Startseite geschriebenen Wert auf 6000das nächste Mal, wenn ein Zeitstempelwert benötigt wird.

Die Werte von 2001 - 5999werden im Speicher zugewiesen und "verloren", wenn die Datenbank offline und dann wieder online gesetzt wird.

Die Sicherung enthält die Kopie der Startseite, auf die aktualisiert wurde 6000. Nach dem Wiederherstellen beginnen die Zeitstempelwerte mit dieser Zahl. Es weiß nichts über verlorene Zwischenwerte.

Um das zu sehen

CREATE DATABASE DbtsTest

GO

USE DbtsTest

GO

DBCC TRACEON(3604);

CREATE TABLE T (X ROWVERSION)

SELECT CAST(@@dbts AS BIGINT);

DBCC PAGE(DbtsTest,1,9,1)

Auf meinem System für eine neu erstellte Datenbank @@dbtsist 2,000. Die DBCC PAGEAusgabe von oben ist

DBCC Seite 1

Ich habe den Zeitstempelwert hervorgehoben. CAST(CAST(REVERSE(0xD007000000000000) AS BINARY(8)) AS BIGINT)=2000

INSERT INTO T DEFAULT VALUES

SELECT CAST(@@dbts AS BIGINT);
DBCC PAGE(DbtsTest,1,9,1)

Jetzt wird das @@dbtsals 2001aber auf die Seite selbst schauend gemeldet .

DBCC Seite 2

Der Zeitstempelwert hat sich geändert. CAST(CAST(REVERSE(0x7017000000000000) AS BINARY(8)) AS BIGINT)= 6000.

Laufen

DBCC DBTABLE('DbtsTest')

Zu diesem Zeitpunkt zeigt die DBTABLEStruktur beide Werte an

dbt_maxDbTimestamp = 6000           
dbt_dbTimestamp = 2001

Schließlich

BACKUP DATABASE [DbtsTest] TO  
DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQL2012\MSSQL\Backup\DbtsTest.bak' 
WITH NOFORMAT, 
     NOINIT,  
     NAME = N'DbtsTest-Full Database Backup', 
     SKIP, 
     NOREWIND, 
     NOUNLOAD,  
     STATS = 10

Ein Blick auf das Backup zeigt dann, dass es sich um die 6.000-Zahl handelt, die geschrieben wurde.

Geben Sie hier die Bildbeschreibung ein

Das Wiederherstellen der Datenbank und das Abfragen von SELECT CAST(@@DBTS AS BIGINT)Retouren 6,000wie erwartet.

Martin Smith
quelle