Jump to content

Transferir dados entre base de dados MariaDB


david.inacio

Recommended Posts

david.inacio
<?php
date_default_timezone_set ("Europe/Lisbon");
?> 
	<html>
	<head>	
		
	</head>
	<body>
		<div id="header">
			 
			<div><b><?=date("Y-m-d H:i:s") ?> <h3> Sistema de transferencia interbase dados</h3> </b></div> 
			 
		</div>
		<div class="clear"></div>
		
	<script type="text/javascript">
				setInterval(function(){ 
				window.location = 'auto.php';
			}, 7500);
      </script>
<?php
$dblink1=mysqli_connect('alfa.ddns.net', 'masters', '************','db1'); // connect server 1
mysqli_select_db($dblink1,'db1');  // select database 1

$dblink2=mysqli_connect('bravo.ddns.net', 'clientes', '**********','db2'); // connect server 2	
mysqli_select_db($dblink2, 'db2'); // select database 2

$table='production_log';

$tableinfo = mysqli_fetch_array(mysqli_query($dblink1,"SHOW CREATE TABLE production_log  ")); // get structure from table on server 1

mysqli_query($dblink2," $tableinfo[1] " ); // use found structure to make table on server 2

$result = mysqli_query($dblink1,"SELECT * FROM production_log where barcode =0 limit 10 "); // select all content	
	
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC) ) 
{	
		mysqli_query($dblink1, "UPDATE production_log SET barcode=1   where barcode =0 limit 1");	
		mysqli_query($dblink2,"INSERT INTO production_log (".implode(", ",array_keys($row)).") VALUES ('".implode("', '",array_values($row))."')"); // insert one row into new table

}

mysqli_close($dblink1);
mysqli_close($dblink2);
?>
</body>
</html>

Boa noite.  Este código faz a passagem de dados entre duas bases de dados em locais distintos. A minha intenção era usar o campo barcode para marcar a linha como já copiada, para não ter de criar outras regras ou campos de controlo. Aparentemente funciona bem, no entanto de vez em quando cria registos duplicados na base de dados de destino (5 registos duplicados num universo de cem mil). Eu não sou programador experiente, só vou juntando partes de código :)
Na vossa opinião como se pode otimizar, ou mesmo alterar a filosofia da coisa para melhorar?
Obrigado

David Inácio

Link to post
Share on other sites

Já confirmaste que os registos não existem em duplicado na fonte?

10 REM Generation 48K!
20 INPUT "URL:", A$
30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50
40 PRINT "404 Not Found"
50 PRINT "./M6 @ Portugal a Programar."

 

Link to post
Share on other sites
Rui Carlos

Tenho algumas reservas que a query UPDATE production_log SET barcode=1   where barcode =0 limit 1 tenha garantidamente o efeito desejado.

Mas também não me parece que a mesma seja necessária (a menos que executes a script mais do que uma vez).  Por isso a hipótese do @M6 deverá ser algo a analisar.

Link to post
Share on other sites
david.inacio
Em 21/06/2020 às 22:06, Rui Carlos disse:

Tenho algumas reservas que a query UPDATE production_log SET barcode=1   where barcode =0 limit 1 tenha garantidamente o efeito desejado.

Mas também não me parece que a mesma seja necessária (a menos que executes a script mais do que uma vez).  Por isso a hipótese do @M6 deverá ser algo a analisar.

Olá Rui Carlos. A query corre de 30 em 30 segundos. No exemplo em causa coloquei 7,5 segundos por uma questão prática. Serve para mover os dados de um pc antigo de produção industrial  para um raspberry numa zona mais exposta. Não fui o criador da BD e a aplicação que escreve nela é blindada e nada consigo alterar na mesma. A forma que eu pensei para marcar os registos na BD source foi aquele 

Set barcode = 1

uma vez que na BD source é 0 por defeito... 

Não sei se sintaxe que escolhi é a mais adequada. Que vos parece? Uma outra forma de fazer? 


 

Em 21/06/2020 às 15:43, M6 disse:

Já confirmaste que os registos não existem em duplicado na fonte?

Desafortunadamente não existem em duplicad na fonte.  Por outro lado, a ser assim, se calhar seriam copiados em duplicado e o valor final seria igual nas duas...

 

Obrigado a ambos.

David 

Edited by david.inacio

David Inácio

Link to post
Share on other sites

Bom, parece-me que a tua questão é mais profunda do que um pequeno script de php/mysql.
Com essa situação de correres a cada X tempo, não admira que tenhas duplicados. Isso tem de ser feito de forma transacional entre as bases de dados.

O que me parece que necessitas é de uma solução de replicação/sincronização de base de dados, como por exemplo o Galera.
Mas caso não necessites de um "canhão" como o Galera, podes usar uma solução mais simples como um dblink - creio que no MySQL terás de ver algo como uma base de dados federada - e assim poderás fazer um insert from select ou outra solução transacional.

10 REM Generation 48K!
20 INPUT "URL:", A$
30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50
40 PRINT "404 Not Found"
50 PRINT "./M6 @ Portugal a Programar."

 

Link to post
Share on other sites

A melhor forma de fazer esse tipo de migrações é usar alguma ferramenta que ter permita fazê-lo de forma transacional, ou seja, na mesma transação tens de inserir na nova DB e atualizar a row com a flag se um destes passos falhar é feito rollback. 

Link to post
Share on other sites
15 hours ago, david.inacio said:

Deve ser algo deste tipo:  Create db links 

Mais uma vez, obrigado.

Sim, é algo desse género, mas não sei se o MySQL suporta isso.

Podes também ver a replicação de Master->Slave embora não seja muito fã desta solução.

10 REM Generation 48K!
20 INPUT "URL:", A$
30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50
40 PRINT "404 Not Found"
50 PRINT "./M6 @ Portugal a Programar."

 

Link to post
Share on other sites
david.inacio

Criei um user exclusivo para esta transacção (webuser) e alterei o código ligeiramente, reduzindo as transações para 5 por query e já sincronizou 900 mil registos sem espinhas...  Está a funcionar bem.

David Inácio

Link to post
Share on other sites
david.inacio
1 minuto atrás, M6 disse:

Sim, é algo desse género, mas não sei se o MySQL suporta isso.

Podes também ver a replicação de Master->Slave embora não seja muito fã desta solução.

Vou continuar a pesquisar, mas para já, ficou a funcionar muito bem com as alterações que fiz. Obrigado pela ajuda.

David Inácio

Link to post
Share on other sites
david.inacio

Voltei para dizer que afinal esta solução que criei não funcionou bem. Voltei a ter muitos problemas com duplicação de registos. Optei então pela criação de um sistema de replicação Master - Slave, o qual aparentemente funciona bem, para já. Obrigado aos que deram o seu contributo.

David Inácio

Link to post
Share on other sites
david.inacio
Em 25/06/2020 às 14:41, M6 disse:

Sim, é algo desse género, mas não sei se o MySQL suporta isso.

Podes também ver a replicação de Master->Slave embora não seja muito fã desta solução.

O MySQL não suporta dblinks, por isso tive de seguir outro caminho.

David Inácio

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.