{"id":38146,"date":"2019-10-31T22:21:54","date_gmt":"2019-10-31T19:21:54","guid":{"rendered":"https:\/\/prohoster.info\/blog\/perekrestnaya-replikatsiya-mezhdu-postgresql-i-mysql\/"},"modified":"2019-10-31T22:21:54","modified_gmt":"2019-10-31T19:21:54","slug":"perekrestnaya-replikatsiya-mezhdu-postgresql-i-mysql","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/perekrestnaya-replikatsiya-mezhdu-postgresql-i-mysql","title":{"rendered":"Replica\u00e7\u00e3o cruzada entre PostgreSQL e MySQL","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Replica\u00e7\u00e3o cruzada entre PostgreSQL e MySQL\" src=\"\/wp-content\/uploads\/2019\/09\/47cf48f9024f406d625ecb6b21020c74.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Vou dar uma vis\u00e3o geral sobre replica\u00e7\u00e3o cruzada entre PostgreSQL e MySQL, al\u00e9m de m\u00e9todos de configura\u00e7\u00e3o para essa replica\u00e7\u00e3o entre esses dois servidores de banco de dados. Geralmente, os bancos de dados na replica\u00e7\u00e3o cruzada s\u00e3o chamados de homog\u00eaneos, e esse \u00e9 um m\u00e9todo conveniente para a transi\u00e7\u00e3o de um servidor de SGBD relacional para outro.<\/p>\n<p><\/p>\n<p>Os bancos de dados PostgreSQL e MySQL s\u00e3o considerados relacionais, mas com extens\u00f5es adicionais, eles oferecem capacidades NoSQL. Aqui, discutiremos a replica\u00e7\u00e3o entre PostgreSQL e MySQL na perspectiva de SGBDs relacionais.<\/p>\n<p><\/p>\n<p>N\u00e3o vamos descrever toda a mec\u00e2nica interna, apenas os princ\u00edpios b\u00e1sicos, para que voc\u00ea possa ter uma no\u00e7\u00e3o de como configurar a replica\u00e7\u00e3o entre servidores de banco de dados, incluindo vantagens, limita\u00e7\u00f5es e cen\u00e1rios de uso.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Geralmente, a replica\u00e7\u00e3o entre dois servidores de banco de dados id\u00eanticos \u00e9 realizada em modo bin\u00e1rio ou atrav\u00e9s de consultas entre o n\u00f3 principal (tamb\u00e9m chamado de editor, master ou ativo) e o secund\u00e1rio (assinante, standby ou passivo). O objetivo da replica\u00e7\u00e3o \u00e9 fornecer uma c\u00f3pia em tempo real do banco de dados principal no lado secund\u00e1rio. Os dados s\u00e3o transferidos do principal para o secund\u00e1rio, ou seja, do ativo para o passivo, uma vez que a replica\u00e7\u00e3o ocorre apenas em uma dire\u00e7\u00e3o. Contudo, \u00e9 poss\u00edvel configurar a replica\u00e7\u00e3o entre dois bancos de dados em ambas as dire\u00e7\u00f5es, permitindo que os dados sejam transferidos do secund\u00e1rio para o principal em uma configura\u00e7\u00e3o \u201cativo-ativo\u201d. Tudo isso, incluindo replica\u00e7\u00e3o em cascata, \u00e9 vi\u00e1vel entre dois ou mais servidores de banco de dados id\u00eanticos. A configura\u00e7\u00e3o \u201cativo-ativo\u201d ou \u201cativo-passivo\u201d depende das necessidades, da disponibilidade dessas capacidades na configura\u00e7\u00e3o original ou do uso de solu\u00e7\u00f5es externas para a configura\u00e7\u00e3o, al\u00e9m de compromissos existentes.<\/p>\n<p><\/p>\n<p>A configura\u00e7\u00e3o descrita \u00e9 poss\u00edvel entre diferentes servidores de banco de dados. Um servidor pode ser configurado para receber dados replicados de outro servidor de banco de dados, mantendo ao mesmo tempo instant\u00e2neas dos dados replicados em tempo real. MySQL e PostgreSQL oferecem a maioria dessas configura\u00e7\u00f5es, seja por conta pr\u00f3pria ou por meio de extens\u00f5es de terceiros, incluindo m\u00e9todos de log bin\u00e1rio, bloqueio de disco e m\u00e9todos baseados em operadores e linhas.<\/p>\n<p><\/p>\n<p>A replica\u00e7\u00e3o cruzada entre MySQL e PostgreSQL \u00e9 necess\u00e1ria para uma migra\u00e7\u00e3o \u00fanica de um servidor de banco de dados para outro. Esses bancos de dados usam protocolos diferentes, portanto, n\u00e3o \u00e9 poss\u00edvel conect\u00e1-los diretamente. Para estabelecer a troca de dados, pode-se usar uma ferramenta de c\u00f3digo aberto externa, como o pg_chameleon.<\/p>\n<p><\/p>\n<h3 id=\"chto-takoe-pg_chameleon\">O que \u00e9 pg_chameleon<\/h3>\n<p><\/p>\n<p>O pg_chameleon \u00e9 um sistema de replica\u00e7\u00e3o do MySQL para PostgreSQL escrito em Python 3. Ele utiliza a biblioteca de c\u00f3digo aberto mysql-replication, tamb\u00e9m em Python. As imagens das linhas s\u00e3o extra\u00eddas das tabelas do MySQL e salvas como objetos JSONB no banco de dados PostgreSQL, e depois decodificadas pela fun\u00e7\u00e3o pl\/pgsql e reproduzidas no banco de dados PostgreSQL.<\/p>\n<p><\/p>\n<h3 id=\"vozmozhnosti-pg_chameleon\">Recursos do pg_chameleon<\/h3>\n<p><\/p>\n<p>V\u00e1rias esquemas MySQL de um cluster podem ser replicados em um \u00fanico banco de dados PostgreSQL com a configura\u00e7\u00e3o \"um para muitos\".<br \/>\nOs nomes dos esquemas de origem e de destino n\u00e3o podem ser iguais.<br \/>\nOs dados de replica\u00e7\u00e3o podem ser extra\u00eddos de uma r\u00e9plica em cascata do MySQL.<br \/>\nTabelas que n\u00e3o podem ser replicadas ou que geram erros s\u00e3o exclu\u00eddas.<br \/>\nCada fun\u00e7\u00e3o de replica\u00e7\u00e3o \u00e9 controlada por dem\u00f4nios.<br \/>\nControle atrav\u00e9s de par\u00e2metros e arquivos de configura\u00e7\u00e3o em formato YAML.<\/p>\n<p><\/p>\n<h3 id=\"primer\">Exemplo<\/h3>\n<p><\/p>\n<p>Host<br \/>\nvm1<br \/>\nvm2<\/p>\n<p><strong>Vers\u00e3o do SO<\/strong><br \/>\nCentOS Linux 7.6 x86_64<br \/>\nCentOS Linux 7.5 x86_64<\/p>\n<p><strong>Vers\u00e3o do servidor de BD<\/strong><br \/>\nMySQL 5.7.26<br \/>\nPostgreSQL 10.5<\/p>\n<p><strong>Porta do BD<\/strong><br \/>\n3306<br \/>\n5433<\/p>\n<p><strong>Endere\u00e7o IP<\/strong><br \/>\n192.168.56.102<br \/>\n192.168.56.106<\/p>\n<p><\/p>\n<p>Primeiro, prepare todos os componentes necess\u00e1rios para a instala\u00e7\u00e3o do pg_chameleon. Neste exemplo, o Python 3.6.8 est\u00e1 instalado, que cria um ambiente virtual e o ativa.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; wget https:\/\/www.python.org\/ftp\/python\/3.6.8\/Python-3.6.8.tar.xz\n$&gt; tar -xJf Python-3.6.8.tar.xz\n$&gt; cd Python-3.6.8\n$&gt; .\/configure --enable-optimizations\n$&gt; make altinstall<\/code><\/pre>\n<p><\/p>\n<p>Ap\u00f3s a instala\u00e7\u00e3o bem-sucedida do Python 3.6, \u00e9 necess\u00e1rio cumprir os outros requisitos, como criar e ativar um ambiente virtual. Al\u00e9m disso, o m\u00f3dulo pip \u00e9 atualizado para a vers\u00e3o mais recente e usado para instalar o pg_chameleon. Nas comandos abaixo, o pg_chameleon 2.0.9 \u00e9 instalado intencionalmente, embora a vers\u00e3o mais recente seja 2.0.10. Isso \u00e9 para evitar bugs novos na vers\u00e3o atualizada.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; python3.6 -m venv venv\n$&gt; source venv\/bin\/activate\n(venv) $&gt; pip install pip --upgrade\n(venv) $&gt; pip install pg_chameleon==2.0.9<\/code><\/pre>\n<p><\/p>\n<p>Em seguida, chamamos o pg_chameleon (chameleon \u00e9 o comando) com o argumento set_configuration_files, para ativar o pg_chameleon e criar os diret\u00f3rios e os arquivos de configura\u00e7\u00e3o padr\u00e3o.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">(venv) $&gt; chameleon set_configuration_files\ncriando diret\u00f3rio \/root\/.pg_chameleon\ncriando diret\u00f3rio \/root\/.pg_chameleon\/configuration\/\ncriando diret\u00f3rio \/root\/.pg_chameleon\/logs\/\ncriando diret\u00f3rio \/root\/.pg_chameleon\/pid\/\ncopiando configura\u00e7\u00e3o exemplo em \/root\/.pg_chameleon\/configuration\/\/config-example.yml<\/code><\/pre>\n<p><\/p>\n<p>Agora estamos criando uma c\u00f3pia do config-example.yml como default.yml, para que se torne o arquivo de configura\u00e7\u00e3o padr\u00e3o. Um exemplo do arquivo de configura\u00e7\u00e3o para este caso \u00e9 fornecido abaixo.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; cat default.yml\n---\n# configura\u00e7\u00f5es globais\npid_dir: '~\/.pg_chameleon\/pid\/'\nlog_dir: '~\/.pg_chameleon\/logs\/'\nlog_dest: file\nlog_level: info\nlog_days_keep: 10\nrollbar_key: ''\nrollbar_env: ''\n\n# type_override permite que o usu\u00e1rio substitua a convers\u00e3o de tipo padr\u00e3o por uma diferente.\ntype_override:\n  \"tinyint(1)\":\n    override_to: boolean\n    override_tables:\n      - \"*\"\n\n# conex\u00e3o de destino do postgres\npg_conn:\n  host: \"192.168.56.106\"\n  port: \"5433\"\n  user: \"usr_replica\"\n  password: \"pass123\"\n  database: \"db_replica\"\n  charset: \"utf8\"\n\nsources:\n  mysql:\n    db_conn:\n      host: \"192.168.56.102\"\n      port: \"3306\"\n      user: \"usr_replica\"\n      password: \"pass123\"\n      charset: 'utf8'\n      connect_timeout: 10\n    schema_mappings:\n      world_x: pgworld_x\n    limit_tables:\n#      - delphis_mediterranea.foo\n    skip_tables:\n#      - delphis_mediterranea.bar\n    grant_select_to:\n      - usr_readonly\n    lock_timeout: \"120s\"\n    my_server_id: 100\n    replica_batch_size: 10000\n    replay_max_rows: 10000\n    batch_retention: '1 day'\n    copy_max_memory: \"300M\"\n    copy_mode: 'file'\n    out_dir: \/tmp\n    sleep_loop: 1\n    on_error_replay: continue\n    on_error_read: continue\n    auto_maintenance: \"disabled\"\n    gtid_enable: No\n    type: mysql\n    skip_events:\n      insert:\n        - delphis_mediterranea.foo # ignora inser\u00e7\u00f5es na tabela delphis_mediterranea.foo\n      delete:\n        - delphis_mediterranea # ignora exclus\u00f5es no esquema delphis_mediterranea\n      update:<\/code><\/pre>\n<p><\/p>\n<p>O arquivo de configura\u00e7\u00e3o neste exemplo \u00e9 um modelo de arquivo pg_chameleon com pequenas altera\u00e7\u00f5es conforme o ambiente de origem e destino, e abaixo est\u00e1 uma vis\u00e3o geral das v\u00e1rias se\u00e7\u00f5es do arquivo de configura\u00e7\u00e3o.<\/p>\n<p><\/p>\n<p>No arquivo de configura\u00e7\u00e3o default.yml, h\u00e1 uma se\u00e7\u00e3o de par\u00e2metros globais (global settings), onde voc\u00ea pode gerenciar configura\u00e7\u00f5es como a localiza\u00e7\u00e3o do arquivo de bloqueio, a localiza\u00e7\u00e3o dos logs, o per\u00edodo de armazenamento dos logs, etc. Em seguida, segue a se\u00e7\u00e3o de substitui\u00e7\u00e3o de tipos (type override), onde um conjunto de regras para substitui\u00e7\u00e3o de tipos durante a replica\u00e7\u00e3o \u00e9 especificado. O exemplo padr\u00e3o utiliza uma regra de substitui\u00e7\u00e3o de tipo que transforma tinyint(1) em um valor booleano. Na pr\u00f3xima se\u00e7\u00e3o, especificamos os detalhes da conex\u00e3o com o banco de dados de destino. No nosso caso, \u00e9 o banco de dados PostgreSQL, denominado pg_conn. Na \u00faltima se\u00e7\u00e3o, fornecemos os dados da fonte, ou seja, os par\u00e2metros de conex\u00e3o do banco de dados de origem, o mapeamento de esquemas entre os bancos de dados de origem e destino, as tabelas que devem ser ignoradas, o tempo de espera, a mem\u00f3ria, e o tamanho do lote. Observe que \"sources\" est\u00e1 no plural, o que significa que podemos adicionar v\u00e1rios bancos de dados de origem para um \u00fanico destino, configurando a replica\u00e7\u00e3o de \"muitos para um\".<\/p>\n<p><\/p>\n<p>O banco de dados world_x no exemplo cont\u00e9m 4 tabelas com linhas que a comunidade MySQL oferece como exemplo. Ele pode ser baixado <noindex><a rel=\"nofollow\" href=\"https:\/\/dev.mysql.com\/doc\/index-other.html\">aqui<\/a><\/noindex>. O exemplo do banco de dados \u00e9 fornecido em forma de tar e como um arquivo compactado com instru\u00e7\u00f5es para criar e importar as linhas.<\/p>\n<p><\/p>\n<p>Em bancos de dados MySQL e PostgreSQL, \u00e9 criado um usu\u00e1rio especial com o mesmo nome usr_replica. No MySQL, lhe s\u00e3o concedidos direitos adicionais para ler todas as tabelas replicadas.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">mysql&gt; CREATE USER usr_replica ;\nmysql&gt; SET PASSWORD FOR usr_replica='pass123';\nmysql&gt; GRANT ALL ON world_x.* TO 'usr_replica';\nmysql&gt; GRANT RELOAD ON *.* to 'usr_replica';\nmysql&gt; GRANT REPLICATION CLIENT ON *.* to 'usr_replica';\nmysql&gt; GRANT REPLICATION SLAVE ON *.* to 'usr_replica';\nmysql&gt; FLUSH PRIVILEGES;<\/code><\/pre>\n<p><\/p>\n<p>No lado do PostgreSQL, \u00e9 criado um banco de dados db_replica, que receber\u00e1 altera\u00e7\u00f5es do banco de dados MySQL. O usu\u00e1rio usr_replica no PostgreSQL \u00e9 automaticamente configurado como propriet\u00e1rio de dois esquemas pgworld_x e sch_chameleon, que cont\u00eam as tabelas replicadas efetivas e as tabelas do cat\u00e1logo de replica\u00e7\u00e3o, respectivamente. A configura\u00e7\u00e3o autom\u00e1tica \u00e9 gerenciada pelo argumento create_replica_schema, como voc\u00ea ver\u00e1 abaixo.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">postgres=# CREATE USER usr_replica WITH PASSWORD 'pass123';\nCREATE ROLE\npostgres=# CREATE DATABASE db_replica WITH OWNER usr_replica;\nCREATE DATABASE<\/code><\/pre>\n<p><\/p>\n<p>O banco de dados MySQL \u00e9 configurado com a altera\u00e7\u00e3o de alguns par\u00e2metros para prepar\u00e1-lo para replica\u00e7\u00e3o, como mostrado abaixo. O servidor de bancos de dados precisar\u00e1 ser reiniciado para que as altera\u00e7\u00f5es entrem em vigor.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; vi \/etc\/my.cnf\nbinlog_format= ROW\nbinlog_row_image=FULL\nlog-bin = mysql-bin\nserver-id = 1<\/code><\/pre>\n<p><\/p>\n<p>Agora \u00e9 importante verificar a conex\u00e3o com os dois servidores de bancos de dados, para que n\u00e3o ocorram problemas ao executar comandos pg_chameleon.<\/p>\n<p><\/p>\n<p>No n\u00f3 PostgreSQL:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; mysql -u usr_replica -Ap'admin123' -h 192.168.56.102 -D world_x<\/code><\/pre>\n<p><\/p>\n<p>No n\u00f3 MySQL:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; psql -p 5433 -U usr_replica -h 192.168.56.106 db_replica<\/code><\/pre>\n<p><\/p>\n<p>Os tr\u00eas comandos a seguir do pg_chameleon (chameleon) preparam o ambiente, adicionam a fonte e inicializam a r\u00e9plica. O argumento create_replica_schema no pg_chameleon cria o esquema padr\u00e3o (sch_chameleon) e o esquema de replica\u00e7\u00e3o (pgworld_x) no banco de dados PostgreSQL, como j\u00e1 mencionamos. O argumento add_source adiciona o banco de dados de origem \u00e0 configura\u00e7\u00e3o, lendo o arquivo de configura\u00e7\u00e3o (default.yml), e no nosso caso \u00e9 o mysql, enquanto init_replica inicializa a configura\u00e7\u00e3o com base nos par\u00e2metros do arquivo de configura\u00e7\u00e3o.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; chameleon create_replica_schema --debug\n$&gt; chameleon add_source --config default --source mysql --debug\n$&gt; chameleon init_replica --config default --source mysql --debug<\/code><\/pre>\n<p><\/p>\n<p>A sa\u00edda desses tr\u00eas comandos indica claramente sua execu\u00e7\u00e3o bem-sucedida. Todas as falhas ou erros de sintaxe s\u00e3o apresentados em mensagens simples e compreens\u00edveis, com dicas para a corre\u00e7\u00e3o dos problemas.<\/p>\n<p><\/p>\n<p>Finalmente, vamos iniciar a replica\u00e7\u00e3o usando start_replica e receber uma mensagem de execu\u00e7\u00e3o bem-sucedida.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; chameleon start_replica --config default --source mysql \noutput: Iniciando o processo de replica\u00e7\u00e3o para a fonte mysql<\/code><\/pre>\n<p><\/p>\n<p>O status da replica\u00e7\u00e3o pode ser consultado usando o argumento show_status, e os erros podem ser visualizados usando o argumento show_errors.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/xpaste.pro\/p\/iYMdAf0b\">Resultado.<\/a><\/noindex><\/p>\n<p><\/p>\n<p>Como j\u00e1 mencionamos, cada fun\u00e7\u00e3o de replica\u00e7\u00e3o \u00e9 gerenciada por dem\u00f4nios. Para visualiz\u00e1-los, consultamos a tabela de processos com o comando Linux ps, conforme mostrado abaixo.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/xpaste.pro\/p\/59GfdvHA\">Resultado.<\/a><\/noindex><\/p>\n<p><\/p>\n<p>A replica\u00e7\u00e3o n\u00e3o \u00e9 considerada configurada at\u00e9 que a testemos em tempo real, como mostrado abaixo. Criamos uma tabela, inserimos algumas linhas no banco de dados MySQL e chamamos o argumento sync_tables no pg_chameleon para atualizar os dem\u00f4nios e replicar a tabela com as entradas no banco de dados PostgreSQL.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">mysql&gt; create table t1 (n1 int primary key, n2 varchar(10));\nQuery OK, 0 rows affected (0.01 sec)\nmysql&gt; insert into t1 values (1,'one');\nQuery OK, 1 row affected (0.00 sec)\nmysql&gt; insert into t1 values (2,'two');\nQuery OK, 1 row affected (0.00 sec)<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; chameleon sync_tables --tables world_x.t1 --config default --source mysql\nO processo de sincroniza\u00e7\u00e3o de tabelas para a fonte mysql foi iniciado.<\/code><\/pre>\n<p><\/p>\n<p>Para confirmar os resultados do teste, consultamos a tabela do banco de dados PostgreSQL e exibimos as linhas.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; psql -p 5433 -U usr_replica -d db_replica -c \"select * from pgworld_x.t1\";\n n1 |  n2\n----+-------\n  1 | one\n  2 | two<\/code><\/pre>\n<p><\/p>\n<p>Se estivermos realizando uma migra\u00e7\u00e3o, os seguintes comandos do pg_chameleon concluir\u00e3o o processo. Os comandos devem ser executados ap\u00f3s garantirmos que todas as linhas das tabelas de destino foram replicadas, resultando em um banco de dados PostgreSQL perfeitamente transferido, sem refer\u00eancias ao banco de dados ou esquema de replica\u00e7\u00e3o de origem (sch_chameleon).<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; chameleon stop_replica --config default --source mysql \n$&gt; chameleon detach_replica --config default --source mysql --debug<\/code><\/pre>\n<p><\/p>\n<p>Opcionalmente, os seguintes comandos podem ser usados para remover a configura\u00e7\u00e3o de origem e o esquema de replica\u00e7\u00e3o.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; chameleon drop_source --config default --source mysql --debug\n$&gt; chameleon drop_replica_schema --config default --source mysql --debug<\/code><\/pre>\n<p><\/p>\n<h3 id=\"preimuschestva-pg_chameleon\">Vantagens do pg_chameleon<\/h3>\n<p><\/p>\n<p>Configura\u00e7\u00e3o e configura\u00e7\u00e3o simples.<br \/>\nDepura\u00e7\u00e3o conveniente e identifica\u00e7\u00e3o de anomalias com mensagens de erro claras.<br \/>\nTabelas especiais adicionais podem ser adicionadas \u00e0 replica\u00e7\u00e3o ap\u00f3s a inicializa\u00e7\u00e3o, sem alterar o restante da configura\u00e7\u00e3o.<br \/>\n\u00c9 poss\u00edvel configurar v\u00e1rias bases de dados de origem para uma \u00fanica base de dados de destino, o que \u00e9 muito conveniente ao consolidar dados de uma ou mais bases de dados MySQL em uma \u00fanica base de dados PostgreSQL.<br \/>\n\u00c9 poss\u00edvel n\u00e3o replicar tabelas selecionadas.<\/p>\n<p><\/p>\n<h3 id=\"nedostatki-pg_chameleon\">Desvantagens do pg_chameleon<\/h3>\n<p><\/p>\n<p>Suporta apenas MySQL 5.5 ou superior como fonte e PostgreSQL 9.5 ou superior como base de dados de destino.<br \/>\nCada tabela deve ter uma chave prim\u00e1ria ou \u00fanica, caso contr\u00e1rio, as tabelas s\u00e3o inicializadas durante o processo init_replica, mas n\u00e3o s\u00e3o replicadas.<br \/>\nA replica\u00e7\u00e3o unidirecional \u00e9 apenas de MySQL para PostgreSQL. Portanto, \u00e9 adequada apenas para um esquema 'ativo-passivo'.<br \/>\nA base de dados de origem pode ser apenas uma base de dados MySQL, e o suporte \u00e0 base de dados PostgreSQL como origem \u00e9 apenas experimental e com restri\u00e7\u00f5es (saiba mais) <noindex><a rel=\"nofollow\" href=\"https:\/\/pgchameleon.org\/documents\/configuration_file.html#postgresql-source-type-experimental\">aqui<\/a><\/noindex>)<\/p>\n<p><\/p>\n<h3 id=\"itogi-po-pg_chameleon\">Resumo sobre pg_chameleon<\/h3>\n<p><\/p>\n<p>O m\u00e9todo de replica\u00e7\u00e3o no pg_chameleon \u00e9 ideal para migrar uma base de dados de MySQL para PostgreSQL. A desvantagem significativa \u00e9 que a replica\u00e7\u00e3o \u00e9 unidirecional, por isso, especialistas em bases de dados provavelmente n\u00e3o desejar\u00e3o utiliz\u00e1-lo para algo al\u00e9m de migra\u00e7\u00e3o. No entanto, o problema da replica\u00e7\u00e3o unidirecional pode ser resolvido com outra ferramenta de c\u00f3digo aberto \u2014 SymmetricDS.<\/p>\n<p><\/p>\n<p>Leia mais na documenta\u00e7\u00e3o oficial <noindex><a rel=\"nofollow\" href=\"https:\/\/pgchameleon.org\/documents\/\">aqui<\/a><\/noindex>. A ajuda da linha de comando pode ser encontrada <noindex><a rel=\"nofollow\" href=\"https:\/\/pgchameleon.org\/documents\/usage.html#https:\/\/pgchameleon.org\/documents\/usage.html\">aqui<\/a><\/noindex>.<\/p>\n<p><\/p>\n<h3 id=\"obzor-symmetricds\">Vis\u00e3o geral do SymmetricDS<\/h3>\n<p><\/p>\n<p>SymmetricDS \u00e9 uma ferramenta de c\u00f3digo aberto que replica qualquer base de dados para outra base de dados comum: Oracle, MongoDB, PostgreSQL, MySQL, SQL Server, MariaDB, DB2, Sybase, Greenplum, Informix, H2, Firebird e outras inst\u00e2ncias de bancos de dados em nuvem, como Redshift e Azure, etc. Recursos dispon\u00edveis: sincroniza\u00e7\u00e3o de bases de dados e arquivos, replica\u00e7\u00e3o de v\u00e1rias bases de dados principais, sincroniza\u00e7\u00e3o filtrada, transforma\u00e7\u00e3o e outros. Esta \u00e9 uma ferramenta em Java, e \u00e9 necess\u00e1rio ter a edi\u00e7\u00e3o padr\u00e3o do JRE ou JDK (vers\u00f5es 8.0 ou superior). Aqui, pode-se registrar altera\u00e7\u00f5es de dados atrav\u00e9s de triggers na base de dados de origem e direcion\u00e1-las para a respectiva base de dados de destino em pacotes.<\/p>\n<p><\/p>\n<h3 id=\"vozmozhnosti-symmetricds\">Recursos do SymmetricDS<\/h3>\n<p><\/p>\n<p>A ferramenta \u00e9 independente de plataforma, o que significa que duas ou mais bases de dados diferentes podem trocar dados.<br \/>\nBases de dados relacionais s\u00e3o sincronizadas por meio do registro de altera\u00e7\u00f5es de dados, enquanto bases de dados baseadas em sistemas de arquivos utilizam sincroniza\u00e7\u00e3o de arquivos.<br \/>\nReplica\u00e7\u00e3o bidirecional utilizando m\u00e9todos Push e Pull baseados em um conjunto de regras.<br \/>\nA transfer\u00eancia de dados \u00e9 poss\u00edvel atrav\u00e9s de redes seguras e redes com baixa largura de banda.<br \/>\nRecupera\u00e7\u00e3o autom\u00e1tica ao retomar o funcionamento dos n\u00f3s ap\u00f3s falhas e resolu\u00e7\u00e3o autom\u00e1tica de conflitos.<br \/>\nCompatibilidade com a nuvem e APIs de extens\u00f5es eficientes.<\/p>\n<p><\/p>\n<h3 id=\"primer-1\">Exemplo<\/h3>\n<p><\/p>\n<p>O SymmetricDS pode ser configurado de uma das duas maneiras:<br \/>\nUm n\u00f3 principal (pai) que coordena centralmente a replica\u00e7\u00e3o de dados entre dois n\u00f3s seguidores (filhos), e a troca de dados entre os n\u00f3s filhos ocorre apenas atrav\u00e9s do pai.<br \/>\nUm n\u00f3 ativo (n\u00f3 1) pode trocar dados para replica\u00e7\u00e3o com outro n\u00f3 ativo (n\u00f3 2) sem intermedi\u00e1rio.<\/p>\n<p><\/p>\n<p>Em ambas as op\u00e7\u00f5es, a troca de dados ocorre por meio de Push e Pull. Neste exemplo, vamos considerar a configura\u00e7\u00e3o \"ativo-ativo\". Descrever toda a arquitetura leva muito tempo, ent\u00e3o estude <noindex><a rel=\"nofollow\" href=\"https:\/\/www.symmetricds.org\/doc\/3.10\/html\/user-guide.html#_architecture\">manual<\/a><\/noindex>, para saber mais sobre o dispositivo SymmetricDS.<\/p>\n<p><\/p>\n<p>Instalar o SymmetricDS \u00e9 muito simples: baixe a vers\u00e3o de c\u00f3digo aberto do arquivo zip <noindex><a rel=\"nofollow\" href=\"https:\/\/www.symmetricds.org\/download\">daqui<\/a><\/noindex> e extraia-o onde quiser. A tabela abaixo fornece informa\u00e7\u00f5es sobre o local de instala\u00e7\u00e3o e a vers\u00e3o do SymmetricDS neste exemplo, al\u00e9m de vers\u00f5es de bancos de dados, vers\u00f5es do Linux, endere\u00e7os IP e portas para ambos os n\u00f3s.<\/p>\n<p><\/p>\n<p>Host<br \/>\nvm1<br \/>\nvm2<\/p>\n<p><strong>Vers\u00e3o do SO<\/strong><br \/>\nCentOS Linux 7.6 x86_64<br \/>\nCentOS Linux 7.6 x86_64<\/p>\n<p><strong>Vers\u00e3o do servidor de BD<\/strong><br \/>\nMySQL 5.7.26<br \/>\nPostgreSQL 10.5<\/p>\n<p><strong>Porta do BD<\/strong><br \/>\n3306<br \/>\n5832<\/p>\n<p><strong>Endere\u00e7o IP<\/strong><br \/>\n192.168.1.107<br \/>\n192.168.1.112<\/p>\n<p><strong>Vers\u00e3o do SymmetricDS<\/strong><br \/>\nSymmetricDS 3.9<br \/>\nSymmetricDS 3.9<\/p>\n<p><strong>Caminho de instala\u00e7\u00e3o do SymmetricDS<\/strong><br \/>\n\/usr\/local\/symmetric-server-3.9.20<br \/>\n\/usr\/local\/symmetric-server-3.9.20<\/p>\n<p><strong>Nome do n\u00f3 do SymmetricDS<\/strong><br \/>\ncorp-000<br \/>\nstore-001<\/p>\n<p><\/p>\n<p>Aqui estamos instalando o SymmetricDS em \/usr\/local\/symmetric-server-3.9.20, e diferentes diret\u00f3rios e arquivos armazenados aqui. Estamos interessados nos diret\u00f3rios e motores aninhados. No diret\u00f3rio de exemplos, existem exemplos de arquivos de configura\u00e7\u00e3o com propriedades do n\u00f3, bem como exemplos de scripts SQL para uma demonstra\u00e7\u00e3o r\u00e1pida.<\/p>\n<p><\/p>\n<p>No diret\u00f3rio de exemplos, vemos tr\u00eas arquivos de configura\u00e7\u00e3o com as propriedades do n\u00f3 \u2014 o nome indica a natureza do n\u00f3 em um determinado esquema.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">corp-000.properties\nstore-001.properties\nstore-002.properties<\/code><\/pre>\n<p><\/p>\n<p>O SymmetricDS possui todos os arquivos de configura\u00e7\u00e3o necess\u00e1rios para um esquema b\u00e1sico de 3 n\u00f3s (op\u00e7\u00e3o 1), e os mesmos arquivos podem ser usados para um esquema de 2 n\u00f3s (op\u00e7\u00e3o 2). Copiamos o arquivo de configura\u00e7\u00e3o necess\u00e1rio do diret\u00f3rio de exemplos para os motores no host vm1. Ficamos assim:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$ &gt; cat engines\/corp-000.properties\nengine.name=corp-000\ndb.driver=com.mysql.jdbc.Driver\ndb.url=jdbc:mysql:\/\/192.168.1.107:3306\/replica_db?autoReconnect=true&amp;useSSL=false\ndb.user=root\ndb.password=admin123\nregistration.url=\nsync.url=http:\/\/192.168.1.107:31415\/sync\/corp-000\ngroup.id=corp\nexternal.id=000<\/code><\/pre>\n<p><\/p>\n<p>Este n\u00f3 na configura\u00e7\u00e3o do SymmetricDS \u00e9 chamado de corp-000, e a conex\u00e3o com o banco de dados \u00e9 gerenciada pelo driver mysql jdbc, que utiliza a string de conex\u00e3o mencionada acima e as credenciais de acesso. Estamos conectando ao banco de dados replica_db, e durante a cria\u00e7\u00e3o do esquema, as tabelas ser\u00e3o criadas. sync.url indica o local de conex\u00e3o com o n\u00f3 para sincroniza\u00e7\u00e3o.<\/p>\n<p><\/p>\n<p>O n\u00f3 2 no host vm2 \u00e9 configurado como store-001, e o restante est\u00e1 especificado no arquivo node.properties, que \u00e9 apresentado abaixo. O n\u00f3 store-001 executa um banco de dados PostgreSQL, e pgdb_replica \u00e9 o banco de dados para replica\u00e7\u00e3o. registration.url permite que o host vm2 se conecte ao host vm1 e obtenha os detalhes de configura\u00e7\u00e3o.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; cat engines\/store-001.properties\nengine.name=store-001\ndb.driver=org.postgresql.Driver\ndb.url=jdbc:postgresql:\/\/192.168.1.112:5832\/pgdb_replica\ndb.user=postgres\ndb.password=admin123\nregistration.url=http:\/\/192.168.1.107:31415\/sync\/corp-000\ngroup.id=store\nexternal.id=001<\/code><\/pre>\n<p><\/p>\n<p>O exemplo completo do SymmetricDS cont\u00e9m par\u00e2metros para configurar a replica\u00e7\u00e3o bidirecional entre dois servidores de banco de dados (dois n\u00f3s). As etapas abaixo s\u00e3o executadas no host vm1 (corp-000), que criar\u00e1 um exemplo de esquema com 4 tabelas. Em seguida, a execu\u00e7\u00e3o do comando create-sym-tables pelo symadmin criar\u00e1 as tabelas de cat\u00e1logo, onde ser\u00e3o armazenadas as regras e a dire\u00e7\u00e3o da replica\u00e7\u00e3o entre os n\u00f3s. Por fim, um conjunto de dados de exemplo \u00e9 carregado nas tabelas.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">vm1$&gt; cd \/usr\/local\/symmetric-server-3.9.20\/bin\nvm1$&gt; .\/dbimport --engine corp-000 --format XML create_sample.xml\nvm1$&gt; .\/symadmin --engine corp-000 create-sym-tables\nvm1$&gt; .\/dbimport --engine corp-000 insert_sample.sql<\/code><\/pre>\n<p><\/p>\n<p>No exemplo, as tabelas item e item_selling_price s\u00e3o configuradas automaticamente para replica\u00e7\u00e3o de corp-000 para store-001, enquanto as tabelas sale (sale_transaction e sale_return_line_item) s\u00e3o configuradas automaticamente para replica\u00e7\u00e3o de store-001 para corp-000. Agora, criamos o esquema no banco de dados PostgreSQL no host vm2 (store-001), para prepar\u00e1-lo para receber dados de corp-000.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">vm2$&gt; cd \/usr\/local\/symmetric-server-3.9.20\/bin\nvm2$&gt; .\/dbimport --engine store-001 --format XML create_sample.xml<\/code><\/pre>\n<p><\/p>\n<p>Certifique-se de que h\u00e1 exemplos de tabelas e tabelas de cat\u00e1logo do SymmetricDS no banco de dados MySQL em vm1. Observe que as tabelas de sistema do SymmetricDS (com o prefixo sym_) est\u00e3o atualmente dispon\u00edveis apenas no n\u00f3 corp-000, porque l\u00e1 executamos o comando create-sym-tables e vamos gerenciar a replica\u00e7\u00e3o. Al\u00e9m disso, no banco de dados no n\u00f3 store-001, haver\u00e1 apenas 4 tabelas de exemplo sem dados.<\/p>\n<p><\/p>\n<p>Pronto. O ambiente est\u00e1 preparado para executar processos de servidor sym em ambos os n\u00f3s, como mostrado abaixo.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">vm1$&gt; cd \/usr\/local\/symmetric-server-3.9.20\/bin\nvm1$&gt; sym 2&gt;&amp;1 &amp;<\/code><\/pre>\n<p><\/p>\n<p>Os registros de log s\u00e3o enviados para o arquivo de log em segundo plano (symmetric.log) na pasta de logs no diret\u00f3rio onde o SymmetricDS est\u00e1 instalado, assim como para a sa\u00edda padr\u00e3o. O servidor sym agora pode ser iniciado no n\u00f3 store-001.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">vm2$&gt; cd \/usr\/local\/symmetric-server-3.9.20\/bin\nvm2$&gt; sym 2&gt;&amp;1 &amp;<\/code><\/pre>\n<p><\/p>\n<p>Se o processo do servidor sym for iniciado no host vm2, ele criar\u00e1 tabelas do cat\u00e1logo SymmetricDS tamb\u00e9m no banco de dados PostgreSQL. Se o processo do servidor sym for iniciado em ambos os n\u00f3s, eles se coordenar\u00e3o para replicar dados de corp-000 para store-001. Se, ap\u00f3s alguns segundos, solicitarmos todas as 4 tabelas de ambos os lados, veremos que a replica\u00e7\u00e3o foi bem-sucedida. Ou podemos enviar uma carga inicial para o n\u00f3 store-001 de corp-000 com o seguinte comando.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">vm1$&gt; .\/symadmin --engine corp-000 reload-node 001<\/code><\/pre>\n<p><\/p>\n<p>Neste est\u00e1gio, um novo registro \u00e9 inserido na tabela item no banco de dados MySQL no n\u00f3 corp-000 (host: vm1), e podemos verificar sua replica\u00e7\u00e3o no banco de dados PostgreSQL no n\u00f3 store-001 (host: vm2). Observamos a opera\u00e7\u00e3o Pull para mover dados de corp-000 para store-001.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">mysql&gt; insert into item values ('22000002','Jelly Bean');\nQuery OK, 1 row affected (0.00 sec)<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">vm2$&gt; psql -p 5832 -U postgres pgdb_replica -c \"select * from item\"\n item_id  |   name\n----------+-----------\n 11000001 | Yummy Gum\n 22000002 | Jelly Bean\n(2 rows)<\/code><\/pre>\n<p><\/p>\n<p>Para executar a opera\u00e7\u00e3o Push para mover dados de store-001 para corp-000, inserimos um registro na tabela sale_transaction e verificamos se a replica\u00e7\u00e3o foi conclu\u00edda.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/xpaste.pro\/p\/B23cJ4sP\">Resultado.<\/a><\/noindex><\/p>\n<p><\/p>\n<p>Observamos uma configura\u00e7\u00e3o bem-sucedida de replica\u00e7\u00e3o bidirecional das tabelas de exemplo entre os bancos de dados MySQL e PostgreSQL. Para configurar a replica\u00e7\u00e3o para novas tabelas de usu\u00e1rios, seguimos as etapas a seguir. Criamos a tabela t1 como exemplo e configuramos suas regras de replica\u00e7\u00e3o da seguinte maneira. Dessa forma, configuramos apenas a replica\u00e7\u00e3o de corp-000 para store-001.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">mysql&gt; create table  t1 (no integer);\nQuery OK, 0 rows affected (0.01 sec)<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">mysql&gt; insert into sym_channel (channel_id,create_time,last_update_time) \nvalues ('t1',current_timestamp,current_timestamp);\nQuery OK, 1 row affected (0.01 sec)<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">mysql&gt; insert into sym_trigger (trigger_id, source_table_name,channel_id,\nlast_update_time, create_time) values ('t1', 't1', 't1', current_timestamp,\ncurrent_timestamp);\nQuery OK, 1 row affected (0.01 sec)<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">mysql&gt; insert into sym_trigger_router (trigger_id, router_id,\nInitial_load_order, create_time,last_update_time) values ('t1',\n'corp-2-store-1', 1, current_timestamp,current_timestamp);\nQuery OK, 1 row affected (0.01 sec)<\/code><\/pre>\n<p><\/p>\n<p>Em seguida, a configura\u00e7\u00e3o recebe uma notifica\u00e7\u00e3o sobre a altera\u00e7\u00e3o do esquema, ou seja, a adi\u00e7\u00e3o de uma nova tabela, atrav\u00e9s do comando symadmin com o argumento sync-triggers, que recria os gatilhos para corresponder \u00e0s defini\u00e7\u00f5es das tabelas. O comando send-schema \u00e9 executado para enviar as altera\u00e7\u00f5es do esquema para o n\u00f3 store-001, e a replica\u00e7\u00e3o da tabela t1 \u00e9 configurada.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">vm1$&gt; .\/symadmin -e corp-000 --node=001 sync-triggers\nvm1$&gt; .\/symadmin send-schema -e corp-000 --node=001 t1<\/code><\/pre>\n<p><\/p>\n<h3 id=\"preimuschestva-symmetricds\">Vantagens do SymmetricDS<\/h3>\n<p><\/p>\n<p>Instala\u00e7\u00e3o e configura\u00e7\u00e3o simples, incluindo um pacote pronto de arquivos de par\u00e2metros para criar um esquema com tr\u00eas ou dois n\u00f3s.<br \/>\nInteroperabilidade de bancos de dados e independ\u00eancia de plataforma, incluindo servidores, laptops e dispositivos m\u00f3veis.<br \/>\nReplica\u00e7\u00e3o de qualquer banco de dados para qualquer outro banco de dados localmente, em WAN ou na nuvem.<br \/>\nCapacidade de operar de forma otimizada com um par de bancos de dados ou at\u00e9 milhares para uma replica\u00e7\u00e3o conveniente.<br \/>\nVers\u00e3o paga com interface gr\u00e1fica e excelente suporte.<\/p>\n<p><\/p>\n<h3 id=\"nedostatki-symmetricds\">Desvantagens do SymmetricDS<\/h3>\n<p><\/p>\n<p>\u00c9 necess\u00e1rio definir manualmente na linha de comando as regras e a dire\u00e7\u00e3o da replica\u00e7\u00e3o atrav\u00e9s de operadores SQL para carregar tabelas de cat\u00e1logo, o que pode ser inconveniente.<br \/>\nConfigurar muitas tabelas para replica\u00e7\u00e3o pode ser cansativo se n\u00e3o forem usados scripts para criar operadores SQL que definem as regras e a dire\u00e7\u00e3o da replica\u00e7\u00e3o.<br \/>\nOs logs registram uma quantidade excessiva de informa\u00e7\u00f5es, e \u00e0s vezes \u00e9 necess\u00e1rio organizar o arquivo de log para que ele n\u00e3o ocupe muito espa\u00e7o.<\/p>\n<p><\/p>\n<h3 id=\"itogi-po-symmetricds\">Resumo sobre o SymmetricDS<\/h3>\n<p><\/p>\n<p>O SymmetricDS permite configurar replica\u00e7\u00e3o bidirecional entre dois, tr\u00eas ou at\u00e9 milhares de n\u00f3s, para realizar replica\u00e7\u00e3o e sincroniza\u00e7\u00e3o de arquivos. \u00c9 uma ferramenta \u00fanica que executa muitas tarefas por conta pr\u00f3pria, como a recupera\u00e7\u00e3o autom\u00e1tica de dados ap\u00f3s longos per\u00edodos de inatividade em um n\u00f3, troca de dados entre n\u00f3s de forma segura e eficiente via HTTPS, gerenciamento autom\u00e1tico de conflitos com base em um conjunto de regras, entre outros. O SymmetricDS realiza replica\u00e7\u00e3o entre quaisquer bancos de dados, por isso pode ser utilizado em diversos cen\u00e1rios, incluindo migra\u00e7\u00f5es, atualiza\u00e7\u00f5es de vers\u00f5es, dissemina\u00e7\u00e3o, filtragem e transforma\u00e7\u00e3o de dados em diferentes plataformas.<\/p>\n<p><\/p>\n<p>Exemplo criado com base no <noindex><a rel=\"nofollow\" href=\"https:\/\/www.symmetricds.org\/doc\/3.9\/html\/tutorials.html\">guia r\u00e1pido<\/a><\/noindex> do SymmetricDS. Em <noindex><a rel=\"nofollow\" href=\"https:\/\/www.symmetricds.org\/doc\/3.9\/html\/user-guide.html\">manual do usu\u00e1rio<\/a><\/noindex> s\u00e3o detalhadamente descritos v\u00e1rios conceitos relacionados \u00e0 configura\u00e7\u00e3o de replica\u00e7\u00e3o com o SymmetricDS.<\/p>\n<p>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/southbridge\/blog\/467313\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u042f \u0432 \u043e\u0431\u0449\u0438\u0445 \u0447\u0435\u0440\u0442\u0430\u0445 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u043f\u0435\u0440\u0435\u043a\u0440\u0435\u0441\u0442\u043d\u043e\u0439 \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043c\u0435\u0436\u0434\u0443 PostgreSQL \u0438 MySQL, \u0430 \u0435\u0449\u0435 \u043e \u043c\u0435\u0442\u043e\u0434\u0430\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0435\u0440\u0435\u043a\u0440\u0435\u0441\u0442\u043d\u043e\u0439 \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043c\u0435\u0436\u0434\u0443 \u044d\u0442\u0438\u043c\u0438 \u0434\u0432\u0443\u043c\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430\u043c\u0438 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u041e\u0431\u044b\u0447\u043d\u043e \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043f\u0435\u0440\u0435\u043a\u0440\u0435\u0441\u0442\u043d\u043e\u0439 \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0440\u043e\u0434\u043d\u044b\u043c\u0438, \u0438 \u044d\u0442\u043e \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0441 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0440\u0435\u043b\u044f\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0421\u0423\u0411\u0414 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439. \u0411\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 PostgreSQL \u0438 MySQL \u043f\u0440\u0438\u043d\u044f\u0442\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0440\u0435\u043b\u044f\u0446\u0438\u043e\u043d\u043d\u044b\u043c\u0438, \u043d\u043e \u0441 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":28635,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-38146","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u042f \u0432 \u043e\u0431\u0449\u0438\u0445 \u0447\u0435\u0440\u0442\u0430\u0445 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/perekrestnaya-replikatsiya-mezhdu-postgresql-i-mysql\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"pt_PT\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041f\u0435\u0440\u0435\u043a\u0440\u0435\u0441\u0442\u043d\u0430\u044f \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u043c\u0435\u0436\u0434\u0443 PostgreSQL \u0438 MySQL | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u042f \u0432 \u043e\u0431\u0449\u0438\u0445 \u0447\u0435\u0440\u0442\u0430\u0445 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/perekrestnaya-replikatsiya-mezhdu-postgresql-i-mysql\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:21:54+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:21:54+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Replica\u00e7\u00e3o cruzada entre PostgreSQL e MySQL | ProHoster","description":"Vou falar de forma geral sobre.","canonical_url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/perekrestnaya-replikatsiya-mezhdu-postgresql-i-mysql","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pt_PT","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041f\u0435\u0440\u0435\u043a\u0440\u0435\u0441\u0442\u043d\u0430\u044f \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u043c\u0435\u0436\u0434\u0443 PostgreSQL \u0438 MySQL | ProHoster","og:description":"\u042f \u0432 \u043e\u0431\u0449\u0438\u0445 \u0447\u0435\u0440\u0442\u0430\u0445 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e.","og:url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/perekrestnaya-replikatsiya-mezhdu-postgresql-i-mysql","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:21:54+00:00","article:modified_time":"2019-10-31T19:21:54+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"38146","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-23 20:38:22","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 18:59:41","updated":"2026-01-23 20:38:22","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/38146","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/comments?post=38146"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/38146\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media\/28635"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media?parent=38146"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/categories?post=38146"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/tags?post=38146"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}