Files
projeto-importado/docs/replicacao_nativa_saude_s1.md
T
2025-11-28 00:29:42 -03:00

431 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Roteiro Replicação Nativa - IPMSaude S1
>Documentação do procedimento de ativação da replicação do sistema IPMSaude S-1 para o S-2, para os casos onde a Origem está na versão 11.5 e destino no 16.
## Processos Adicionais
> Os links abaixos são referentes a desativação e remoção da replicação.
[`1 - Interromper Replicação Nativa`](../docs/replicacao_nativa_interrompe_ipmsaude.md)
[`2 - Remover Estrutura`](../docs/replicacao_nativa_remover_estrutura.md)
> Banco do IpmSaúde, não deve ter o schema "migracao_saude", se tiver, verificar com a equipe de migração"
> Banco do Atende.Net, não deve ter o schema "migracao_saude", se tiver, verificar com a equipe de migração"
## Destino - Banco Atende.Net - (00000-cliente-bdp-01-1600.atende.net)
No banco do cliente (PostgreSQL16), criar um disco para a replicação do IpmSaude:
> Deve-se adicionar um HD temporário ao servidor do banco de dados de Destino (Atende.Net - PostgreSQL16) ao qual receberá o tablespace replicacao.
> Como sugestão, adicionar o HD com tamanho de 1234GB, no formato Thin Provision com a controladora SCSI Controller 1, desta forma o HD crescerá somente o necessário e será fácil de identificá-lo para posterior remoção.
```
su - root
Criando pasta:
mkdir -p /var/lib/postgresql/16/tablespaces/replicacao
Adicionando disco:
lsblk
pvcreate /dev/sde
vgcreate postgresql-vg10 /dev/sde
lvcreate -l +100%FREE -n lv-replicacao postgresql-vg10
mkfs.xfs /dev/mapper/postgresql--vg10-lv--replicacao
blkid | grep replicacao
blkid | grep replicacao | grep "0cbfc3a7-07d2-483e-885a-73936788b157"
ls -l /dev/disk/by-id/ | grep dm-7
#Retorno: dm-uuid-LVM-My295Ba6z7Vl5TX7eyue3b5bCCOtX1NfqddL0ZoIJLfOjD0N9deI8yySYvvRff3h -> ../../dm-7
vim /etc/fstab
# disco replicacao
/dev/disk/by-id/dm-uuid-LVM-My295Ba6z7Vl5TX7eyue3b5bCCOtX1NfqddL0ZoIJLfOjD0N9deI8yySYvvRff3h /var/lib/postgresql/16/tablespaces/replicacao xfs defaults,noatime,nodiratime 0 1
Montando e aplicando permissões para o diretório:
mount /var/lib/postgresql/16/tablespaces/replicacao
chown postgres.postgres /var/lib/postgresql/16/tablespaces/replicacao
```
Inserir o IP do banco Master (IpmSaude S1) como TRUST no pg_hba.conf.
Obs: Esta linha deve ser adicionada logo abaixo da linha que possui o endereço "127.0.0.1/32 como trust"
```
vim /etc/postgresql/16/main/pg_hba.conf
Ex.:
host all all 127.0.0.1/32 trust
host all all 192.168.21.29/32 trust # Libera IpmSaude S1
systemctl reload postgresql.service
```
Ajustar configurações no arquivo postgresql.conf:
```
cd /etc/postgresql/16/main/
cp postgresql.conf postgresql.bkp-antes-saude_s1
vim postgresql.conf
OBSERVAÇÃO: Se o parametro estiver max_worker_processes = 3, deverá ser alterado para max_worker_processes = 4
Se: max_worker_processes < 10
wal_level = logical
max_wal_senders = 3
max_replication_slots = 3
max_sync_workers_per_subscription = 2
wal_receiver_status_interval = 60s
wal_receiver_timeout = 300s
Se: max_worker_processes > 10
wal_level = logical
max_wal_senders = 5
max_replication_slots = 6
max_sync_workers_per_subscription = 2
max_logical_replication_workers = 4
wal_receiver_status_interval = 60s
wal_receiver_timeout = 300s
```
Criar a tablespace replicacao para recebimento dos dados:
```ruby
CREATE TABLESPACE replicacao
OWNER postgres
LOCATION '/var/lib/postgresql/16/tablespaces/replicacao';
```
Criar o schema replicação e demais tabelas/funções/etc...
```ruby
--drop SCHEMA replicacao cascade;
CREATE SCHEMA replicacao;
CREATE SEQUENCE replicacao.sqttblog
INCREMENT 1
START 1
MINVALUE 0
MAXVALUE 9223372036854775807
CACHE 1;
CREATE TABLE replicacao.tblog
(
logcodigo bigint NOT NULL DEFAULT nextval('replicacao.sqttblog'::regclass),
logdatahora timestamp not null default now(),
logip varchar(30) not null default inet_client_addr(),
logpid bigint not null default pg_backend_pid(),
logacao text not null,
logquery text not null default current_query()
);
COMMENT ON COLUMN replicacao.tblog.logcodigo IS 'Código do log';
COMMENT ON COLUMN replicacao.tblog.logdatahora IS 'Datahora da ocorrencia';
COMMENT ON COLUMN replicacao.tblog.logip IS 'Ip do client';
COMMENT ON COLUMN replicacao.tblog.logpid IS 'Pid da conexao';
COMMENT ON COLUMN replicacao.tblog.logacao IS 'Acao sendo executada';
COMMENT ON COLUMN replicacao.tblog.logquery IS 'Query';
ALTER TABLE replicacao.tblog
ADD CONSTRAINT pk_tblog PRIMARY KEY(logcodigo);
CREATE SEQUENCE replicacao.sqttbddl
INCREMENT 1
START 1
MINVALUE 0
MAXVALUE 9223372036854775807
CACHE 1;
CREATE TABLE replicacao.tbddl
(
ddlcodigo bigint NOT NULL DEFAULT nextval('replicacao.sqttbddl'::regclass),
ddlcomando text COLLATE pg_catalog."default" NOT NULL,
ddldatahora timestamp default now(),
CONSTRAINT pk_tbddl PRIMARY KEY (ddlcodigo)
);
--Altera o tablespace das tabelas do IPM Fiscal
create or replace function replicacao.fn_altera_tablespace()
returns boolean as
$body$
declare
r_objeto record;
begin
--Tabelas
for r_objeto in (select 'alter table "'||nspname||'"."'||pg_class.relname||'" set tablespace replicacao;' as cmd,
'"'||nspname||'"."'||pg_class.relname||'"' as nome
from pg_namespace
left join pg_class
on pg_class.relnamespace = pg_namespace.oid
where translate(pg_namespace.nspname, '1234567890', '') in ('dcarq', '_fiarq', '_gtarq', '_isarq', '_nfarq', '_spunico', '_wgt', '_wnp', '_wsn', 'saudeweb', 'saudewebglo', 'spunico')
and pg_class.relkind = 'r'
and pg_class.reltablespace <> (select oid from pg_tablespace where spcname = 'replicacao')
order by pg_namespace.nspname,
pg_class.relname)
loop
insert into replicacao.tblog (logacao, logquery) values ('Alterando tablespace da tabela '||r_objeto.nome, r_objeto.cmd);
raise notice 'Alterando tablespace da tabela %.', r_objeto.nome;
execute r_objeto.cmd;
end loop;
--Índices
for r_objeto in (select 'alter index "'||nspname||'"."'||pg_class.relname||'" set tablespace replicacao;' as cmd,
'"'||nspname||'"."'||pg_class.relname||'"' as nome
from pg_namespace
left join pg_class
on pg_class.relnamespace = pg_namespace.oid
where translate(pg_namespace.nspname, '1234567890', '') in ('dcarq', '_fiarq', '_gtarq', '_isarq', '_nfarq', '_spunico', '_wgt', '_wnp', '_wsn', 'saudeweb', 'saudewebglo', 'spunico')
and pg_class.relkind = 'i'
and pg_class.reltablespace <> (select oid from pg_tablespace where spcname = 'replicacao')
order by pg_namespace.nspname,
pg_class.relname)
loop
insert into replicacao.tblog (logacao, logquery) values ('Alterando tablespace da tabela '||r_objeto.nome, r_objeto.cmd);
raise notice 'Alterando tablespace do índice %.', r_objeto.nome;
execute r_objeto.cmd;
end loop;
return true;
end;
$body$
LANGUAGE plpgsql VOLATILE;
create or replace function replicacao.fn_remove_relacao_atendenet()
returns boolean as
$body$
declare
r_fk record;
begin
for r_fk in (select *,
'alter table "'||schema_filha||'"."'||tabela_filha||'" drop constraint "'||conname||'";' as cmd
from (SELECT pg_constraint.conname,
schema_pai.nspname as schema_pai,
tabela_pai.relname as tabela_pai,
schema_filha.nspname as schema_filha,
tabela_filha.relname as tabela_filha
FROM pg_constraint
INNER JOIN pg_class tabela_filha
ON tabela_filha.oid = pg_constraint.conrelid
INNER JOIN pg_namespace schema_filha
ON schema_filha.oid = tabela_filha.relnamespace
INNER JOIN pg_class tabela_pai
ON tabela_pai.oid = pg_constraint.confrelid
INNER JOIN pg_namespace schema_pai
ON schema_pai.oid = tabela_pai.relnamespace
where pg_constraint.contype = 'f'
and (translate(substr(schema_pai.nspname,1,1),'1234567890','') = '' or
translate(substr(schema_filha.nspname,1,1),'1234567890','') = '' or
schema_pai.nspname in ('saudeweb', 'saudewebglo', 'spunico') or
schema_filha.nspname in ('saudeweb', 'saudewebglo', 'spunico'))
and pg_constraint.confupdtype <> 'c') orig
where translate(schema_pai, '1234567890', '') not in ('dcarq', '_fiarq', '_gtarq', '_isarq', '_nfarq', '_spunico', '_wgt', '_wnp', '_wsn', 'saudeweb', 'saudewebglo', 'spunico')
or translate(schema_filha, '1234567890', '') not in ('dcarq', '_fiarq', '_gtarq', '_isarq', '_nfarq', '_spunico', '_wgt', '_wnp', '_wsn', 'saudeweb', 'saudewebglo', 'spunico'))
loop
insert into replicacao.tblog (logacao, logquery) values ('Apagando a FK "'||r_fk.conname||'" da tabela "'||r_fk.schema_filha||'"."'||r_fk.tabela_filha||'".', r_fk.cmd);
raise notice 'Apagando a FK "%" da tabela "%".', r_fk.conname, r_fk.schema_filha||'"."'||r_fk.tabela_filha;
execute r_fk.cmd;
end loop;
return true;
end;
$body$
LANGUAGE plpgsql VOLATILE;
```
__ATENÇÃO: O RESTART DO SERVIÇO DE BANCO DE DADOS DEVERÁ SER EXECUTADO SOMENTE APÓS AS 18Hrs!__
```
systemctl restart postgresql.service
```
## Origem - Banco IpmSaude S1 - (00000-cliente-bdp-02-1150.atende.net)
Deve-se liberar o IP do Banco do Atende.Net (bdp-01) no pg_hba do Banco do IpmSaude S1 (bdp-02), apenas para o usuario replicação após a linha do endereço "127.0.0.1 como trust", inserindo a linha conforme exemplo abaixo:
```
cd /var/lib/pgsql/11/data/
vim pg_hba.conf
Ex.:
host all all 127.0.0.1/32 trust
host all replicacao 192.168.21.28/32 trust # Atende.Net
systemctl reload postgresql-11.service
```
Alterar as configurações do postgresql.conf
```
cd /var/lib/pgsql/11/data/
cp postgresql.conf postgresql.bkp-antes-saude_s1
vim postgresql.conf
wal_level = logical
max_wal_senders = 3
max_replication_slots = 3
max_sync_workers_per_subscription = 2
```
Criar usuário replicação (via pgadmin):
```ruby
CREATE ROLE replicacao WITH LOGIN
SUPERUSER
INHERIT
REPLICATION
CONNECTION LIMIT -1
PASSWORD '123456';
```
Deve-se executar o script para criar a estrutura no banco slave, para isto edite o script de backup, o qual será feito download durante o processo de configuração:
```ruby
cd /root/
wget https://datacenter.atende.net/updates/backup_estrutura_ipmsaude_s1.sh
chmod 755 backup_estrutura_ipmsaude_s1.sh
# Altere
IP_Origem="127.0.0.1"
Porta_Origem="5432"
BD_Origem="00000_ipmsaude"
IP_Destino="192.168.21.28"
Porta_Destino="5432"
BD_Destino="00000_cliente"
# Execute o script - O backup e o log serão criados na storage de backup "X:\STORE\Transferir\00000_ipmsaude"
./backup_estrutura_ipmsaude_s1.sh &
# Ao final, confira os log´s.
cat XX*.log | grep ERROR | uniq -u (Substituir XX pelo nome do database de origem)
# Conferir se os Schemas foram criados, o comando deve retornar os Schemas restaurados, caso não existe favor verificar
cat XX*.log | grep "creating SCHEMA" | uniq -u (Substituir XX pelo nome do database de origem)
```
OBS: Os erros abaixo são normais de aparecer, pois relatam a ausência do schema webbased (IpmSaude) e a diferença entre versões do PostgreSQL.
```ruby
[2025-04-15 17:01:22] pg_restore: [arquivador] não pôde definir default_with_oids: ERROR: tables declared WITH OIDS are not supported
[2025-04-15 17:01:33] pg_restore: [arquivador] não pôde definir default_with_oids: ERROR: tables declared WITH OIDS are not supported
[2025-04-15 17:01:36] pg_restore: [arquivador] não pôde definir default_with_oids: ERROR: tables declared WITH OIDS are not supported
[2025-04-15 17:01:36] pg_restore: [arquivador] não pôde definir default_with_oids: ERROR: tables declared WITH OIDS are not supported
[2025-04-15 17:01:47] pg_restore: [arquivador (bd)] could not execute query: ERROR: function webbased.insere_registro_sigaf_entrada() does not exist
[2025-04-15 17:01:47] pg_restore: [arquivador (bd)] could not execute query: ERROR: function webbased.insere_registro_sigaf_baixa() does not exist
[2025-04-15 17:01:47] pg_restore: [arquivador (bd)] could not execute query: ERROR: function webbased.insere_registro_sigaf_imunizacao() does not exist
[2025-04-15 17:01:47] pg_restore: [arquivador (bd)] could not execute query: ERROR: function webbased.insere_registro_sigaf_saida() does not exist
[2025-04-15 17:01:47] pg_restore: [arquivador (bd)] could not execute query: ERROR: function webbased.insere_registro_sigaf_entrada_atualizacao() does not exist
[2025-04-15 17:01:47] pg_restore: [arquivador (bd)] could not execute query: ERROR: function webbased.remove_registro_sigaf_saida() does not exist
[2025-04-15 17:01:47] pg_restore: [arquivador (bd)] could not execute query: ERROR: function webbased.remove_registro_sigaf_entrada() does not exist
[2025-04-15 17:01:47] pg_restore: [arquivador (bd)] could not execute query: ERROR: function webbased.remove_registro_sigaf_baixa() does not exist
[2025-04-15 17:01:47] pg_restore: [arquivador (bd)] could not execute query: ERROR: function webbased.remove_registro_sigaf_imunizacao() does not exist
[2025-04-15 17:01:47] pg_restore: [arquivador (bd)] could not execute query: ERROR: relation "webbased.acao" does not exist
[2025-04-15 17:01:47] pg_restore: [arquivador (bd)] could not execute query: ERROR: relation "webbased.usuario" does not exist
[2025-04-15 17:01:49] pg_restore: [arquivador (bd)] could not execute query: ERROR: relation "webbased.acao" does not exist
[2025-04-15 17:01:49] pg_restore: [arquivador (bd)] could not execute query: ERROR: relation "webbased.rotina" does not exist
[2025-04-15 17:01:50] pg_restore: [arquivador (bd)] could not execute query: ERROR: relation "webbased.acao" does not exist
[2025-04-15 17:01:51] pg_restore: [arquivador (bd)] could not execute query: ERROR: relation "webbased.acao" does not exist
[2025-04-15 17:01:51] pg_restore: [arquivador (bd)] could not execute query: ERROR: relation "webbased.sistema" does not exist
[2025-04-15 17:01:51] pg_restore: [arquivador (bd)] could not execute query: ERROR: relation "webbased.usuario" does not exist
[2025-04-15 17:01:51] pg_restore: [arquivador (bd)] could not execute query: ERROR: relation "webbased.sistema" does not exist
[2025-04-15 17:01:52] pg_restore: [arquivador (bd)] could not execute query: ERROR: relation "webbased.usuario" does not exist
[2025-04-15 17:01:52] pg_restore: [arquivador (bd)] could not execute query: ERROR: relation "webbased.acao" does not exist
[2025-04-15 17:01:52] pg_restore: [arquivador (bd)] could not execute query: ERROR: relation "webbased.rotina" does not exist
[2025-04-15 17:01:52] pg_restore: [arquivador (bd)] could not execute query: ERROR: relation "webbased.grupo" does not exist
[2025-04-15 17:01:52] pg_restore: [arquivador (bd)] could not execute query: ERROR: relation "webbased.grupo" does not exist
[2025-04-15 17:01:52] pg_restore: [arquivador (bd)] could not execute query: ERROR: relation "webbased.rotina" does not exist
[2025-04-15 17:01:52] pg_restore: [arquivador (bd)] could not execute query: ERROR: relation "webbased.sistema" does not exist
[2025-04-15 17:01:52] pg_restore: [arquivador (bd)] could not execute query: ERROR: relation "webbased.rotina" does not exist
```
## Validações Banco Atende.Net
Executar scripts abaixo no banco de Destino (00000-cliente-bdp-01-1600.atende.net):
```ruby
-- Schema: migracao_saude
-- DROP SCHEMA migracao_saude;
CREATE SCHEMA migracao_saude
AUTHORIZATION dbaipm;
GRANT ALL ON SCHEMA migracao_saude TO dbaipm;
GRANT ALL ON SCHEMA migracao_saude TO administradores;
GRANT USAGE ON SCHEMA migracao_saude TO consultas;
GRANT ALL ON SCHEMA migracao_saude TO migradores;
GRANT ALL ON SCHEMA migracao_saude TO sistema;
```
Setar privilégios schemas saude:
```ruby
do
$body$
declare
r_objeto record;
begin
for r_objeto in (select 'GRANT ALL ON SCHEMA "'||pg_namespace.nspname||'" TO dbaipm;
GRANT ALL ON SCHEMA "'||pg_namespace.nspname||'" TO administradores;
GRANT USAGE ON SCHEMA "'||pg_namespace.nspname||'" TO consultas;
GRANT ALL ON SCHEMA "'||pg_namespace.nspname||'" TO migradores;
GRANT ALL ON SCHEMA "'||pg_namespace.nspname||'" TO sistema;' as cmd,
'"'||pg_namespace.nspname||'"' as nome
from pg_namespace
where translate(pg_namespace.nspname, '1234567890', '') in ('dcarq', '_fiarq', '_gtarq', '_isarq', '_nfarq', '_spunico', '_wgt', '_wnp', '_wsn', 'saudeweb', 'saudewebglo', 'spunico', 'migracao_fiscal', 'migracao_saude')
)
loop
--insert into replicacao.tblog (logacao, logquery) values ('Alterando grants do schema '||r_objeto.nome, r_objeto.cmd);
raise notice 'Alterando grants do schema %.', r_objeto.nome;
execute r_objeto.cmd;
end loop;
end;
$body$;
```
__ATENÇÃO: O RESTART DO SERVIÇO DE BANCO DE DADOS DEVERÁ SER EXECUTADO SOMENTE APÓS AS 18Hrs!__
```
systemctl restart postgresql-11.service
```
## Apagar Checks Not Valid
No servidor de Destino (Atende.Net), execute o script abaixo:
```ruby
/*Destino*/
create table tbscriptschecks as
WITH ORIG AS (
SELECT FORMAT('ALTER TABLE %s DROP CONSTRAINT %s;', CONRELID::REGCLASS::TEXT, CONNAME) AS DROPSCRIPT,
FORMAT('ALTER TABLE %s ADD CONSTRAINT %s %s;', CONRELID::REGCLASS::TEXT, CONNAME, PG_GET_CONSTRAINTDEF(OID)) AS CREATESCRIPT
FROM PG_CONSTRAINT
WHERE CONTYPE = 'c'
AND NOT CONVALIDATED
AND SUBSTRING(CONRELID::REGCLASS::TEXT,1,POSITION('.' IN CONRELID::REGCLASS::TEXT)-1) IN ('saudeweb','saudewebglo','spunico') )
SELECT ARRAY_TO_STRING(ARRAY(SELECT DROPSCRIPT FROM ORIG),CHR(13)||CHR(10)) DROPSCRIPT,
ARRAY_TO_STRING(ARRAY(SELECT CREATESCRIPT FROM ORIG),CHR(13)||CHR(10)) CREATESCRIPT
--Executar a saída do comando
select DROPSCRIPT from tbscriptschecks;
```
## Script de teste
IMPORTANTE: Necessário alterar as informações abaixo, para as desejadas.
Ex.: dbname=08573_ipmsaude e host="IP LAN do bdp-02-1150"
```ruby
# ORIGEM - IpmSaude S1 "bdp-02-1150"
create table replicacao.tbteste4(col1 integer primary key, col2 text);
insert into replicacao.tbteste4 values(1,'1');
select * from replicacao.tbteste4;
CREATE PUBLICATION publication_saude;
ALTER PUBLICATION publication_saude ADD table replicacao.tbteste4;
# DESTINO - Atende.Net "bdp-01-1600"
create table replicacao.tbteste4(col1 integer primary key, col2 text);
CREATE SUBSCRIPTION subscription_saude CONNECTION 'host=192.168.xx.xxx port=5432 user=replicacao dbname=00000_cliente' PUBLICATION publication_saude;
select * from replicacao.tbteste4; --Ja deve ter 1 registro
# ORIGEM - IpmSaude S1 "bdp-02-1150"
insert into replicacao.tbteste4 values(2,'2');
# DESTINO - Atende.Net "bdp-01-1600"
select * from replicacao.tbteste4; --Deve ter 2 registro
--Tudo deve estar funcionando. Pode apagar a tabela de teste
# ORIGEM - IpmSaude S1 "bdp-02-1150"
drop PUBLICATION publication_saude;
drop table replicacao.tbteste4;
# DESTINO - Atende.Net "bdp-01-1600"
ALTER SUBSCRIPTION subscription_saude REFRESH PUBLICATION;
ALTER SUBSCRIPTION subscription_saude DISABLE;
DROP SUBSCRIPTION subscription_saude;
DROP TABLE replicacao.tbteste4;
```