Eu estava executando alguns testes no Banco de Dados SQL e descobri pelo menos uma nova operação que suporta
ONLINE = ON
. Esta é uma versão muito recente, a propósito – SELECT @@VERSION;
continua a gerar um número de compilação antigo, mas a prova está na data de compilação:Microsoft SQL Azure (RTM) – 12.0.2000.8
12 de fevereiro de 2015 00:53:13
Copyright (c) Microsoft Corporation
Esta versão do Banco de Dados SQL do Azure dá suporte ao
ONLINE = ON
opção para ALTER TABLE ... ALTER COLUMN
. Digamos que você tenha uma tabela com uma coluna anulável:
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;
E agora você decide tornar essa coluna não anulável, você pode fazer isso (supondo que não haja
NULL
s):ALTER TABLE dbo.a ALTER COLUMN x VARCHAR(255) NOT NULL WITH (ONLINE = ON);
Você também pode fazer coisas como alterar o agrupamento, o tipo de dados ou o tamanho da coluna:
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);
Nas versões atuais do SQL Server (e versões anteriores do Banco de Dados SQL do Azure), o
ONLINE = ON
dica não era suportada para ALTER TABLE
, e sem a opção, esta foi uma operação de bloqueio e tamanho de dados. Para ser justo, na primeira vez que executei o código, só pude provar que a versão com ONLINE = ON
funcionou com sucesso, não que tenha funcionado como anunciado. Eu executei este código com
ONLINE = ON
e sem: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;
No
--placeholder
local, eu tentei algumas coisas para determinar qualquer diferença no comportamento (este era o nosso banco de dados SQL de produção, então eu não queria usar dados suficientes ou criar atividade suficiente para que a diferença fosse óbvia). Eu queria verificar em ambos os cenários se a página havia mudado (indicando uma verdadeira operação online) ou se os valores foram atualizados nas páginas existentes (uma operação não tão online). Eu também poderia ter expandido o teste para ver quantas novas páginas foram criadas se as páginas estivessem cheias e/ou todos os 255 caracteres fossem usados, mas pensei que apenas ver se as páginas foram alteradas seria suficiente. Eu tentei
DBCC IND()
:DBCC IND(N'dbname', N'dbo.a', 1, 1);
Os resultados aqui não foram surpreendentes:
Msg 40518, Level 16, State 1
O comando DBCC 'IND' não é suportado nesta versão do SQL Server.
E
sys.dm_db_database_page_allocations
(o substituto para 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;
Isso gerou um conjunto de resultados vazio – acredito que é por design que essa função de gerenciamento dinâmico não expõe nenhuma informação física no Banco de Dados SQL do Azure.
Em seguida, tentei um truque com
fn_PhysLocCracker
, sobre o qual pessoas como Michelle Ufford (@sqlfool) escreveram antes:SELECT l.page_id FROM dbo.a OUTER APPLY sys.fn_PhysLocCracker(%%PhysLoc%%) AS l;
Sucesso! Isso retornou valores para as páginas usadas na verificação em relação a
dbo.a
, e é claro que no ONLINE = ON
versão, os dados são movidos para novas páginas (presumivelmente deixando as antigas disponíveis ao longo da operação), e sem a dica, os dados e metadados são atualizados no local:Comparação de páginas sob o comportamento padrão ALTER COLUMN (esquerda) com ONLINE =ON (direita)
Outra coisa que eu queria comparar eram os planos de execução. Posso não ver muito no Management Studio, mas no SQL Sentry Plan Explorer Pro, posso ver a pilha de chamadas completa, incluindo o que acontece nos bastidores de alguns comandos DDL. Nossa ferramenta não decepcionou – embora não tenha apresentado um plano real para a variação de atualização in-loco, também demonstra que há uma diferença significativa de comportamento ao usar
ONLINE = ON
:Comparação de planos sob o comportamento padrão ALTER COLUMN (esquerda) com ONLINE =ON (direita)
Obviamente, você só verá essa diferença se atender a todas as outras condições exigidas para operações online (muitas são semelhantes aos requisitos para reconstrução de índice online) na documentação atualizada recentemente.
Agora, se você não estiver usando o Banco de Dados SQL, como isso o ajuda? Afinal, essa sintaxe não é analisada corretamente, mesmo na atualização cumulativa nº 6 do SQL Server 2014 (12.0.2480). Bem, a Microsoft não está exatamente protegendo o fato de que o padrão de desenvolvimento se tornou "primeiro a nuvem, depois a caixa" - como Mark Souza sugeriu recentemente quando twittou sobre o novo recurso de segurança em nível de linha introduzido primeiro no Banco de Dados SQL do Azure:
Segurança em nível de linha. Muito pedido pela comunidade #sqlserver. http://t.co/pp0sNr8Nt5 Nuvem primeiro, mas você sabe o que isso significa. Está chegando
— Mark Souza (@mark_AzureCAT) 8 de fevereiro de 2015
Isso significa que essas operações online provavelmente também chegarão à sua cópia local do SQL Server em breve. Como muitas outras operações online, porém, lembre-se de que essas coisas tendem a ser reservadas para a Enterprise Edition.