AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 120248
Accepted
JohnG
JohnG
Asked: 2015-11-06 13:25:25 +0800 CST2015-11-06 13:25:25 +0800 CST 2015-11-06 13:25:25 +0800 CST

O Service Broker é a melhor escolha para auditar alterações de dados no SQL Server Express?

  • 772

Meu projeto é auditar de 5 a 10 tabelas existentes em nosso sistema sem prolongar as transações. Seja qual for o método usado, ele deve funcionar no SQL Server Express 2005 até (eventualmente) 2016.

Eu fiz pesquisas sobre Change Data Capture (CDC) e Change Tracking. O controle de alterações não captura as alterações específicas e o CDC está disponível apenas na Enterprise Edition.

Então me deparei com o Service Broker. Fiquei intrigado com o Service Broker, então comecei a criar um protótipo. O Service Broker está funcionando bem, mas as respostas recebidas em duas de minhas outras postagens me levam a acreditar que esse pode não ser o caminho certo a seguir. Muito complicado para nada. Ainda estou no estágio de análise e tentando coisas diferentes como parte da minha análise.

No momento, os resultados do corretor de serviços não são convincentes... uma atualização em massa de 105.000 itens para uma tabela de preços leva 38 segundos, enquanto o processamento da Fila (a parte de auditoria) leva 17 segundos... mas os 38 segundos incluem o processamento duplo de inserção em 2 tabelas #temp que são usadas para inserir nos TMPins e TMPdel. Então, acho que posso cortar isso pela metade... Agora estou questionando o uso do service broker... logicamente, o gatilho provavelmente levaria o mesmo tempo apenas inserindo as informações diretamente na tabela de auditoria. .

Para esclarecer, quando digo inserção em massa, não é a função "Inserção em massa". Estou falando de um grande bloco de dados que é inserido ou atualizado de uma só vez. ao atualizar 105.000 itens na tabela de preços, quero auditar as alterações ocorridas. Quando digo mudanças que acontecem, resolvi inserir os novos valores na tabela de auditoria (se for um insert ou update) ou inserir a chave primária com todos os outros campos nulos (para registros que foram apagados)... Então sim! pode ser depois que os dados forem carregados, mas não quero perder nenhuma auditoria (não quero que uma transação passe fora de ordem)

As outras duas postagens ajudarão a obter o contexto do que estou tentando fazer e do que tentei:

  • Gatilho para criar uma tabela de variáveis ​​a ser enviada ao service broker
  • gatilhos - usando as tabelas inseridas/excluídas no SQL dinâmico

Eu valorizo ​​cada ideia.

sql-server trigger
  • 1 1 respostas
  • 4252 Views

1 respostas

  • Voted
  1. Best Answer
    Solomon Rutzky
    2015-11-07T12:38:17+08:002015-11-07T12:38:17+08:00

    Suponho que a postagem a seguir seja a base do que você está usando atualmente: Auditoria assíncrona centralizada com o Service Broker .

    Embora eu realmente goste do Service Broker, não acho que seja o mais adequado para lidar com essa situação específica. As principais preocupações que tenho com o Service Broker, pelo menos neste cenário específico, são:

    • Provavelmente é muito complicado se usado principalmente para separar o evento DML do evento de auditoria. Se não mover os dados para outro sistema, isso não parece oferecer muitos benefícios, pois você ainda precisará persistir as tabelas INSERTEDe no gatilho DML.DELETED
    • É baseado em eventos, e os eventos variam muito em tamanho e frequência. Você pode ter um milhão de operações de 1 registro ou uma ou duas operações de 1 milhão de registros. E como cada evento é cada operação DML individual, você não tem nenhuma oportunidade de remover entradas duplicadas e/ou negativas em várias operações DML.

    Minha preferência é despejar as alterações em uma tabela de filas e, em seguida, em um processo separado programado para ser executado a cada X minutos, ler o número Y de linhas e processá-las.

    1. Crie uma tabela de filas para armazenar os dados de auditoria de uma tabela específica (não para cada operação DML individual). A tabela deve ter:

      • a LOCK_ESCALATIONopção definida como DISABLE(via ALTER TABLE {name} SET (LOCK_ESCALATION = DISABLE)) para evitar conflito entre o registro de novos dados pelo gatilho e a remoção de dados do processamento de auditoria. Esta opção foi introduzida no SQL Server 2008, portanto não pode ser usada em instâncias de 2005, mas não há razão para não usá-la nas instâncias de 2008 e mais recentes, pois não altera a funcionalidade em nenhum dos casos.
      • uma AuditIDPK que é uma das seguintes:
        • a INT IDENTITYpartir de -2147483648
        • umaBIGINT IDENTITY
        • an INTcom seu valor vindo de a SEQUENCEque é definido comoCYCLE
      • apenas os campos para os quais você está rastreando alterações, se não todos eles
      • campos para "antigo" e "novo" se precisar acompanhar os valores antes e depois de cada processamento. Dependendo de como você está auditando as alterações, se você tiver um arquivo de valores anteriores, precisará apenas dos "novos" valores da INSERTEDtabela, pois os valores na DELETEDtabela já devem estar em seus dados de auditoria anteriores.
    2. Crie um gatilho que simplesmente insere na tabela de filas. Se você precisar passar valores "antigos" e "novos", JUNTE as tabelas INSERTEDe DELETEDaqui em vez de tentar manter duas tabelas de filas separadas, uma para cada uma dessas pseudotabelas. Juntá-los neste ponto e inserir os valores "antigo" e "novo" em uma única linha é um pequeno impacto no desempenho, mas garantirá que cada operação permaneça unida e em ordem cronológica (via PK de incremento).

      Se você não estiver rastreando as alterações em todos os campos, use UPDATE() ou COLUMNS_UPDATED() para determinar se as colunas que estão sendo auditadas foram realmente atualizadas (para UPDATEoperações; essas funções retornam true para todas as colunas em INSERToperações). Lembre-se de que as funções UPDATE()e não determinam se uma alteração foi feita no valor da(s) coluna(s)!! Eles informam apenas se as colunas estavam presentes na cláusula da declaração. A única maneira de determinar se o(s) valor(es) realmente mudou(s) é JOIN the eCOLUMNS_UPDATED()SETUPDATEINSERTEDDELETEDtabelas. Mas, se não estiver rastreando todas as colunas, essas funções são ótimas para sair do Gatilho sem fazer nenhum trabalho se nenhuma coluna rastreada tiver sido alterada. Ou seja, no início do Trigger, você faria:

      IF (NOT UPDATE(TrackedColumn1) AND NOT UPDATE(TrackedColumn2))
      BEGIN
        RETURN; -- no changes so just exit
      END;
      

      Se você não estiver capturando valores "antigos" e "novos" na tabela de filas, essa é a única oportunidade de eliminar registros "atualizados" em que nenhuma coluna foi realmente alterada. Ao inserir na tabela de filas, basta filtrar WHERE IntColOld <> IntColNew OR StringFieldOld <> StringFieldNew COLLATE Latin1_General_BIN2 OR ISNULL(DateFieldOld, '1900-01-01') <> ISNULL(DateFieldNew, '1900-01-01') OR .... É importante usar um _BIN2agrupamento em campos de string para garantir que os dois campos sejam de fato idênticos. E você precisa usar INSULLapenas os campos anuláveis ​​para que eles possam ser iguais se ambos forem NULL.

    3. Crie um procedimento armazenado que será executado por X segundos e, nesse período, processará conjuntos de TOP(@BatchSize)linhas, usando ORDER BY AuditID ASC. Você faz isso por meio de um WHILEloop que verifica qual foi definido GETDATE()no @StartTimeinício do procedimento armazenado. Dependendo do processamento que você precisa fazer, às vezes é mais fácil criar uma tabela temporária local para INSERT INTO #TempTable SELECT...o conjunto de trabalho (então você terá DELETEessas linhas no final de cada loop) ou DELETE FROMusar OUTPUT INTO #TempTable.

      Aqui você pode remover modificações duplicadas. Se você estiver rastreando valores "antigos" e "novos" para cada linha, também deverá eliminar as linhas em que nenhuma das colunas realmente foi alterada. Você pode fazer isso testando WHERE IntColOld = IntColNew AND StringFieldOld = StringFieldNew COLLATE Latin1_General_BIN2 AND .... É importante usar um _BIN2agrupamento em campos de string para garantir que os dois campos sejam de fato idênticos. Os agrupamentos não binários, mesmo se diferenciam maiúsculas de minúsculas e acentos, etc., ainda permitem normalizações linguísticas que devem comparar o mesmo para comparações regulares, mas não durante a auditoria. Não use _BINagrupamentos, pois eles foram obsoletos desde o SQL Server 2005, que foi quando os _BIN2agrupamentos foram lançados.

      Tudo feito dentro do loop precisa estar dentro de um // BEGIN TRANexplícito . Use um bloco TRY / CATCH para gerenciar isso. Isso evitará a perda de alguns registros ou o processamento duplo de alguns.COMMITROLLBACK

    4. Agende o procedimento armazenado para ser executado a cada X minutos. Normalmente, isso é feito por meio de um trabalho do SQL Server Agent , mas o SQL Server Agent não está disponível para as edições Express. Nesse caso, você pode usar o Agendador de Tarefas do Windows ou obter algo como Quartz.NET .

    A configuração de um processo dessa maneira permite que você tenha um processo mais consistente e ajustável que deve processar constantemente X registros a cada Y minutos. Portanto, não importa se você tem 1 milhão de operações DML de linha única ou uma única operação DML de 1 milhão de linhas; esse processo continuará avançando, fazendo o que faz.

    • 7

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve