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

783 lines
30 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 - Adicionando Novo Node no Slony
### IMPORTANTE
Esse manual é um passo a passo do procedimento de inclusão de um novo Node (Cliente) no serviço do Slony já instalado.
Caso precise realizar uma instalação Inicial (partindo do zero) utilize o manual:
[`Ativação Slony Fiscal - Inicial`](./replicacao_slony_fiscal_s1.md)
### Abaixo a representação do funcionamento da estrutura:
![Diagrama_Funcionamento_Replicacao](../img/diagrama_replicacao_postgres16.png)
## Destino - Banco Fiscal Slony (00002_www.nfs-e.net_SGDB_1150_SLONY - 192.168.23.11)
Checar se o Slony esta instalado e executando:
```
rpm -qi slony1_11
```
Caso receba o retorno que a aplicação <b> não está instalada </b>, execute a instalação conforme os passos abaixo:
```
cd /root/
wget https://datacenter.atende.net/updates/slony1_11.zip
unzip slony1_11.zip
cd slony
rpm -Uvh slony1_11-2.2.10-1.rhel8.x86_64.rpm perl-Switch-2.17-10.el8.noarch.rpm perl-DBD-Pg-3.7.4-4.module_el8.3.0+426+0b4e9c0a.x86_64.rpm perl-Text-Balanced-2.03-395.el8.noarch.rpm perl-Filter-1.58-2.el8.x86_64.rpm perl-SelfLoader-1.23-416.el8.noarch.rpm
```
Verificar se o IP do banco Master do Fiscal S1 esta liberado no pg_hba.conf
Também liberar o IP da INT_RT do cliente que esta sendo configurado!
```
vim /var/lib/pgsql/11/data/pg_hba.conf
Ex.: host all all 192.168.23.10/32 trust (Libera Fiscal S1)
Ex: host all all 172.16.XXX.XXX/32 trust (IP INT_RT do Cliente)
systemctl reload postgresql-11.service
```
Conferir as configurações do postgresql.conf (/var/lib/pgsql/11/data/postgresql.conf)
```
wal_level = logical
max_wal_senders = 10
max_replication_slots = 10
max_sync_workers_per_subscription = 2
```
Conferir se o usuário replicação existe no Banco de Dados (via pgAdmin):
```
login roles > replicacao
Caso não existe, crie o mesmo:
CREATE ROLE replicacao WITH LOGIN
SUPERUSER
INHERIT
REPLICATION
CONNECTION LIMIT -1
PASSWORD '123456';
```
Efetue a criação do database conforme o cliente que você esta ativando a replicação via Slony
```
Exemplo: 00000_cliente
CREATE DATABASE "00000_cliente"
WITH ENCODING='LATIN1'
OWNER=dbaipm
TEMPLATE=template0
TABLESPACE = pg_default
LC_COLLATE = 'pt_BR'
LC_CTYPE = 'pt_BR'
CONNECTION LIMIT=-1;
```
Setar os defaults privilégios para o Data Base (substituir o nome 00000_cliente pelo código e nome do cliente):
```
GRANT ALL ON DATABASE "00000_cliente" TO dbaipm;
GRANT ALL ON DATABASE "00000_cliente" TO administradores;
GRANT CONNECT ON DATABASE "00000_cliente" TO consultas;
GRANT ALL ON DATABASE "00000_cliente" TO migradores;
GRANT ALL ON DATABASE "00000_cliente" TO sistema;
REVOKE ALL ON DATABASE "00000_cliente" FROM public;
ALTER DEFAULT PRIVILEGES
GRANT INSERT, SELECT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON TABLES
TO administradores WITH GRANT OPTION;
ALTER DEFAULT PRIVILEGES
GRANT SELECT ON TABLES
TO consultas WITH GRANT OPTION;
ALTER DEFAULT PRIVILEGES
GRANT INSERT, SELECT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON TABLES
TO migradores WITH GRANT OPTION;
ALTER DEFAULT PRIVILEGES
GRANT INSERT, SELECT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON TABLES
TO sistema WITH GRANT OPTION;
ALTER DEFAULT PRIVILEGES
GRANT INSERT, SELECT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON TABLES
TO atualizacao;
ALTER DEFAULT PRIVILEGES
GRANT SELECT, UPDATE, USAGE ON SEQUENCES
TO administradores WITH GRANT OPTION;
ALTER DEFAULT PRIVILEGES
GRANT USAGE ON SEQUENCES
TO consultas WITH GRANT OPTION;
ALTER DEFAULT PRIVILEGES
GRANT SELECT, UPDATE, USAGE ON SEQUENCES
TO migradores WITH GRANT OPTION;
ALTER DEFAULT PRIVILEGES
GRANT SELECT, UPDATE, USAGE ON SEQUENCES
TO sistema WITH GRANT OPTION;
ALTER DEFAULT PRIVILEGES
GRANT SELECT, UPDATE, USAGE ON SEQUENCES
TO atendenetweb;
ALTER DEFAULT PRIVILEGES
GRANT EXECUTE ON FUNCTIONS
TO public;
ALTER DEFAULT PRIVILEGES
GRANT EXECUTE ON FUNCTIONS
TO administradores WITH GRANT OPTION;
ALTER DEFAULT PRIVILEGES
GRANT EXECUTE ON FUNCTIONS
TO consultas WITH GRANT OPTION;
ALTER DEFAULT PRIVILEGES
GRANT EXECUTE ON FUNCTIONS
TO migradores WITH GRANT OPTION;
ALTER DEFAULT PRIVILEGES
GRANT EXECUTE ON FUNCTIONS
TO sistema WITH GRANT OPTION;
ALTER DEFAULT PRIVILEGES
GRANT EXECUTE ON FUNCTIONS
TO dbaipm;
```
Criar as extensões
```
CREATE EXTENSION pg_buffercache;
CREATE EXTENSION pg_freespacemap;
CREATE EXTENSION pg_stat_statements;
CREATE EXTENSION btree_gist;
CREATE EXTENSION postgis;
CREATE EXTENSION postgis_sfcgal;
```
Execute o SQL para criação da estrutura (schema replicacao) no SGBD de destino na database criada no passo anterior:
```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;
```
Verificar se o disco de 1,2 TB esta adicionado no Destino:
```
Disco: /var/lib/pgsql/11/tablespaces/replicacao
[root@00002-NFSE_SGDB_1150_SLONY ~]# df -h
Sist. Arq. Tam. Usado Disp. Uso% Montado em
devtmpfs 8,8G 0 8,8G 0% /dev
tmpfs 8,8G 12K 8,8G 1% /dev/shm
tmpfs 8,8G 8,8M 8,8G 1% /run
tmpfs 8,8G 0 8,8G 0% /sys/fs/cgroup
/dev/mapper/cl_00000--clean--centos8-root 15G 4,9G 11G 33% /
/dev/mapper/cl_00000--clean--centos8-home 2,4G 50M 2,4G 3% /home
/dev/sda2 976M 179M 731M 20% /boot
/dev/mapper/sgdb04-dados 119G 921M 119G 1% /var/lib/pgsql/11
/dev/sda1 599M 6,7M 593M 2% /boot/efi
/dev/mapper/sgdb01-pg_log 19G 168M 19G 1% /var/lib/pgsql/11/data/log
/dev/mapper/sgdb03-indices 89G 668M 89G 1% /var/lib/pgsql/11/tablespaces/indice
/dev/mapper/sgdb02-pg_wal 29G 272M 29G 1% /var/lib/pgsql/11/data/pg_wal
/dev/mapper/cl_00000--clean--centos8-var_log 15G 347M 15G 3% /var/log
tmpfs 1,8G 0 1,8G 0% /run/user/0
/dev/mapper/sgdb10-replicacao 1,3T 8,7G 1,2T 1% /var/lib/pgsql/11/tablespaces/replicacao
[root@00002-NFSE_SGDB_1150_SLONY ~]#
```
<b> IMPORTANTE: EXECUTAR O PASSO ABAIXO APENAS SE O DISCO NÃO EXISTIR NO SERVIDOR LINUX E O TABLESPACE REPLICACAO NÃO EXISTA NO BANCO DE DADOS DE DESTINO!</b>
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.
```
lsblk
fdisk /dev/sde
#Dispositivo Inicializar Início Fim Setores Tamanho Id Tipo
#/dev/sde1 2048 2587885567 2587883520 1,2T 8e Linux LVM
vgcreate sgdb10 /dev/sde1
lvcreate -L +1233G -n replicacao sgdb10
mkfs.xfs /dev/mapper/sgdb10-replicacao
vim /etc/fstab
/dev/mapper/sgdb10-replicacao /var/lib/pgsql/11/tablespaces/replicacao xfs defaults 0 1
mkdir -p /var/lib/pgsql/11/tablespaces/replicacao
mount /var/lib/pgsql/11/tablespaces/replicacao
chown postgres.postgres /var/lib/pgsql/11/tablespaces/replicacao/ -R
chmod 700 /var/lib/pgsql/11/tablespaces/replicacao/ -R
```
Verificar se o tablespace replicacao existe via PGAdmin. Caso não exista execute a criação da mesma:
```ruby
CREATE TABLESPACE replicacao
OWNER postgres
LOCATION '/var/lib/pgsql/11/tablespaces/replicacao';
```
## Destino - Banco Cliente Versão 16 (00000-clean-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.
Criando pasta:
```
su - root
```
```
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
```
Montando 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.18/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 tablespace e schema 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;
```
## Origem - Banco Fiscal (00002_www.nfs-e.net_SGDB - 192.168.23.10)
Altere os dados conforme os do cliente que irá fazer a replicação:
```
vim /usr/local/slony1/etc/slon_tools.conf
$CLUSTER_NAME = 'replication_ipmfiscal';
add_node(
node => 1,
host => '192.168.23.10',
dbname => '00002_ipmfiscal',
port => 5432,
user => 'postgres',
password => ''
);
add_node(
node => 2,
host => '192.168.23.11',
dbname => '00000_cliente',
port => 5432,
user => 'postgres',
password => ''
);
```
Quando finalizada a configuração do Slave, deve-se prosseguir com o próximo passo:
Navegue até a pasta e crie o arquivo de configuração para criação do novo Node
No nome do arquivo siga o padrão dos demais (create_node_"numerodonode"_"nomedocliente".cmd)
cd /usr/local/slony1/bin/
vim create_node_2_cliente.cmd
```
cluster name=replication_ipmfiscal;
node 1 admin conninfo ='dbname=00002_ipmfiscal host=127.0.0.1 user=postgres';
node 2 admin conninfo ='dbname=00000_cliente host=192.168.23.11 port=5432 user=postgres'; #(Servidor:00002_www.nfs-e.net_SGDB_1150_SLONY )
store node (id=2, comment='Node 2 - [email protected]', event node=1);
store path(server=1,client=2,conninfo='host=127.0.0.1 dbname=00002_ipmfiscal user=postgres');
store path(server=2,client=1,conninfo='host=192.168.23.11 port=5432 dbname=00000_cliente user=postgres');
```
Após configurado, salve o arquivo e execute o comando abaixo indicando o arquivo que acabou de ser configurado:
```
/usr/local/slony1/bin/slonik /usr/local/slony1/bin/create_node_"numerodonode"_"nomedocliente".cmd
```
Acessar o banco do fiscal, e executar o SQL abaixo:
clicodigo = (Codigo do sistema) do cliente no Atende.Net
nodcodigo - Código do node criado no slon_tools.conf ou no arquivo relacionado a sua adição no master.
```ruby
insert into replicacao.tbclientenode (clicodigo, nodcodigo) values (55, 2);
```
Ao final, 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" (Script: backup_estrutura_slony.sh)
```ruby
su - postgres
vim backup_estrutura_slony.sh
# Altere
cod_fiscal="8043" -- Código do schema (Fiscal)
# Destino 11 Fiscal Slony
IP_Destino_11="192.168.23.11" (IP do Banco de Dados do Slony intermediário, não precisa ser alterado)
Porta_Destino_11="5432" (Portal default sem necessidade de alterar)
BD_Destino_11="00000_teste" (Informe o database do cliente que irá ativar a replicacao)
# Destino Cliente Atende
IP_Destino_16="172.16.XXX.XXX ou 172.24.XXX.XXX" (Informe a INT_RT do cliente Atende.Net - Banco de Dados PostgreSQL 16)
Porta_Destino_16="65432" (Porta default)
BD_Destino_16="00000_teste" (Informe o nome da database do cliente)
# Execute o script - O backup e o log serão criados na storage de backup "X:\STORE\Transferir\00002_ipmfiscal"
./backup_estrutura_slony.sh &
# Ao realizar a conferencia, alguns erros serão normais, pois o Fiscal S1 possui tabelas globais que estão vinculadas a todos os clientes. Na dúvida após a consulta dos logs, verificar com o Richard se trata-se de erros já conhecidos e "normais".
# Ao final, confira os log´s.
cat 8043*.log | grep ERROR | uniq -u
# Conferir se os Schemas foram criados, o comando deve retornar os Schemas restaurados, caso não existe favor verificar
cat 8043*.log | grep "creating SCHEMA 8043" | uniq -u (Substituir pelo Código do Schema)
```
Com o usuário "root", inicie o node:
```ruby
su - root
/usr/local/slony1/bin/slon_start "numerodonode"
```
## Validações (00002_www.nfs-e.net_SGDB_1150_SLONY - 192.168.23.11 e 00000-cliente-bdp-01-1600.atende.net)
> Validações devem ocorrer nos dois bancos de dados (Fiscal Slony e no Banco de Dados PostgreSQL 16 do cliente.)
Verificar se o Schema migracao_fiscal esta criado nos dois servidores, caso não execute o create abaixo!
```ruby
-- Schema: migracao_fiscal
-- DROP SCHEMA migracao_fiscal;
CREATE SCHEMA migracao_fiscal
AUTHORIZATION dbaipm;
```
Caso exista ou você acabou de criar, será necessário dar as permissões para o Schema, para isso execute os GRANTS nos dois ambientes:
```ruby
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$;
```
Liberar porta 65434 no Firewall do cliente, para a conexão entre PG11 x PG16:
Vá em: Firewall > Rules > LAN
Destination: 65434
Description: Bdp-1150-SLONY
![Libera Porta Firewall](../img/libera_porta_firewall_replicacao.png)
## Script de teste
```ruby
# Master (Origem)
create table replicacao.tbteste4(col1 integer primary key, col2 text);
insert into replicacao.tbteste4 values(1,'1');
select * from replicacao.tbteste4;
# Slave (11.5)
create table replicacao.tbteste4(col1 integer primary key, col2 text);
# Destino (16)
create table replicacao.tbteste4(col1 integer primary key, col2 text);
# Master (origem)
select replicacao.fn_prepara_contexto('Teste Inicial 4', string_to_array('replicacao.tbteste4',','));
select replicacao.fn_inicia_replicacao_contexto('Teste Inicial 4', 55); --Segundo parametro é o código do cliente (CÓDIGO DO SISTEMA NO GDT)
# Slave (11.5)
select * from replicacao.tbteste4; --Já deve ter 1 registro
CREATE PUBLICATION publication_mig_ipm_fiscal_00000_cliente;
ALTER PUBLICATION publication_mig_ipm_fiscal_00000_cliente ADD table replicacao.tbteste4;
# Destino (16)
CREATE SUBSCRIPTION subscription_mig_ipm_fiscal_00000_cliente CONNECTION 'host=172.16.1.18 port=65434 user=replicacao dbname=00000_cliente' PUBLICATION publication_mig_ipm_fiscal_00000_cliente;
select * from replicacao.tbteste4;
# Master (origem)
insert into replicacao.tbteste4 values(2,'2');
# Slave (11.5)
select * from replicacao.tbteste4; --Deve ter 2 registro
--Tudo deve estar funcionando. Pode apagar a tabela de teste
# Destino (16)
select * from replicacao.tbteste4; --Deve ter 2 registro
--Tudo deve estar funcionando. Pode apagar a tabela de teste
# Master (origem)
select replicacao.fn_interrompe_replicacao('Teste Inicial 4');
drop table replicacao.tbteste4;
# Slave (11.5)
drop PUBLICATION publication_mig_ipm_fiscal_00000_cliente;
drop table replicacao.tbteste4;
# Destino (16)
ALTER SUBSCRIPTION subscription_mig_ipm_fiscal_00000_cliente DISABLE;
DROP SUBSCRIPTION subscription_mig_ipm_fiscal_00000_cliente;
drop table replicacao.tbteste4;
```
Após os testes, executar o comando abaixo para verificar o LagTime no Servidor Master.
Esse select irá retornar o tempo de todos os nodes ativos via Slony (replicação). O retorno será apenas o tempo do lagtime e o mesmo deverá sempre estar variando (descendo e subindo), se estiver com mais de 10 minutos acumulado considera que possa haver algum probelma.
```ruby
select * from replicacao.status();
```
[`Início`](replicacao_slony_fiscal_s1.md)