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 / 2967
Accepted
Marco Aviles
Marco Aviles
Asked: 2011-05-27 20:50:33 +0800 CST2011-05-27 20:50:33 +0800 CST 2011-05-27 20:50:33 +0800 CST

Replicação de banco de dados e verificação de consistência

  • 772

Tenho uma dúvida sobre dois bancos de dados (no Oracle 10g) que tenho, vamos chamá-los de A e B. A tem algumas informações (em várias tabelas) e quero que B obtenha uma cópia parcial de algumas tabelas de A e verifique constantemente alterações em A e 'sincroniza-las' em B.

Quero perguntar sobre algum método, técnica ou talvez ideias, sabendo que não posso fazer nenhuma alteração em A (só selects, sem triggers).

Desde já agradeço ajuda e paciência (para possíveis edições).

Informações adicionais :

Obrigado pelas respostas, não sei se é relevante, mas encontrei o operador MINUS, embora não tenha certeza se funciona com uma "subtabela" (selecionar).

oracle replication
  • 3 3 respostas
  • 1715 Views

3 respostas

  • Voted
  1. Best Answer
    Leigh Riffel
    2011-05-28T06:10:32+08:002011-05-28T06:10:32+08:00

    Suas opções são bastante limitadas por causa de seus requisitos para "verificar ... sincronizar constantemente" e "não pode fazer nenhuma alteração em A". Coisas como logs de exibição materializada, dbms_alert, fluxos e um banco de dados de espera estão todos fora de questão.

    Se as tabelas em A estiverem constantemente tendo todas as suas linhas atualizadas, então (como disse Jack Douglas) uma visualização materializada seria a mais fácil de configurar. No caso mais provável de que a maioria dos registros não mude em A de momento a momento, você provavelmente desejará configurar um pacote (ou pacotes) em B que selecione de A para mesclar e excluir conforme necessário em B. Isso irá esteja atualizado apenas com a frequência em que é executado, mas, considerando seus requisitos, pode ser o melhor que você pode fazer.

    Especificamente, seu pacote deve fazer o seguinte:

    • Excluir de B as linhas que não existem em A.
    • Mesclar A em B atualizando quando correspondido e inserindo quando não correspondido.

    Se você quiser evitar atingir a tabela em A várias vezes, poderá inserir a tabela inteira em uma tabela temporária global em B e, em seguida, excluir/mesclar a partir daí.

    Com relação a Minus: Minus pode informar todas as linhas de uma consulta de A que não estão em B. Unindo isso com B menos consulta de A, você pode obter todas as linhas que são diferentes, mas isso provavelmente levaria mais tempo para processar mesmo antes de adicionar a parte de inserção/atualização. Se A não obtiver atualizações ou exclusões, você poderá inserir os resultados do primeiro menos, mas insert into B...where not exists A...ainda seria mais rápido e simples.

    • 5
  2. Jack Douglas
    2011-05-27T21:39:52+08:002011-05-27T21:39:52+08:00

    Não há como saber que uma tabela em A foi alterada, exceto por votação. Você pode considerar as visualizações materializadas, atualizando periodicamente, que podem funcionar em um dblink - mas apenas uma atualização completa é possível, portanto, isso só pode ser prático se as tabelas forem pequenas.

    • 4
  3. Kerri Shotts
    2011-06-02T21:01:31+08:002011-06-02T21:01:31+08:00

    Difícil, já que você não tem acesso além de um SELECT em db_A. Então, aqui está um pensamento, mas requer algumas suposições bastante rígidas que podem (ou não) ser atendidas:

    Requisitos:

    • Todas as tabelas sendo sincronizadas teriam:
      • Um timestamp (quanto mais resolução, melhor)
      • Um ID único e sequencial
    • Todas as linhas da tabela, uma vez sincronizadas, não mudam.
      • Como alternativa, se ocorrer uma alteração E atualizar um carimbo de data/hora no registro, você poderá resolver isso dessa maneira.

    Agora, em db_B:

    CREATE TABLE table1...
    CREATE TABLE table2...,
    etc.
    
    PROCEDURE SYNC_TABLE1 IS
        MAX_ACTIVITY_DATE DATE;
        MAX_SEQUENCE_NO NUMBER;
    
        BEGIN
            SELECT MAX(SEQUENCE_NO), MAX(ACTIVITY_DATE) 
              INTO MAX_SEQUENCE_NO, MAX_ACTIVITY_DATE
              FROM table1;
        EXCEPTION WHEN NO_DATA_FOUND THEN
            MAX_SEQUENCE_NO := 0;
            MAX_ACTIVITY_DATE = TO_DATE('01/01/1980', 'MM/DD/YYYY');
        END;
    
        -- Bring over recent entries from db_A.table1 to db_B.table1
    
        INSERT INTO table1
        SELECT *
          FROM table1@db_A
         WHERE
               -- if using timestamps as your criteria:
               activity_date > MAX_ACTIVITY_DATE
               -- if using sequence nos as your criteria:
               sequence_no > MAX_SEQUENCE_NO
        ;
    
        -- consider adding limiters to decrease the bandwidth necessary
        -- for large transactions. For example activity_date < MAX_ACTIVITY_DATE + 30
        -- would load a month's worth of transactions at a time. sequence_no <
        -- MAX_SEQUENCE_NO + 500 would load 500 transactions at a time.
    
        COMMIT;
    EXCEPTION WHEN OTHERS THEN
        ROLLBACK;
        -- Consider logging the error!
        RAISE;
    END;
    (lather, rinse, repeat.)
    

    Novamente, isso só funciona se você tiver um ID exclusivo sequencial OU uma data de atividade sempre atualizada em db_A (e essa data deve ter resolução suficiente para detectar uma transação inserida um milissegundo após a anterior, portanto, os carimbos de data e hora são os melhores.)

    A maneira como sincronizo dados entre instâncias Oracle (e instâncias não Oracle, por exemplo, Oracle para mySql) é garantir que eu tenha uma coluna sync_date em todas as minhas tabelas sincronizáveis. Quando uma solicitação é feita para sincronizar dados, essa coluna sync_date é preenchida com a data da sincronização. Portanto, o processo de sincronização real é simples:

    FOR r in ( SELECT * FROM table1
                WHERE sync_date IS NULL ) LOOP
        send_sync_data_somewhere;
        UPDATE table1
           SET sync_date = current_timestamp
         WHERE rowid=r.rowid;
    END LOOP;
    

    Normalmente, um limitador entra em vigor, mas essa é a ideia. Além disso, se os dados forem alterados em um registro, a coluna sync_date será NULL, ponto em que o processo de sincronização os recuperará novamente.

    Observação: não importa a situação, você precisará de algum tipo de tratamento de desduplicação se puder oferecer suporte a alterações de dados depois que uma linha for sincronizada. Você pode tentar um MERGE ou um INSERT com um WHERE NOT EXISTS na cláusula SELECT juntamente com um UPDATE ... WHERE EXISTS.

    Espero que isso ajude.

    • 3

relate perguntas

  • ORDER BY usando prioridades personalizadas para colunas de texto

  • Interface sqlplus confortável? [fechado]

  • Como encontrar as instruções SQL mais recentes no banco de dados?

  • Como posso consultar nomes usando expressões regulares?

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

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

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

    • 4 respostas
  • Marko Smith

    Como você mostra o SQL em execução em um banco de dados Oracle?

    • 2 respostas
  • Marko Smith

    Como selecionar a primeira linha de cada grupo?

    • 6 respostas
  • Marko Smith

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

    • 10 respostas
  • Marko Smith

    Posso ver Consultas Históricas executadas em um banco de dados SQL Server?

    • 6 respostas
  • Marko Smith

    Como uso currval() no PostgreSQL para obter o último id inserido?

    • 10 respostas
  • Marko Smith

    Como executar o psql no Mac OS X?

    • 11 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
  • Marko Smith

    Passando parâmetros de array para um procedimento armazenado

    • 12 respostas
  • Martin Hope
    Manuel Leduc Restrição exclusiva de várias colunas do PostgreSQL e valores NULL 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler Quando uma chave primária deve ser declarada sem cluster? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +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
  • Martin Hope
    BrunoLM Guid vs INT - Qual é melhor como chave primária? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick Como posso otimizar um mysqldump de um banco de dados grande? 2011-01-04 13:13:48 +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