Database
 sql >> Base de Dados >  >> RDS >> Database

Mais operações online disponíveis agora – ou em breve


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:



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.