Replicação entre servidores > Implantação das bases replicadas
Reimplantar uma base MASTER
RTREPLICATOR.RQ-008
Descrição
Cenário
Em uma rede de replicação ocorreu um problema com o servidor MASTER que deverá ser reinstalado a partir dos dados obtidos em um servidor SLAVE.
ATENÇÃO
Este processo nunca foi testado. Favor observar com atenção para identificar possíveis problemas que não foram previstos.
Fluxo normal
Este procedimento deve ser executado quando ocorreu um problema com um servidor MASTER que terá de ser recuperado a partir dos dados de um SLAVE existente.
Para proceder com a reimplantação do MASTER, executar os passos abaixo.
- Escolher um dos servidores SLAVE para ser utilizado como matriz para a geração dos dados do novo MASTER.
- Garantir que o ELIGO tanto do servidor MASTER como do SLAVE estejam parados. O único acesso a eles será feito diretamente através do banco de dados.
No SLAVE
- Executar um backup sem incluir as tabelas de LOGs, nem DML_LOGS.
- Alterar todos os dml-logs da fila A para a fila F:
update dml_logs set queue='F' where queue='A';
- Zerar o ponteiro do próximo DML_LOG a ser baixado do novo MASTER (isso também será executado nos demais slaves):
update dml_logs_cfg set last_id_retrieved=0;
Sequences
Antigo MASTER acessível
Se o antigo MASTER ainda for acessível, recuperar as sequences e salvar em um arquivo texto "sequences.sql":
dml-insert sequences;
Incluir a linha abaixo no início do arquivo (antes dos DMLs gerados pelo comando acima):
delete from sequences;
O arquivo final esperado é algo como:
delete from sequences;
insert into sequences (id, sequence, next_value, cache, description, max_value, next_range_min_value, next_range_max_value, range_size, attributes, random) values (386523, 'A0', 2, 1, null, 0, 0, 0, 100, null, 'N');
insert into sequences (id, sequence, next_value, cache, description, max_value, next_range_min_value, next_range_max_value, range_size, attributes, random) values (386520, 'SEQ_GERACAO', 1676452, 100, null, 0, 0, 0, null, null, 'N');
insert into sequences (id, sequence, next_value, cache, description, max_value, next_range_min_value, next_range_max_value, range_size, attributes, random) values (386517, 'PK_SEQUENCE', 24803524, 100, null, 0, 0, 0, 6250, 'COMPONENTES.ID', 'N');
insert into sequences (id, sequence, next_value, cache, description, max_value, next_range_min_value, next_range_max_value, range_size, attributes, random) values (386522, 'SEQ_DML_LOGS', 49964444, 100, null, 0, 0, 0, null, null, 'N');
insert into sequences (id, sequence, next_value, cache, description, max_value, next_range_min_value, next_range_max_value, range_size, attributes, random) values (386519, 'LOG_SEQUENCE', 130343038, 100, null, 0, 0, 0, null, null, 'N');
...
Sem acesso ao antigo MASTER
Caso os dados de sequences do MASTER original não puderem ser recuperados, será necessário executar o SQL abaixo em TODOS os SLAVES e copiar o resultado em um arquivo texto "sequences.sql":
select 'update sequences set next_value='
|| next_range_max_value+1
|| ' where sequence_name = '''
|| sequence
|| ''' and next_value < '
|| next_range_max_value+1
|| ';'
from sequences
where range_size > 0;
Incluir no início do arquivo a linha abaixo:
update sequences set max_value=0, next_range_min_value=0, next_range_max_value=0;
O arquivo final deverá ficar algo tipo:
update sequences set max_value=0, next_range_min_value=0, next_range_max_value=0;
update sequences set next_value=102 where sequence_name = SEQ_NEGOCIACAO and next_value < 102;
update sequences set next_value=2010 where sequence_name = SEQ_PESSOAS and next_value < 2010;
update sequences set next_value=590034 where sequence_name = PK_SEQUENCE and next_value < 590034;
update sequences set next_value=43008 where sequence_name = SEQ_PEDIDO and next_value < 43008;
update sequences set next_value=714 where sequence_name = NUMERO_LOTE_NFE and next_value < 714;
...
Outros SLAVES
Caso existam outros SLAVES, eles também terão de ter o ponteiro do próximo DML_LOG a ser baixado zerado:
update dml_logs_cfg set last_id_retrieved=0;
No novo MASTER
- Criar o banco do novo MASTER
- Executar o restore da base de dados
- Ajustar a configuração para indicar que ele é um MASTER (considerando que seu nome é "M"):
update dml_logs_cfg
set server_url=null, secret_key=null, last_id_retrieved=0
, node_id=(select id from replication_nodes where global_name='M')
, logging_level=1, start='S', file_sync_interval=null, last_file_sync_master_time=null
, last_file_sync_local_time=null
, file_sync_ignored_roots='/tlu';
- Ajustar as sequences do MASTER, executando o script contido no arquivo "sequences.sql" (criado por um dos métodos explicados anteriormente)
- Excluir o JOB de atualização total dos arquivos
- Revisar todos os demais jobs para identificar quais devem ser executados no MASTER.
- Criar as tabelas de DML_LOGS e LOGS. O ideal é que isso seja feito ANTES do serviço ser reniciado, a partir do DDL capturado no SLAVE:
CREATE TABLE dml_logs
(
id bigint NOT NULL,
date timestamp without time zone NOT NULL,
origin text NOT NULL,
dml text NOT NULL,
dml_parameters text,
queue character varying(1),
original_id bigint NOT NULL,
original_date timestamp without time zone NOT NULL,
error_message text,
origin_table_name character varying(80),
origin_record_id bigint,
CONSTRAINT regra_pk_505355 PRIMARY KEY (id )
);
CREATE INDEX ak_dmllog_data
ON dml_logs
USING btree
(date );
CREATE INDEX ak_dmllog_id
ON dml_logs
USING btree
(original_id );
CREATE INDEX ak_dmllog_origin_record_id
ON dml_logs
USING btree
(origin_record_id );
CREATE INDEX ak_dmllog_original_date
ON dml_logs
USING btree
(original_date );
CREATE INDEX ak_dmllog_queue
ON dml_logs
USING btree
(queue COLLATE pg_catalog."default" );
CREATE INDEX ak_dmllog_queue_id
ON dml_logs
USING btree
(queue COLLATE pg_catalog."default" , id );
CREATE TABLE logs
(
id bigint NOT NULL,
data_hora timestamp without time zone NOT NULL,
endereco_remoto character varying(160),
usuario character varying(40),
usuario_id bigint,
descricao text,
tipo character varying(30),
origem character varying(160),
registro character varying(160),
sessao_id character varying(40),
tempo integer,
CONSTRAINT pk_logs PRIMARY KEY (id )
);
CREATE INDEX ak_logs_data
ON logs
USING btree
(data_hora );
CREATE INDEX ak_logs_journaling
ON logs
USING btree
(origem COLLATE pg_catalog."default" , registro COLLATE pg_catalog."default" , tipo COLLATE pg_catalog."default" );
CREATE INDEX ak_logs_registro
ON logs
USING btree
(registro COLLATE pg_catalog."default" );
CREATE INDEX ak_logs_sessao
ON logs
USING btree
(sessao_id COLLATE pg_catalog."default" );
CREATE INDEX ak_logs_tipo
ON logs
USING btree
(tipo COLLATE pg_catalog."default" );
CREATE INDEX ak_logs_usuario
ON logs
USING btree
(usuario COLLATE pg_catalog."default" );
- Voltar a sequence SEQ_DML_LOGS para 1:
drop sequence SEQ_DML_LOGS;
create sequence SEQ_DML_LOGS;
Finalizando
Uma vez que a base de dados estiver OK, os serviços do ELIGO deverão ser reiniciados e os mesmos testes de replicação sugeridos para uma nova instalação deverão ser executados.
No caso das sequences terem sido definidas pelos SLAVES (segundo método) é importante verificar nos dados se não houve o consumo de sequences diretamente no antigo MASTER. No caso de dúvida, pode-se aumentar o next_value das sequences suspeitas em uma certa quantidade "segura".