Prováděl jsem nějaké testy v SQL Database a objevil jsem alespoň jednu novou operaci, která podporuje ONLINE = ON
. Toto je mimochodem na velmi nedávné verzi – SELECT @@VERSION;
nadále poskytuje staré číslo sestavení, ale důkaz je v datu sestavení:
12. února 2015 00:53:13
Copyright (c) Microsoft Corporation
Tato verze Azure SQL Database podporuje ONLINE = ON
možnost pro ALTER TABLE ... ALTER COLUMN
.
Řekněme, že máte tabulku se sloupcem s možnou hodnotou Null:
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;
A nyní se rozhodnete, aby tento sloupec neměl hodnotu null, můžete to udělat (za předpokladu, že neexistují žádné NULL
s):
ALTER TABLE dbo.a ALTER COLUMN x VARCHAR(255) NOT NULL WITH (ONLINE = ON);
Můžete také provádět věci, jako je změna řazení, datového typu nebo velikosti sloupce:
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);
V aktuálních verzích SQL Server (a předchozích verzích Azure SQL Database) je ONLINE = ON
nápověda nebyla pro ALTER TABLE
podporována a bez možnosti to byla operace blokování a velikosti dat. Abych byl spravedlivý, při prvním spuštění kódu jsem dokázal pouze to, že verze s ONLINE = ON
běžel úspěšně, ne že by fungoval tak, jak bylo inzerováno.
Spustil jsem tento kód s ONLINE = ON
a bez:
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;
V --placeholder
místě, zkusil jsem pár věcí, abych určil jakýkoli rozdíl v chování (toto byla naše produkční SQL databáze, takže jsem nechtěl používat dostatek dat nebo vytvářet dostatek aktivity, aby byl rozdíl patrný). Chtěl jsem v obou scénářích zkontrolovat, zda se stránka změnila (což naznačuje skutečnou online operaci) nebo zda byly hodnoty aktualizovány na stávajících stránkách (nepříliš online operace). Mohl jsem také rozšířit test, abych zjistil, kolik nových stránek bylo vytvořeno, pokud byly stránky plné a/nebo bylo použito všech 255 znaků, ale myslel jsem si, že by stačilo zjistit, zda se stránky změnily.
Zkoušel jsem DBCC IND()
:
DBCC IND(N'dbname', N'dbo.a', 1, 1);
Výsledky zde nebyly překvapivé:
Zpráva 40518, úroveň 16, stav 1Příkaz DBCC 'IND' není v této verzi SQL Server podporován.
A sys.dm_db_database_page_allocations
(náhrada za 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;
Výsledkem byla prázdná sada výsledků – domnívám se, že tato funkce dynamické správy neodhaluje v Azure SQL Database žádné fyzické informace.
Dále jsem zkusil trik s fn_PhysLocCracker
, o kterém už dříve blogovali lidé jako Michelle Ufford (@sqlfool):
SELECT l.page_id FROM dbo.a OUTER APPLY sys.fn_PhysLocCracker(%%PhysLoc%%) AS l;
Úspěch! To vrátilo hodnoty pro stránky použité při skenování proti dbo.a
, a je jasné, že v ONLINE = ON
verze se data přesunou na nové stránky (pravděpodobně zůstanou ty staré dostupné po celou dobu operace) a bez nápovědy se data a metadata aktualizují na místě:
Porovnání stránek se standardním chováním ALTER COLUMN (vlevo) s ONLINE =ON (vpravo)
Další věc, kterou jsem chtěl porovnat, byly prováděcí plány. V Management Studio toho možná moc nevidím, ale v SQL Sentry Plan Explorer Pro vidím celý zásobník volání, včetně toho, co se děje v zákulisí některých příkazů DDL. Náš nástroj nezklamal – i když nepředložil skutečný plán pro variaci aktualizace na místě, také ukazuje, že při použití ONLINE = ON
existuje významný rozdíl v chování. :
Porovnání plánů při standardním chování ALTER COLUMN (vlevo) s ONLINE =ON (vpravo)
Tento rozdíl samozřejmě uvidíte pouze v případě, že splníte všechny ostatní podmínky požadované pro online operace (mnoho z nich je podobných požadavkům na online přestavbu indexu) v nedávno aktualizované dokumentaci.
Nyní, pokud nepoužíváte databázi SQL, jak vám to pomůže? Koneckonců, tato syntaxe není správně analyzována ani v SQL Server 2014 Kumulativní aktualizace #6 (12.0.2480). No, Microsoft zrovna nehlídal fakt, že se z vývojového vzoru stalo „nejdřív cloud, pak box“ – jak nedávno naznačil Mark Souza, když tweetoval o nové funkci zabezpečení na úrovni řádků, která byla poprvé představena v Azure SQL Database:
Zabezpečení na úrovni řádku. Komunita #sqlserver hodně žádá. http://t.co/pp0sNr8Nt5 Nejprve cloud, ale víte, co to znamená. Už se to blíží
— Mark Souza (@mark_AzureCAT) 8. února 2015
To znamená, že tyto online operace se pravděpodobně brzy dostanou i do vaší místní kopie SQL Serveru. Stejně jako mnoho jiných online operací však mějte na paměti, že tyto věci bývají vyhrazeny pro Enterprise Edition.