Pergunta

No nosso banco de dados de produção / live Eu estou tentando adicionar um gatilho para uma mesa, mas não tiveram sucesso. Eu tentei algumas vezes, mas levou mais de 30 minutos para a instrução gatilho para completo criar e eu cancelei.

A tabela é um que é lido / escrito para muitas vezes por um par de processos diferentes. Eu ter desabilitado as tarefas agendadas que atualizar a tabela e tentou, por vezes, quando há menos actividade sobre a mesa, mas eu não sou capaz de tudo paragem que acessa a tabela.

Eu não acredito que há um problema com o próprio comando CREATE TRIGGER. A instrução CREATE TRIGGER foi bem sucedida e rápida em um ambiente de teste, e o gatilho funciona corretamente quando linhas são inseridas / atualizadas para a mesa. Embora quando eu criei o gatilho no banco de dados de teste não havia nenhuma carga sobre a mesa e que teve consideravelmente menos linhas, que é diferente do que no banco de dados / produção ao vivo (100 vs. 13.000.000 +).

Aqui está a declaração gatilho que eu estou tentando executar criar

CREATE TRIGGER [OnItem_Updated] 
    ON  [Item]
   AFTER UPDATE
AS 
BEGIN
    SET NOCOUNT ON;

    IF update(State)
    BEGIN
        /* do some stuff including for each row updated call a stored 
          procedure that increments a value in table based on the 
          UserId of the updated row */
    END
END

Pode haver problemas com a criação de um gatilho em uma tabela, enquanto linhas estão sendo atualizados ou se ele tem muitas linhas?

gatilhos Em SQLServer são criados ativado por padrão. É possível criar o gatilho desativado por padrão?

Quaisquer outras ideias?

Foi útil?

Solução

O problema pode não estar na mesa em si, mas nas tabelas do sistema que têm de ser actualizados de forma a criar o gatilho. Se você estiver fazendo qualquer outro tipo de DDL como parte de seus processos normais pudessem ser segurá-lo.

Use sp_who para descobrir onde o bloco está vindo, então, investigar a partir daí.

Outras dicas

Eu acredito que o CREATE TRIGGER tentará colocar um cadeado na tabela inteira.

Se você tem um monte de atividade em que a tabela pode ter que esperar um longo tempo e você poderia estar criando um impasse.

Para quaisquer alterações de esquema que você deve realmente fazer com que todos da base de dados.

Dito isto, é tentador colocar em "pequenas" alterações com conexões ativas. Você deve dar uma olhada nas fechaduras / conexões para ver onde a contenção de bloqueio é.

Isso é estranho. Um gatilho AFTER UPDATE não deve precisar verificar as linhas existentes na tabela. Acho que é possível que você não é capaz de obter um bloqueio na tabela para adicionar o gatilho.

Você pode tentar criar um gatilho que, basicamente, não faz nada. Se você não pode criar isso, então é uma questão de bloqueio. Se você pode, então você pode desativar esse gatilho, adicionar seu código destinado ao corpo, e habilitá-lo. (Eu não acredito que você pode desativar um gatilho durante a criação.)

Parte do problema também pode ser o próprio gatilho. Poderia seu gatilho acidentalmente estar atualizando todas as linhas da tabela? Há uma grande diferenca entre 100 linhas em um banco de dados de teste e 13.000.000. É uma idéia muito ruim para desenvolver código contra tal um pequeno conjunto quando você tem um grande conjunto de dados, como você pode ter nenhuma maneira de prever o desempenho. SQL que funciona bem para 100 registros pode completamente trancar um sistema com milhões de horas. Você realmente quer saber que no dev, não quando você promove a prod.

Chamar um proc armazenado em um gatilho é geralmente uma escolha muito ruim. Isso também significa que você tem que percorrer registros que é uma escolha ainda pior em um gatilho. Gatilhos deve alawys representam vários recordes inserções / atualizações ou exclusões. Se alguém inserir 100.000 linhas (não improvável, se você tem 13.000.000 registros), então looping através de uma base de proc armazenados registro poderia levar horas, bloquear a tabela inteira e causar todos os usuários querem caçar o desenvolvedor e kill (ou pelo menos Maim) -lo porque eles não podem fazer seu trabalho.

Eu não teria sequer considerar colocar o gatilho na prod até que você teste contra um simliar conjunto de registros em tamanho para prod.

Meu amigo Dennis escreveu este artigo que ilustra por testar uma pequena volumn de informações quando você tem um grande volumn de informações pode criar dificuldades no prd que você não reparou em dev: http://blogs.lessthandot.com/index.php/DataMgmt/?blog=3&title=your-testbed-has-to-have-the-same-volume&disp=single&more= 1 & c = 1 & tb = 1 & pb = 1 # c1210

Executar DISABLE TRIGGER triggername ON tablename antes de alterar o gatilho, então habilitá-lo com ENABLE TRIGGER triggername ON tablename

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top