Ich habe einige Tests in der SQL-Datenbank ausgeführt und mindestens eine neue Operation entdeckt, die ONLINE = ON
unterstützt . Dies ist übrigens eine sehr aktuelle Version – SELECT @@VERSION;
ergibt weiterhin eine alte Build-Nummer, aber der Beweis liegt im Build-Datum:
12. Februar 2015 00:53:13
Copyright (c) Microsoft Corporation
Diese Version von Azure SQL-Datenbank unterstützt ONLINE = ON
Option für ALTER TABLE ... ALTER COLUMN
.
Angenommen, Sie haben eine Tabelle mit einer Spalte, die Nullwerte zulässt:
CREATE TABLE dbo.a(id INT PRIMARY KEY, x VARCHAR(255)); INSERT dbo.a(id, x) SELECT TOP (1) [object_id], name FROM sys.all_objects;
Und jetzt entscheiden Sie sich, diese Spalte nicht nullfähig zu machen, Sie können dies tun (vorausgesetzt, es gibt keine NULL
s):
ALTER TABLE dbo.a ALTER COLUMN x VARCHAR(255) NOT NULL WITH (ONLINE = ON);
Sie können auch Dinge wie die Sortierung, den Datentyp oder die Größe der Spalte ändern:
ALTER TABLE dbo.a ALTER COLUMN x NVARCHAR(510) -- changed data type and length COLLATE Albanian_BIN NOT NULL -- changed collation and nullability WITH (ONLINE = ON);
In aktuellen Versionen von SQL Server (und früheren Versionen von Azure SQL-Datenbank) ist ONLINE = ON
Hinweis wurde für ALTER TABLE
nicht unterstützt , und ohne die Option war dies ein Blockierungs- und Datengrößenvorgang. Um fair zu sein, als ich den Code zum ersten Mal ausgeführt habe, konnte ich nur beweisen, dass die Version mit ONLINE = ON
lief erfolgreich, nicht dass es wie angekündigt funktionierte.
Ich habe diesen Code mit ONLINE = ON
ausgeführt und ohne:
CREATE TABLE dbo.a(id INT PRIMARY KEY, x VARCHAR(255)); INSERT dbo.a(id, x) SELECT TOP (1) [object_id], name FROM sys.all_objects; -- placeholder; ALTER TABLE dbo.a ALTER COLUMN x NVARCHAR(510) COLLATE Albanian_BIN NOT NULL -- WITH (ONLINE = ON); -- placeholder; DROP TABLE dbo.a;
Im --placeholder
Spot habe ich ein paar Dinge ausprobiert, um Unterschiede im Verhalten festzustellen (das war unsere Produktions-SQL-Datenbank, also wollte ich nicht genug Daten verwenden oder genug Aktivität erstellen, damit der Unterschied offensichtlich wäre). Ich wollte in beiden Szenarien überprüfen, ob sich die Seite geändert hat (was auf einen echten Online-Vorgang hinweist) oder ob die Werte auf den vorhandenen Seiten aktualisiert wurden (ein nicht so Online-Vorgang). Ich hätte den Test auch erweitern können, um zu sehen, wie viele neue Seiten erstellt wurden, wenn die Seiten voll waren und/oder alle 255 Zeichen verwendet wurden, aber ich dachte, dass es ausreichen würde, nur zu sehen, ob sich die Seiten geändert haben.
Ich habe DBCC IND()
versucht :
DBCC IND(N'dbname', N'dbo.a', 1, 1);
Die Ergebnisse hier waren nicht überraschend:
Nachricht 40518, Ebene 16, Status 1Der DBCC-Befehl „IND“ wird in dieser Version von SQL Server nicht unterstützt.
Und sys.dm_db_database_page_allocations
(der Ersatz für DBCC IND
):
SELECT allocated_page_page_id FROM sys.dm_db_database_page_allocations(DB_ID(),OBJECT_ID(N'dbo.a'),1,1,N'LIMITED') WHERE is_iam_page = 0;
Dies führte zu einem leeren Ergebnissatz – ich glaube, dass diese dynamische Verwaltungsfunktion keine physischen Informationen in der Azure SQL-Datenbank verfügbar macht.
Als nächstes habe ich einen Trick mit fn_PhysLocCracker
ausprobiert , über die Leute wie Michelle Ufford (@sqlfool) bereits gebloggt haben:
SELECT l.page_id FROM dbo.a OUTER APPLY sys.fn_PhysLocCracker(%%PhysLoc%%) AS l;
Erfolg! Dies gab Werte für die Seiten zurück, die im Scan gegen dbo.a
verwendet wurden , und es ist klar, dass in der ONLINE = ON
Version werden die Daten auf neue Seiten verschoben (wobei vermutlich die alten während der gesamten Operation verfügbar bleiben), und ohne den Hinweis werden die Daten und Metadaten an Ort und Stelle aktualisiert:
Vergleich von Seiten unter Standardverhalten ALTER COLUMN (links) mit ONLINE =ON (rechts)
Eine andere Sache, die ich vergleichen wollte, waren die Ausführungspläne. In Management Studio sehe ich vielleicht nicht viel, aber in SQL Sentry Plan Explorer Pro kann ich den vollständigen Aufrufstapel sehen, einschließlich dessen, was hinter den Kulissen einiger DDL-Befehle vor sich geht. Unser Tool hat uns nicht enttäuscht – obwohl es keinen tatsächlichen Plan für die In-Place-Update-Variante präsentierte, zeigt es auch, dass es einen signifikanten Verhaltensunterschied gibt, wenn ONLINE = ON
verwendet wird :
Vergleich von Plänen unter dem standardmäßigen ALTER COLUMN-Verhalten (links) mit ONLINE =ON (rechts)
Natürlich werden Sie diesen Unterschied nur bemerken, wenn Sie alle anderen Bedingungen erfüllen, die für den Online-Betrieb erforderlich sind (viele ähneln den Anforderungen für die Online-Indexneuerstellung) in der kürzlich aktualisierten Dokumentation.
Wie hilft Ihnen das jetzt, wenn Sie keine SQL-Datenbank verwenden? Schließlich wird diese Syntax auch in SQL Server 2014 Cumulative Update #6 (12.0.2480) nicht korrekt geparst. Nun, Microsoft hat nicht gerade darauf geachtet, dass das Entwicklungsmuster „erst Cloud, dann Box“ geworden ist – wie Mark Souza kürzlich andeutete, als er über das neue Sicherheitsfeature auf Zeilenebene twitterte, das zuerst in Azure SQL Database eingeführt wurde:
Sicherheit auf Zeilenebene. Viel verlangt von der #sqlserver-Community. http://t.co/pp0sNr8Nt5 Cloud zuerst, aber Sie wissen, was das bedeutet. Es kommt
– Mark Souza (@mark_AzureCAT) 8. Februar 2015
Das bedeutet, dass diese Online-Vorgänge wahrscheinlich bald auch für Ihre lokale Kopie von SQL Server verfügbar sein werden. Beachten Sie jedoch, wie bei vielen anderen Online-Operationen, dass diese Dinge in der Regel der Enterprise Edition vorbehalten sind.