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

357 lines
14 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 - Fiscal S1
>Documentação do procedimento de ativação da replicação do sistema Fiscal S-1 para o S-2, para os casos onde a Origem está na versão 11.5 e destino no 16.
Como exemplo: pr.nfs-e.net, rs.nfs-e.net e sc.nfs-e.net
>Caso deseja ativar replicação com a origem na versão 9.3, deve-se seguir esta documentação [`Ativação Slony Fiscal - Inicial`](./replicacao_slony_fiscal_s1.md)
## 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_interromper.md)
[`2 - Remover Estrutura`](../docs/replicacao_nativa_remover_estrutura.md)
## Destino - Banco Cliente Versão 16 (00000-cliente-bdp-01-1600.atende.net)
No banco do cliente (PostgreSQL16), criar um disco para a replicação do Fiscal:
>Deve-se adicionar um HD temporário ao servidor SLAVE (destino) do banco de dados 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 slony
/dev/disk/by-id/dm-uuid-LVM-My295Ba6z7Vl5TX7eyue3b5bCCOtX1NfqddL0ZoIJLfOjD0N9deI8yySYvvRff3h /var/lib/postgresql/16/tablespaces/replicacao xfs defaults,noatime,nodiratime 0 1
Montar o disco:
mount /var/lib/postgresql/16/tablespaces/replicacao
Aplicando permissão para o diretório:
chown postgres.postgres /var/lib/postgresql/16/tablespaces/replicacao
```
Verificar se o IP do banco Master do Fiscal S1 esta liberado no pg_hba.conf
```
vim /etc/postgresql/16/main/pg_hba.conf
Ex.: host all all 172.16.1.xxx/32 trust (Libera Fiscal S1)
systemctl reload postgresql.service
```
Conferir configurações no arquivo postgresql.conf:
```
cd /etc/postgresql/16/main/
cp postgresql.conf postgresql.bkp-antesslony
vim postgresql.conf
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
OBSERVAÇÃO: Se o parametro estiver max_worker_processes = 3, deverá ser alterado para max_worker_processes = 4
```
<b> ATENÇÃO: O RESTART DO SERVIÇO DE BANCO DE DADOS DEVERÁ SER EXECUTADO APÓS AS 18H!
(systemctl restart postgresql.service)</b>
Criar a tablespace replicacao para recebimento dos dados:
```ruby
CREATE TABLESPACE replicacao
OWNER postgres
LOCATION '/var/lib/postgresql/16/tablespaces/replicacao';
```
```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;
```
Liberar porta 65432 no Firewall do cliente, para a conexão entre PG11 x PG16:
Vá em: Firewall > Rules > LAN
Destination: 65432
Description: Bdp-1150-Fiscal
![Libera Porta Firewall](../img/libera_porta_firewall_replicacao_nativa.png)
## Origem - Banco Fiscal S-1
Liberar IP do cliente no hba, apenas para o usuario replicação. Inserir linha conforme abaixo:
```
cd /var/lib/pgsql/11/data/
vim pg_hba.conf
Ex.: host all replicacao 172.XX.1.XX/32 trust
systemctl reload postgresql-11.service
```
Alterar as configurações do postgresql.conf
```
cd /var/lib/pgsql/11/data/
cp postgresql.conf postgresql.bkp-antesslony
vim postgresql.conf
wal_level = logical
max_wal_senders = 5
max_replication_slots = 6
max_sync_workers_per_subscription = 2
```
<b> ATENÇÃO: O RESTART DO SERVIÇO DE BANCO DE DADOS DEVERÁ SER EXECUTADO APÓS AS 18H!
(systemctl restart postgresql.service)</b>
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 que fica no servidor master(IPMFiscal)
```ruby
su - root
vim backup_estrutura_slony_ipmfiscal.sh
# Altere
cod_fiscal="XXX"
IP_Destino="172.XX.1.XX"
Porta_Destino="65432"
BD_Destino="00000_cliente"
# Execute o script - O backup e o log serão criados na storage de backup "X:\STORE\Transferir\00002_ipmfiscal"
./backup_estrutura_slony_ipmfiscal.sh
# Ao final, confira os log´s.
cat XX*.log | grep ERROR | uniq -u (Substituir pelo Código do Schema)
# 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 pelo Código do Schema)
```
## Validações
Executar scripts abaixo no banco de DESTINO:
```ruby
-- Schema: migracao_fiscal
-- DROP SCHEMA migracao_fiscal;
CREATE SCHEMA migracao_fiscal
AUTHORIZATION dbaipm;
GRANT ALL ON SCHEMA migracao_fiscal TO dbaipm;
GRANT ALL ON SCHEMA migracao_fiscal TO administradores;
GRANT USAGE ON SCHEMA migracao_fiscal TO consultas;
GRANT ALL ON SCHEMA migracao_fiscal TO migradores;
GRANT ALL ON SCHEMA migracao_fiscal TO sistema;
```
Setar privilégios schemas fiscal:
```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$;
```
## Script de teste
IMPORTANTE: Necessário alterar as informações abaixo, para as desejadas.
Ex.: dbname, 00000_cliente e host
```ruby
# ORIGEM - Fiscal S1
create table replicacao.tbteste2(col1 integer primary key, col2 text);
insert into replicacao.tbteste2 values(1,'1');
select * from replicacao.tbteste2;
create publication publication_mig_ipm_fiscal_00000_cliente;
alter publication publication_mig_ipm_fiscal_00000_cliente add table replicacao.tbteste2;
# DESTINO - Cliente bdp-01-1600
create table replicacao.tbteste2(col1 integer primary key, col2 text);
create subscription subscription_mig_ipm_fiscal_00000_cliente connection 'host=172.16.1.xx port=65432 user=replicacao dbname=00002_ipmfiscal_xx' publication publication_mig_ipm_fiscal_00000_cliente;
select * from replicacao.tbteste2;
# ORIGEM - Fiscal S1
insert into replicacao.tbteste2 values(2,'2');
# DESTINO - Cliente bdp-01-1600
select * from replicacao.tbteste2;
# ORIGEM - Fiscal S1
drop publication publication_mig_ipm_fiscal_00000_cliente;
drop table replicacao.tbteste2;
# DESTINO - Cliente bdp-01-1600
alter subscription subscription_mig_ipm_fiscal_00000_cliente disable;
drop subscription subscription_mig_ipm_fiscal_00000_cliente;
drop table replicacao.tbteste2;
```