# 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 ``` ATENÇÃO: O RESTART DO SERVIÇO DE BANCO DE DADOS DEVERÁ SER EXECUTADO APÓS AS 18H! (systemctl restart postgresql.service) 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 ``` ATENÇÃO: O RESTART DO SERVIÇO DE BANCO DE DADOS DEVERÁ SER EXECUTADO APÓS AS 18H! (systemctl restart postgresql.service) 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; ```