Jag körde några tester i SQL Database och upptäckte minst en ny operation som stöder ONLINE = ON
. Detta är förresten på en mycket ny version – SELECT @@VERSION;
fortsätter att ge ett gammalt byggnummer, men beviset finns i byggdatumet:
12 feb 2015 00:53:13
Copyright (c) Microsoft Corporation
Den här versionen av Azure SQL Database stöder ONLINE = ON
alternativ för ALTER TABLE ... ALTER COLUMN
.
Låt oss säga att du har en tabell med en nullbar kolumn:
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;
Och nu bestämmer du dig för att göra den kolumnen inte nullbar, du kan göra detta (förutsatt att det inte finns någon NULL
s):
ALTER TABLE dbo.a ALTER COLUMN x VARCHAR(255) NOT NULL WITH (ONLINE = ON);
Du kan också göra saker som att ändra sorteringen, datatypen eller storleken på kolumnen:
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);
I nuvarande versioner av SQL Server (och tidigare versioner av Azure SQL Database), ONLINE = ON
ledtråd stöddes inte för ALTER TABLE
, och utan alternativet var detta en blockering och datastorlek. För att vara rättvis, första gången jag körde koden kunde jag bara bevisa att versionen med ONLINE = ON
körde framgångsrikt, inte för att det fungerade som annonserat.
Jag körde den här koden med ONLINE = ON
och utan:
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;
I --placeholder
spot, försökte jag några saker för att fastställa eventuella skillnader i beteende (detta var vår produktions SQL-databas, så jag ville inte använda tillräckligt med data eller skapa tillräckligt med aktivitet för att skillnaden skulle vara uppenbar). Jag ville kontrollera i båda scenarierna om sidan hade ändrats (som indikerar en verklig online-operation) eller om värdena uppdaterades på plats på de befintliga sidorna (en inte-så-online-operation). Jag kunde också ha utökat testet för att se hur många nya sidor som skapades om sidorna var fulla och/eller alla 255 tecken hade använts, men jag trodde att det skulle räcka att bara se om sidorna ändrades.
Jag försökte DBCC IND()
:
DBCC IND(N'dbname', N'dbo.a', 1, 1);
Resultaten här var inte överraskande:
Msg 40518, nivå 16, tillstånd 1DBCC-kommandot 'IND' stöds inte i den här versionen av SQL Server.
Och sys.dm_db_database_page_allocations
(ersättningen 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;
Detta gav en tom resultatuppsättning – jag tror att det är designat som denna dynamiska hanteringsfunktion inte exponerar någon fysisk information i Azure SQL Database.
Därefter provade jag ett trick med fn_PhysLocCracker
, som folk som Michelle Ufford (@sqlfool) har bloggat om tidigare:
SELECT l.page_id FROM dbo.a OUTER APPLY sys.fn_PhysLocCracker(%%PhysLoc%%) AS l;
Framgång! Detta returnerade värden för sidorna som användes i skanningen mot dbo.a
, och det är tydligt att i ONLINE = ON
version, data flyttas till nya sidor (förmodligen lämnar de gamla tillgängliga under hela operationen), och utan antydan uppdateras data och metadata på plats:
Jämföra sidor med standardbeteende ALTER COLUMN (vänster) med ONLINE =ON (höger)
En annan sak jag ville jämföra var utförandeplanerna. Jag kanske inte ser mycket i Management Studio, men i SQL Sentry Plan Explorer Pro kan jag se hela anropsstacken, inklusive vad som händer bakom kulisserna för vissa DDL-kommandon. Vårt verktyg gjorde ingen besviken – även om det inte presenterade en faktisk plan för uppdateringsvarianten på plats, visar det också att det finns en betydande beteendeskillnad när du använder ONLINE = ON
:
Jämföra planer under standardbeteende ALTER COLUMN (vänster) med ONLINE =ON (höger)
Naturligtvis kommer du bara att se den här skillnaden om du uppfyller alla andra villkor som krävs för onlineoperationer (många liknar kraven för online-indexombyggnad) i den nyligen uppdaterade dokumentationen.
Nu, om du inte använder SQL Database, hur hjälper det dig? När allt kommer omkring tolkar den här syntaxen inte korrekt ens i SQL Server 2014 Cumulative Update #6 (12.0.2480). Nåväl, Microsoft har inte precis bevakat det faktum att utvecklingsmönstret har blivit "moln först, sedan box" – som Mark Souza nyligen antydde när han twittrade om den nya säkerhetsfunktionen på radnivå som introducerades först i Azure SQL Database:
Säkerhet på radnivå. Efterfrågat mycket av #sqlserver-gemenskapen. http://t.co/pp0sNr8Nt5 Molnet först men du vet vad det betyder. Det kommer
— Mark Souza (@mark_AzureCAT) 8 februari 2015
Detta betyder att dessa onlineoperationer sannolikt kommer till din lokala kopia av SQL Server någon gång snart också. Liksom många andra onlineoperationer, kom dock ihåg att dessa saker tenderar att vara reserverade för Enterprise Edition.