27 KiB
Roteiro de Ativação do Slony
LEIA - IMPORTANTE
Caso queira ativar o Slony pela primeira vez utilize o manual seguindo os passos abaixo. Porém caso queira apenas adicionar um novo Node em uma estrutura do Slony já configurada (Exemplo Fiscal S1), siga o passo a passo do roteiro a seguir:
Ativação Slony Fiscal - Adicionando Novo Node
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:
--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:
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:
/usr/local/slony1/bin/slonik_init_cluster | /usr/local/slony1/bin/slonik
Após, inicie o cluster:
/usr/local/slony1/bin/slon_start 1
/usr/local/slony1/bin/slon_start 2
Atualize as funções no master:
CREATE SCHEMA replicacao;
CREATE TABLE replicacao.tbclientenode
(
clicodigo integer not null,
nodcodigo integer not null
);
ALTER TABLE replicacao.tbclientenode
ADD CONSTRAINT pk_tbclientenode PRIMARY KEY(nodcodigo);
CREATE UNIQUE INDEX idx_unique_tbclientenode_cliente
ON replicacao.tbclientenode (clicodigo);
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);
drop function if exists replicacao.fn_inicia_replicacao(s_contexto text, a_tabelas text[], i_clicodigo integer);
create or replace function replicacao.fn_get_schema_slony()
returns text as
$body$
begin
return (select schemaname
from pg_tables
where tablename = 'sl_node');
end;
$body$
LANGUAGE plpgsql VOLATILE;
create or replace function replicacao.fn_adiciona_schema_slony_search_path()
returns boolean as
$body$
declare
s_search_path text;
s_schema_name text;
begin
s_schema_name := (select replicacao.fn_get_schema_slony());
s_search_path := pg_catalog.current_setting('search_path');
s_search_path := s_search_path||', '||s_schema_name;
PERFORM pg_catalog.set_config('search_path', s_search_path, true);
return true;
end;
$body$
LANGUAGE plpgsql VOLATILE;
create or replace function replicacao.fn_remove_schema_slony_search_path()
returns boolean as
$body$
declare
s_search_path text;
s_schema_name text;
begin
s_schema_name := (select replicacao.fn_get_schema_slony());
s_search_path := pg_catalog.current_setting('search_path');
s_search_path := replace(s_search_path, ', '||s_schema_name, '');
PERFORM pg_catalog.set_config('search_path', s_search_path, true);
return true;
end;
$body$
LANGUAGE plpgsql VOLATILE;
create or replace function replicacao.status()
returns table(cliente integer, lagtime interval, lastevent bigint, lastreceived bigint, sincronizado boolean) as
$body$
begin
perform (select replicacao.fn_adiciona_schema_slony_search_path());
drop table if exists tbreturn;
create temp table tbreturn as
select tbclientenode.clicodigo as cliente,
sl_status.st_lag_time as lagtime,
sl_status.st_last_event as lastevent,
sl_status.st_last_received as lastreceived,
sl_status.st_last_event = sl_status.st_last_received as sincronizado
from sl_status
left join replicacao.tbclientenode
on tbclientenode.nodcodigo = sl_status.st_received;
perform (select replicacao.fn_remove_schema_slony_search_path());
return query(select * from tbreturn);
end;
$body$
LANGUAGE plpgsql VOLATILE;
CREATE OR REPLACE FUNCTION replicacao.fn_get_node_by_clicodigo(i_clicodigo integer)
RETURNS integer AS
$BODY$
declare
i_node integer;
begin
select nodcodigo
into i_node
from replicacao.tbclientenode
where clicodigo = i_clicodigo;
if (i_node is null) then
raise exception 'Não foi possível encontrar um node de replicação para o cliente %.', i_clicodigo;
end if;
return i_node;
end
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
CREATE OR REPLACE FUNCTION replicacao.fn_prepara_contexto(
s_contexto text,
a_tabelas text[])
RETURNS boolean AS
$BODY$
declare
i_set integer;
s_pk text;
r_tabela record;
begin
perform replicacao.fn_adiciona_schema_slony_search_path();
insert into replicacao.tblog (logacao) values ('fn_prepara_contexto');
lock table sl_event;
if exists(select 1 from pg_event_trigger where evtname = 'tg_event_trigger_on_execute_ddl_replicacao_ipm') then
ALTER EVENT TRIGGER tg_event_trigger_on_execute_ddl_replicacao_ipm DISABLE;
end if;
if exists(select 1 from sl_set where set_comment = s_contexto) then
raise exception 'O contexto "%", já existe.', s_contexto;
else
select coalesce(max(set_id),0)+1 into i_set from sl_set;
perform storeset(i_set, s_contexto);
end if;
for r_tabela in select unnest(a_tabelas) as nometabela
loop
if (position('webbased.' in lower(r_tabela.nometabela)) > 0) then
raise exception 'A tabela "%", está relacionada ao schema webbased, o qual não deve ser replicado.', r_tabela.nometabela;
end if;
if (exists(select 1
from sl_table
where tab_nspname||'.'||tab_relname = r_tabela.nometabela)) then
raise exception 'A tabela "%", já está sendo replicada.', r_tabela.nometabela;
end if;
select indice.relname
into s_pk
from pg_class tabela
left join pg_namespace
on pg_namespace.oid = tabela.relnamespace
left join pg_index
on pg_index.indrelid = tabela.oid
left join pg_class indice
on indice.oid = pg_index.indexrelid
where pg_namespace.nspname||'.'||tabela.relname = r_tabela.nometabela
and pg_index.indisprimary;
if coalesce(s_pk,'') = '' then
raise exception 'A tabela "%", não possui chave primária.', r_tabela.nometabela;
end if;
perform setaddtable(i_set, (select coalesce(max(tab_id),0)+1 from sl_table), r_tabela.nometabela, s_pk, '');
end loop;
if exists(select 1 from pg_event_trigger where evtname = 'tg_event_trigger_on_execute_ddl_replicacao_ipm') then
ALTER EVENT TRIGGER tg_event_trigger_on_execute_ddl_replicacao_ipm ENABLE;
end if;
perform replicacao.fn_remove_schema_slony_search_path();
return true;
end
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
CREATE OR REPLACE FUNCTION replicacao.fn_inicia_replicacao_contexto(
s_contexto text,
i_clicodigo integer)
RETURNS boolean AS
$BODY$
begin
perform replicacao.fn_adiciona_schema_slony_search_path();
insert into replicacao.tblog (logacao) values ('fn_inicia_replicacao_contexto');
if exists(select 1 from pg_event_trigger where evtname = 'tg_event_trigger_on_execute_ddl_replicacao_ipm') then
ALTER EVENT TRIGGER tg_event_trigger_on_execute_ddl_replicacao_ipm DISABLE;
end if;
perform replicacao.fn_adiciona_slave_replicacao(s_contexto, i_clicodigo);
if exists(select 1 from pg_event_trigger where evtname = 'tg_event_trigger_on_execute_ddl_replicacao_ipm') then
ALTER EVENT TRIGGER tg_event_trigger_on_execute_ddl_replicacao_ipm ENABLE;
end if;
perform replicacao.fn_remove_schema_slony_search_path();
return true;
end
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
CREATE OR REPLACE FUNCTION replicacao.fn_interrompe_replicacao(s_contexto text)
RETURNS boolean AS
$BODY$
declare
i_set integer;
begin
perform replicacao.fn_adiciona_schema_slony_search_path();
insert into replicacao.tblog (logacao) values ('fn_interrompe_replicacao('''||s_contexto||''')');
if not exists(select 1 from sl_set where set_comment = s_contexto) then
raise exception 'O contexto "%", não existe.', s_contexto;
else
select set_id into i_set from sl_set where set_comment = s_contexto;
end if;
perform dropset(i_set);
perform replicacao.fn_remove_schema_slony_search_path();
return true;
end
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
CREATE OR REPLACE FUNCTION replicacao.fn_interrompe_replicacao_tabela(s_tabela text)
RETURNS boolean AS
$BODY$
begin
perform replicacao.fn_adiciona_schema_slony_search_path();
insert into replicacao.tblog (logacao) values ('fn_interrompe_replicacao_tabela('''||s_tabela||''')');
if (not exists(select tab_id
from sl_table
where tab_nspname||'.'||tab_relname = s_tabela)) then
raise exception 'A tabela "%", não está sendo replicada.', s_tabela;
end if;
perform setdroptable((select tab_id
from sl_table
where tab_nspname||'.'||tab_relname = s_tabela));
perform replicacao.fn_remove_schema_slony_search_path();
return true;
end
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
CREATE OR REPLACE FUNCTION replicacao.fn_adiciona_slave_replicacao(
s_contexto text,
i_clicodigo integer)
RETURNS boolean AS
$BODY$
declare
i_set integer;
i_node_master integer;
i_node_slave integer;
begin
perform replicacao.fn_adiciona_schema_slony_search_path();
i_node_master = 1;
i_node_slave = replicacao.fn_get_node_by_clicodigo(i_clicodigo);
insert into replicacao.tblog (logacao) values ('fn_adiciona_slave_replicacao');
if not exists(select 1 from sl_set where set_comment = s_contexto) then
raise exception 'O contexto "%", não existe.', s_contexto;
else
select set_id into i_set from sl_set where set_comment = s_contexto;
if exists(select 1 from sl_set where set_comment = s_contexto and age(xmin) = 0) then
raise exception 'O contexto "%", não deve ser preparado e iniciado na mesma execução.', s_contexto;
end if;
end if;
if not exists(select 1 from sl_node where no_id = i_node_master) then
raise exception 'O node de replicação "%", não existe.', i_node_master;
end if;
if not exists(select 1 from sl_node where no_id = i_node_slave) then
raise exception 'O node de replicação "%", não existe.', i_node_slave;
end if;
perform subscribeset(i_set, i_node_master, i_node_slave, false, false);
perform replicacao.fn_remove_schema_slony_search_path();
return true;
end
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
CREATE OR REPLACE FUNCTION replicacao.fn_interrompe_replicacao_tabelas_sem_slave()
RETURNS boolean AS
$BODY$
declare
s_objetos text;
r_record record;
begin
perform replicacao.fn_adiciona_schema_slony_search_path();
insert into replicacao.tblog (logacao) values ('fn_interrompe_replicacao_tabelas_sem_slave');
lock table sl_set;
for r_record in
select sl_table.tab_nspname||'.'||sl_table.tab_relname as table
from sl_table
left join sl_set
on sl_set.set_id = sl_table.tab_set
left join sl_subscribe
on sl_subscribe.sub_set = sl_set.set_id
where sl_subscribe.sub_receiver is null
loop
perform replicacao.fn_interrompe_replicacao_tabela(r_record.table);
end loop;
perform replicacao.fn_remove_schema_slony_search_path();
perform replicacao.fn_adiciona_schema_slony_search_path();
for r_record in
select sl_set.set_comment as contexto
from sl_set
left join sl_subscribe
on sl_subscribe.sub_set = sl_set.set_id
where sl_subscribe.sub_receiver is null
loop
perform replicacao.fn_interrompe_replicacao(r_record.contexto);
end loop;
perform replicacao.fn_remove_schema_slony_search_path();
return true;
end
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
CREATE OR REPLACE FUNCTION replicacao.fn_remove_slave_replicacao(
s_contexto text,
i_clicodigo integer)
RETURNS text AS
$BODY$
declare
i_set integer;
i_node_master integer;
i_node_slave integer;
begin
perform replicacao.fn_adiciona_schema_slony_search_path();
i_node_master = 1;
i_node_slave = replicacao.fn_get_node_by_clicodigo(i_clicodigo);
insert into replicacao.tblog (logacao) values ('fn_remove_slave_replicacao');
if not exists(select 1 from sl_set where set_comment = s_contexto) then
raise exception 'O contexto "%", não existe.', s_contexto;
else
select set_id into i_set from sl_set where set_comment = s_contexto;
if exists(select 1 from sl_set where set_comment = s_contexto and age(xmin) = 0) then
raise exception 'O contexto "%", não deve ser preparado e iniciado na mesma execução.', s_contexto;
end if;
end if;
if not exists(select 1 from sl_node where no_id = i_node_master) then
raise exception 'O node de replicação "%", não existe.', i_node_master;
end if;
if not exists(select 1 from sl_node where no_id = i_node_slave) then
raise exception 'O node de replicação "%", não existe.', i_node_slave;
end if;
raise notice 'Executar no slave: "select * from _replication_ipmfiscal.unsubscribeset(%, %, false);"', i_set, i_node_slave;
/*perform unsubscribeset(i_set, i_node_slave, false);*/
perform replicacao.fn_remove_schema_slony_search_path();
return format('Executar no slave: "select * from _replication_ipmfiscal.unsubscribeset(%s, %s, false);"', i_set, i_node_slave);
end
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
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)
);
CREATE OR REPLACE FUNCTION replicacao.fn_event_trigger_on_execute_ddl()
RETURNS event_trigger
LANGUAGE 'plpgsql'
COST 100
VOLATILE NOT LEAKPROOF
AS $BODY$
BEGIN
if position((select replicacao.fn_get_schema_slony()) in current_query()) = 0 then
insert into replicacao.tbddl (ddlcomando) values (current_query());
end if;
END
$BODY$;
Acessar o banco do fiscal, schema replicação, tabela tbclientenode (alterar o código do cliente) não necessário o SQL abaixo:
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)
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 e Authorization no banco destino:
-- 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:
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$;
Script de teste
# 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',','));
--executar os dois acima juntos
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;
Parar o serviço e iniciar novamente, após, verifique o Lag Time:
/usr/local/slony1/bin/slon_kill
/usr/local/slony1/bin/slon_start 1
/usr/local/slony1/bin/slon_start 2
select * from replicacao.status();