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

339 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 - 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`](./ativacao_slony.md)
## Destino - Banco Atende.Net
Realize a instalação do Slony no banco:
```
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
```
Realize a liberação do IP do Fiscal ou Vigilância no pg_hba do SGBD:
```
vim /var/lib/pgsql/11/data/pg_hba.conf
Ex.: host all all 172.16.1.18/32 trust
systemctl reload postgresql-11.service
```
Execute o SQL para criação da estrutura (schema replicacao) no SGBD de destino:
```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;
```
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
```
Criar tablespace replicacao:
```ruby
CREATE TABLESPACE replicacao
OWNER postgres
LOCATION '/var/lib/pgsql/11/tablespaces/replicacao';
```
## Origem - Configurando Node
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 => '172.24.1.24',
dbname => '08573_sc',
port => 65432,
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=IP_INT_RT port=65432 user=postgres';
store node (id=2, comment='Node 2 - 00000_cliente@IP_INT_RT', 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=IP_INT_RT port=65432 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, schema replicação, tabela tbclientenode (alterar o código do cliente) não necessário o SQL abaixo:
```ruby
insert into replicacao.tbclientenode (clicodigo, nodcodigo) values (88, 2);
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.
Obs: Para cada node SLAVE (Destino) adicional deve-se executar o procedimento descrito no chamado: 480647, anexo 9 (Migração Fiscal - Criando Nodes)
```
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
# Altere
cod_fiscal="8165" -- Código do schema (Fiscal)
IP_Destino="172.16.1.90" -- IP do Atende.Net - Servidor SLAVE (Destino)
Porta_Destino="65432" - Porta de acesso ao banco Atende.Net - Servidor SLAVE (Destino)
BD_Destino="01611_pinhais" - Nome do banco de dados do Atende.Net - Servidor SLAVE (Destino)
# Execute o script - O backup e o log serão criados na storage de backup "X:\STORE\Transferir\00002_ipmfiscal"
su - postgres
./backup_estrutura_slony.sh
# Ao final, confira os log´s.
cat 8561*.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 8561*.log | grep "creating SCHEMA 8561" | uniq -u (Substituir pelo Código do Schema)
```
## Validações
Validar Schema migracao_fiscal foi criado no banco destino, e setar os privilégios para o mesmo:
```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 para demais schemas referentes ao Fiscal também no SGDB de Destino (cliente):
```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')
)
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$;
```
Após a restauração e conferencia dos logs, com o usuário root no SGDB Origem inicie o Node:
```ruby
/usr/local/slony1/bin/slon_start 2 (Indique o node que deseja iniciar)
```
## Script de teste
```ruby
# Master (Origem)
create table replicacao.tbteste2(col1 integer primary key, col2 text);
insert into replicacao.tbteste2 values(1,'1');
select * from replicacao.tbteste2;
# Slave (destino)
create table replicacao.tbteste2(col1 integer primary key, col2 text);
# Master (origem)
select replicacao.fn_prepara_contexto('Teste Inicial 2', string_to_array('replicacao.tbteste2',','));
select replicacao.fn_inicia_replicacao_contexto('Teste Inicial 2', 512); --Segundo parametro é o código do cliente (CÓDIGO DO SISTEMA NO GDT)
# Slave (destino)
select * from replicacao.tbteste2; --Já deve ter 1 registro
# Master (origem)
insert into replicacao.tbteste2 values(2,'2');
# Slave (destino)
select * from replicacao.tbteste2; --Deve ter 2 registro
--Tudo deve estar funcionando. Pode apagar a tabela de teste
# Master (origem)
select replicacao.fn_interrompe_replicacao('Teste Inicial 2');
drop table replicacao.tbteste2;
# Slave (destino)
drop table replicacao.tbteste2;
```
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();
```