{"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\/pl\/blog\/administrirovanie\/perekrestnaya-replikatsiya-mezhdu-postgresql-i-mysql","title":{"rendered":"Replikacja krzy\u017cowa mi\u0119dzy PostgreSQL a MySQL","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Replikacja krzy\u017cowa mi\u0119dzy PostgreSQL a MySQL\" src=\"\/wp-content\/uploads\/2019\/09\/47cf48f9024f406d625ecb6b21020c74.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>W skr\u00f3cie opowiem o replikacji krzy\u017cowej mi\u0119dzy PostgreSQL a MySQL oraz o metodach konfigurowania replikacji krzy\u017cowej mi\u0119dzy tymi dwoma serwerami baz danych. Zazwyczaj bazy danych w replikacji krzy\u017cowej nazywane s\u0105 jednorodnymi, a to wygodna metoda przej\u015bcia z jednego serwera relacyjnej bazy danych na inny.<\/p>\n<p><\/p>\n<p>Bazy danych PostgreSQL i MySQL s\u0105 uwa\u017cane za relacyjne, ale dzi\u0119ki dodatkowym rozszerzeniom oferuj\u0105 mo\u017cliwo\u015bci NoSQL. Tutaj om\u00f3wimy replikacj\u0119 mi\u0119dzy PostgreSQL a MySQL z perspektywy relacyjnych baz danych.<\/p>\n<p><\/p>\n<p>Nie b\u0119dziemy opisywa\u0107 ca\u0142ej wewn\u0119trznej kuchni, tylko podstawowe zasady, aby\u015b mia\u0142 poj\u0119cie o konfiguracji replikacji mi\u0119dzy serwerami baz danych, jej zaletach, ograniczeniach oraz scenariuszach u\u017cycia.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Zazwyczaj replikacja mi\u0119dzy dwoma identycznymi serwerami baz danych odbywa si\u0119 w trybie binarnym lub za pomoc\u0105 zapyta\u0144 mi\u0119dzy w\u0119z\u0142em g\u0142\u00f3wnym (wydawc\u0105, g\u0142\u00f3wnym lub aktywnym) a w\u0119z\u0142em podrz\u0119dnym (subskrybentem, oczekuj\u0105cym lub pasywnym). Celem replikacji jest dostarczenie w czasie rzeczywistym kopii g\u0142\u00f3wnej bazy danych po stronie w\u0119z\u0142a podrz\u0119dnego. Dane s\u0105 przesy\u0142ane od w\u0119z\u0142a g\u0142\u00f3wnego do podrz\u0119dnego, czyli z aktywnego do pasywnego, poniewa\u017c replikacja odbywa si\u0119 tylko w jedn\u0105 stron\u0119. Mo\u017cna jednak skonfigurowa\u0107 replikacj\u0119 mi\u0119dzy dwiema bazami danych w obie strony, aby dane by\u0142y przesy\u0142ane od w\u0119z\u0142a podrz\u0119dnego do g\u0142\u00f3wnego w konfiguracji \u201eaktywny-aktywny\u201d. Wszystko to, w tym replikacja kaskadowa, mo\u017cliwe jest mi\u0119dzy dwoma lub wi\u0119cej identycznymi serwerami baz danych. Konfiguracja \u201eaktywny-aktywny\u201d lub \u201eaktywny-pasywny\u201d zale\u017cy od potrzeb, dost\u0119pno\u015bci takich mo\u017cliwo\u015bci w pierwotnej konfiguracji lub wykorzystania zewn\u0119trznych rozwi\u0105za\u0144 do konfiguracji oraz istniej\u0105cych kompromis\u00f3w.<\/p>\n<p><\/p>\n<p>Opisana konfiguracja jest mo\u017cliwa mi\u0119dzy r\u00f3\u017cnymi serwerami baz danych. Serwer mo\u017cna skonfigurowa\u0107 do odbierania replikowanych danych z innego serwera baz danych, jednocze\u015bnie zachowuj\u0105c zrzuty replikowanych danych w czasie rzeczywistym. MySQL i PostgreSQL oferuj\u0105 wi\u0119kszo\u015b\u0107 z tych konfiguracji samodzielnie lub za pomoc\u0105 zewn\u0119trznych rozszerze\u0144, w tym metody dziennika binarnego, blokady dysk\u00f3w oraz metody oparte na operatorach i wierszach.<\/p>\n<p><\/p>\n<p>Replikacja krzy\u017cowa mi\u0119dzy MySQL a PostgreSQL jest potrzebna do jednorazowej migracji z jednego serwera bazy danych na inny. Te bazy danych u\u017cywaj\u0105 r\u00f3\u017cnych protoko\u0142\u00f3w, wi\u0119c nie mo\u017cna je po\u0142\u0105czy\u0107 bezpo\u015brednio. Aby zorganizowa\u0107 wymian\u0119 danych, mo\u017cna u\u017cy\u0107 zewn\u0119trznego narz\u0119dzia open source, takiego jak pg_chameleon.<\/p>\n<p><\/p>\n<h3 id=\"chto-takoe-pg_chameleon\">Co to jest pg_chameleon<\/h3>\n<p><\/p>\n<p>pg_chameleon to system replikacji z MySQL do PostgreSQL w Pythonie 3. Wykorzystuje on open source'ow\u0105 bibliotek\u0119 mysql-replication, r\u00f3wnie\u017c napisan\u0105 w Pythonie. Obrazy wierszy s\u0105 wydobywane z tabel MySQL i zapisywane jako obiekty JSONB w bazie danych PostgreSQL, a nast\u0119pnie dekodowane funkcj\u0105 pl\/pgsql i odtwarzane w bazie danych PostgreSQL.<\/p>\n<p><\/p>\n<h3 id=\"vozmozhnosti-pg_chameleon\">Mo\u017cliwo\u015bci pg_chameleon<\/h3>\n<p><\/p>\n<p>Kilka schemat\u00f3w MySQL z jednego klastra mo\u017cna replikowa\u0107 do jednej docelowej bazy danych PostgreSQL w konfiguracji \"jeden do wielu\".<br \/>\nNazwy schemat\u00f3w \u017ar\u00f3d\u0142owego i docelowego nie mog\u0105 si\u0119 pokrywa\u0107.<br \/>\nDane replikacji mo\u017cna wydobywa\u0107 z kaskadowej repliki MySQL.<br \/>\nTabele, kt\u00f3re nie mog\u0105 by\u0107 replikowane lub powoduj\u0105 b\u0142\u0119dy, s\u0105 wykluczane.<br \/>\nKa\u017cd\u0105 funkcj\u0105 replikacji zarz\u0105dzaj\u0105 demony.<br \/>\nKontrola poprzez parametry i pliki konfiguracyjne na bazie YAML.<\/p>\n<p><\/p>\n<h3 id=\"primer\">Przyk\u0142ad<\/h3>\n<p><\/p>\n<p>Host<br \/>\nvm1<br \/>\nvm2<\/p>\n<p><strong>Wersja systemu operacyjnego<\/strong><br \/>\nCentOS Linux 7.6 x86_64<br \/>\nCentOS Linux 7.5 x86_64<\/p>\n<p><strong>Wersja serwera bazy danych<\/strong><br \/>\nMySQL 5.7.26<br \/>\nPostgreSQL 10.5<\/p>\n<p><strong>Port bazy danych<\/strong><br \/>\n3306<br \/>\n5433<\/p>\n<p><strong>Adres IP<\/strong><br \/>\n192.168.56.102<br \/>\n192.168.56.106<\/p>\n<p><\/p>\n<p>Na pocz\u0105tek przygotuj wszystkie niezb\u0119dne komponenty do instalacji pg_chameleon. W tym przyk\u0142adzie zainstalowano Pythona 3.6.8, kt\u00f3ry tworzy i aktywuje wirtualne \u015brodowisko.<\/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>Po pomy\u015blnej instalacji Pythona 3.6 nale\u017cy zrealizowa\u0107 pozosta\u0142e wymagania, na przyk\u0142ad utworzy\u0107 i aktywowa\u0107 wirtualne \u015brodowisko. Ponadto modu\u0142 pip jest aktualizowany do najnowszej wersji i u\u017cywany do instalacji pg_chameleon. W poni\u017cszych poleceniach celowo instalujemy pg_chameleon w wersji 2.0.9, mimo \u017ce najnowsza wersja to 2.0.10. Ma to na celu unikni\u0119cie nowych b\u0142\u0119d\u00f3w w zaktualizowanej wersji.<\/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>Nast\u0119pnie wywo\u0142ujemy pg_chameleon (chameleon to komenda) z argumentem set_configuration_files, aby w\u0142\u0105czy\u0107 pg_chameleon i utworzy\u0107 katalogi oraz pliki konfiguracyjne domy\u015blne.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">(venv) $&gt; chameleon set_configuration_files\nutworzenie katalogu \/root\/.pg_chameleon\nutworzenie katalogu \/root\/.pg_chameleon\/configuration\/\nutworzenie katalogu \/root\/.pg_chameleon\/logs\/\nutworzenie katalogu \/root\/.pg_chameleon\/pid\/\nkopiowanie przyk\u0142adowej konfiguracji do \/root\/.pg_chameleon\/configuration\/\/config-example.yml<\/code><\/pre>\n<p><\/p>\n<p>Teraz tworzymy kopi\u0119 config-example.yml jako default.yml, aby sta\u0142 si\u0119 domy\u015blnym plikiem konfiguracyjnym. Przyk\u0142ad pliku konfiguracyjnego dla tego przypadku przedstawiono poni\u017cej.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; cat default.yml\n---\n#global settings\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 allows the user to override the default type conversion into a different one.\ntype_override:\n  \"tinyint(1)\":\n    override_to: boolean\n    override_tables:\n      - \"*\"\n\n#postgres destination connection\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 #skips inserts on the table delphis_mediterranea.foo\n      delete:\n        - delphis_mediterranea #skips deletes on schema delphis_mediterranea\n      update:<\/code><\/pre>\n<p><\/p>\n<p>Plik konfiguracyjny w tym przyk\u0142adzie to wz\u00f3r pliku z pg_chameleon z niewielkimi zmianami zgodnie z oryginalnym i docelowym \u015brodowiskiem, a poni\u017cej przedstawiono przegl\u0105d r\u00f3\u017cnych sekcji pliku konfiguracyjnego.<\/p>\n<p><\/p>\n<p>W pliku konfiguracyjnym default.yml znajduje si\u0119 sekcja globalnych ustawie\u0144 (global settings), w kt\u00f3rej mo\u017cna zarz\u0105dza\u0107 takimi ustawieniami, jak lokalizacja pliku blokady, lokalizacja log\u00f3w, okres przechowywania log\u00f3w itp. Nast\u0119pnie znajdujemy sekcj\u0119 zmiany typ\u00f3w (type override), w kt\u00f3rej wskazany jest zestaw regu\u0142 do nadpisywania typ\u00f3w podczas replikacji. W przyk\u0142adzie domy\u015blnym u\u017cyte jest regu\u0142a zmiany typu, kt\u00f3ra przekszta\u0142ca tinyint(1) w warto\u015b\u0107 logiczn\u0105. W nast\u0119pnej sekcji podajemy dane po\u0142\u0105czenia z docelow\u0105 baz\u0105 danych. W naszym przypadku jest to baza danych PostgreSQL, oznaczona jako pg_conn. W ostatniej sekcji podajemy dane \u017ar\u00f3d\u0142owe, czyli parametry po\u0142\u0105czenia z oryginaln\u0105 baz\u0105 danych, mapowanie schemat\u00f3w oryginalnej i docelowej bazy danych, tabele, kt\u00f3re nale\u017cy pomin\u0105\u0107, czas oczekiwania, pami\u0119\u0107, rozmiar partii. Zauwa\u017c, \u017ce \u201esources\u201d jest podane w liczbie mnogiej, co oznacza, \u017ce mo\u017cemy doda\u0107 kilka baz danych \u017ar\u00f3d\u0142owych do jednej docelowej, aby dostosowa\u0107 konfiguracj\u0119 \u201ewielu do jednego\u201d.<\/p>\n<p><\/p>\n<p>Baza danych world_x w przyk\u0142adzie zawiera 4 tabele z wierszami, kt\u00f3re spo\u0142eczno\u015b\u0107 MySQL oferuje jako przyk\u0142ad. Mo\u017cna j\u0105 za\u0142adowa\u0107 <noindex><a rel=\"nofollow\" href=\"https:\/\/dev.mysql.com\/doc\/index-other.html\">tutaj<\/a><\/noindex>. Przyk\u0142ad bazy danych dostarczany jest jako archiwum tar i skompresowany z instrukcjami dotycz\u0105cymi tworzenia i importowania wierszy.<\/p>\n<p><\/p>\n<p>W bazach danych MySQL i PostgreSQL tworzony jest specjalny u\u017cytkownik o tej samej nazwie usr_replica. W MySQL przyznawane s\u0105 mu dodatkowe uprawnienia do odczytu wszystkich replikowanych tabel.<\/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>Po stronie PostgreSQL tworzona jest baza danych db_replica, kt\u00f3ra b\u0119dzie przyjmowa\u0107 zmiany z bazy danych MySQL. U\u017cytkownik usr_replica w PostgreSQL jest automatycznie konfigurowany jako w\u0142a\u015bciciel dw\u00f3ch schemat\u00f3w pgworld_x i sch_chameleon, kt\u00f3re zawieraj\u0105 faktycznie replikowane tabele oraz tabele z katalogami replikacji odpowiednio. Automatyczna konfiguracja jest realizowana przez argument create_replica_schema, o czym przekonasz si\u0119 poni\u017cej.<\/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>Baza danych MySQL jest konfigurowana z wprowadzeniem zmian w niekt\u00f3rych parametrach, aby przygotowa\u0107 j\u0105 do replikacji, jak pokazano poni\u017cej. Nale\u017cy zrestartowa\u0107 serwer baz danych, aby zmiany wesz\u0142y w \u017cycie.<\/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>Obecnie wa\u017cne jest, aby sprawdzi\u0107 po\u0142\u0105czenie z obiema bazami danych, aby podczas wykonywania polece\u0144 pg_chameleon nie wyst\u0105pi\u0142y problemy.<\/p>\n<p><\/p>\n<p>Na w\u0119\u017ale 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>Na w\u0119\u017ale 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>Nast\u0119puj\u0105ce trzy polecenia pg_chameleon (chameleon) przygotowuj\u0105 \u015brodowisko, dodaj\u0105 \u017ar\u00f3d\u0142o i inicjalizuj\u0105 replik\u0119. Argument create_replica_schema w pg_chameleon tworzy schemat domy\u015blny (sch_chameleon) i schemat replikacji (pgworld_x) w bazie danych PostgreSQL, jak ju\u017c wspomniano. Argument add_source dodaje \u017ar\u00f3d\u0142ow\u0105 baz\u0119 danych do konfiguracji, odczytuj\u0105c plik konfiguracyjny (default.yml), a w naszym przypadku to mysql, a init_replica inicjalizuje konfiguracj\u0119 na podstawie parametr\u00f3w w pliku konfiguracyjnym.<\/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>Wyniki tych trzech polece\u0144 jasno wskazuj\u0105 na ich pomy\u015blne wykonanie. Wszystkie b\u0142\u0119dy lub b\u0142\u0119dy sk\u0142adniowe s\u0105 zg\u0142aszane w prostych i zrozumia\u0142ych komunikatach, zawieraj\u0105cych wskaz\u00f3wki dotycz\u0105ce rozwi\u0105zywania problem\u00f3w.<\/p>\n<p><\/p>\n<p>Na koniec uruchomimy replikacj\u0119 za pomoc\u0105 start_replica i otrzymamy komunikat o pomy\u015blnym wykonaniu.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; chameleon start_replica --config default --source mysql \nwyj\u015bcie: Rozpoczynanie procesu replikacji dla \u017ar\u00f3d\u0142a mysql<\/code><\/pre>\n<p><\/p>\n<p>Status replikacji mo\u017cna sprawdzi\u0107 za pomoc\u0105 argumentu show_status, a b\u0142\u0119dy mo\u017cna przegl\u0105da\u0107 za pomoc\u0105 argumentu show_errors.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/xpaste.pro\/p\/iYMdAf0b\">Wynik.<\/a><\/noindex><\/p>\n<p><\/p>\n<p>Jak ju\u017c wspomniano, ka\u017cd\u0105 funkcj\u0105 replikacji zarz\u0105dzaj\u0105 demony. Aby je zobaczy\u0107, mo\u017cemy zapyta\u0107 tabel\u0119 proces\u00f3w za pomoc\u0105 polecenia Linux ps, jak pokazano poni\u017cej.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/xpaste.pro\/p\/59GfdvHA\">Wynik.<\/a><\/noindex><\/p>\n<p><\/p>\n<p>Replikacja nie jest uznawana za skonfigurowan\u0105, dop\u00f3ki nie przetestujemy jej w czasie rzeczywistym, jak pokazano poni\u017cej. Tworzymy tabel\u0119, wstawiamy kilka rekord\u00f3w do bazy danych MySQL i wywo\u0142ujemy argument sync_tables w pg_chameleon, aby zaktualizowa\u0107 demony i replikowa\u0107 tabel\u0119 z zapisami w bazie danych PostgreSQL.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">mysql&gt; create table t1 (n1 int primary key, n2 varchar(10));\nZapytanie OK, 0 wierszy dotkni\u0119tych (0.01 sek)\nmysql&gt; insert into t1 values (1,'one');\nZapytanie OK, 1 wiersz dotkni\u0119ty (0.00 sek)\nmysql&gt; insert into t1 values (2,'two');\nZapytanie OK, 1 wiersz dotkni\u0119ty (0.00 sek)<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">$&gt; chameleon sync_tables --tables world_x.t1 --config default --source mysql\nRozpocz\u0119to proces synchronizacji tabel dla \u017ar\u00f3d\u0142a mysql.<\/code><\/pre>\n<p><\/p>\n<p>Aby potwierdzi\u0107 wyniki testu, zapytujemy tabel\u0119 z bazy danych PostgreSQL i wy\u015bwietlamy wiersze.<\/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>Je\u015bli przeprowadzamy migracj\u0119, nast\u0119puj\u0105ce polecenia pg_chameleon zako\u0144cz\u0105 j\u0105. Polecenia nale\u017cy wykonywa\u0107 po upewnieniu si\u0119, \u017ce wszystkie rekordy w docelowych tabelach zosta\u0142y zreplikowane, a wynikiem b\u0119dzie starannie przeniesiona baza danych PostgreSQL bez odniesie\u0144 do \u017ar\u00f3d\u0142owej bazy danych lub schematu replikacji (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>Opcjonalnie, nast\u0119puj\u0105cymi poleceniami mo\u017cna usun\u0105\u0107 pierwotn\u0105 konfiguracj\u0119 i schemat replikacji.<\/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\">Zalety pg_chameleon<\/h3>\n<p><\/p>\n<p>Prosta konfiguracja i ustawienia.<br \/>\n\u0141atwe rozwi\u0105zywanie problem\u00f3w i identyfikacja anomalii przy pomocy zrozumia\u0142ych komunikat\u00f3w o b\u0142\u0119dach.<br \/>\nDo replikacji mo\u017cna doda\u0107 dodatkowe specjalne tabele po inicjalizacji, nie zmieniaj\u0105c pozosta\u0142ej konfiguracji.<br \/>\nMo\u017cna skonfigurowa\u0107 wiele \u017ar\u00f3d\u0142owych baz danych dla jednej docelowej, co jest bardzo wygodne, gdy \u0142\u0105czysz dane z jednej lub kilku baz danych MySQL w jednej bazie danych PostgreSQL.<br \/>\nWybrane tabele mo\u017cna nie replikowa\u0107.<\/p>\n<p><\/p>\n<h3 id=\"nedostatki-pg_chameleon\">Wady pg_chameleon<\/h3>\n<p><\/p>\n<p>Obs\u0142uguje tylko MySQL 5.5 i nowsze jako \u017ar\u00f3d\u0142o oraz PostgreSQL 9.5 i nowsze jako docelow\u0105 baz\u0119 danych.<br \/>\nKa\u017cda tabela musi mie\u0107 klucz podstawowy lub unikalny, w przeciwnym razie tabele s\u0105 inicjowane w procesie init_replica, ale nie s\u0105 replikowane.<br \/>\nReplikacja jednostronna \u2014 tylko z MySQL do PostgreSQL. Dlatego nadaje si\u0119 tylko do schematu \u201eaktywny-pasywny\u201d.<br \/>\n\u0179r\u00f3d\u0142ow\u0105 baz\u0105 danych mo\u017ce by\u0107 tylko MySQL, a wsparcie dla bazy danych PostgreSQL jako \u017ar\u00f3d\u0142a jest tylko eksperymentalne i ma ograniczenia (dowiedz si\u0119 wi\u0119cej <noindex><a rel=\"nofollow\" href=\"https:\/\/pgchameleon.org\/documents\/configuration_file.html#postgresql-source-type-experimental\">tutaj<\/a><\/noindex>)<\/p>\n<p><\/p>\n<h3 id=\"itogi-po-pg_chameleon\">Podsumowanie pg_chameleon<\/h3>\n<p><\/p>\n<p>Metoda replikacji w pg_chameleon \u015bwietnie nadaje si\u0119 do migracji bazy danych z MySQL do PostgreSQL. Znacznym minusem jest to, \u017ce replikacja jest tylko jednostronna, dlatego specjali\u015bci od baz danych raczej nie b\u0119d\u0105 chcieli jej u\u017cywa\u0107 do niczego poza migracj\u0105. Jednak problem jednostronnej replikacji mo\u017cna rozwi\u0105za\u0107 za pomoc\u0105 jeszcze jednego narz\u0119dzia open source \u2014 SymmetricDS.<\/p>\n<p><\/p>\n<p>Wi\u0119cej informacji znajdziesz w oficjalnej dokumentacji <noindex><a rel=\"nofollow\" href=\"https:\/\/pgchameleon.org\/documents\/\">tutaj<\/a><\/noindex>. Dokumentacj\u0119 pomocy w wierszu polece\u0144 mo\u017cna znale\u017a\u0107 <noindex><a rel=\"nofollow\" href=\"https:\/\/pgchameleon.org\/documents\/usage.html#https:\/\/pgchameleon.org\/documents\/usage.html\">tutaj<\/a><\/noindex>.<\/p>\n<p><\/p>\n<h3 id=\"obzor-symmetricds\">Przegl\u0105d SymmetricDS<\/h3>\n<p><\/p>\n<p>SymmetricDS to narz\u0119dzie open source, kt\u00f3re replikuje dowoln\u0105 baz\u0119 danych do innej powszechnie stosowanej bazy danych: Oracle, MongoDB, PostgreSQL, MySQL, SQL Server, MariaDB, DB2, Sybase, Greenplum, Informix, H2, Firebird i inne chmurowe instancje baz danych, takie jak Redshift i Azure itp. Dost\u0119pne funkcje: synchronizacja baz danych i plik\u00f3w, replikacja wielu wiod\u0105cych baz danych, filtrowana synchronizacja, konwersja i inne. To narz\u0119dzie w Javie wymaga standardowej wersji JRE lub JDK (wersja 8.0 lub nowsza). Mo\u017cna rejestrowa\u0107 zmiany danych na podstawie wyzwalaczy w \u017ar\u00f3d\u0142owej bazie danych i kierowa\u0107 je do odpowiedniej docelowej bazy danych w postaci paczek.<\/p>\n<p><\/p>\n<h3 id=\"vozmozhnosti-symmetricds\">Mo\u017cliwo\u015bci SymmetricDS<\/h3>\n<p><\/p>\n<p>Narz\u0119dzie jest niezale\u017cne od platformy, co oznacza, \u017ce dwie lub wi\u0119cej r\u00f3\u017cnych baz danych mog\u0105 wymienia\u0107 si\u0119 danymi.<br \/>\nRelacyjne bazy danych s\u0105 synchronizowane poprzez rejestrowanie zmian danych, a bazy danych oparte na systemach plikowych wykorzystuj\u0105 synchronizacj\u0119 plik\u00f3w.<br \/>\nDwustronna replikacja z wykorzystaniem metod Push i Pull na podstawie zestawu zasad.<br \/>\nPrzesy\u0142anie danych jest mo\u017cliwe przez zabezpieczone sieci oraz sieci o niskiej przepustowo\u015bci.<br \/>\nAutomatyczne przywracanie po wznowieniu pracy w\u0119z\u0142\u00f3w po awarii oraz automatyczne rozwi\u0105zywanie konflikt\u00f3w.<br \/>\nKompatybilno\u015b\u0107 z chmur\u0105 oraz efektywne API rozszerze\u0144.<\/p>\n<p><\/p>\n<h3 id=\"primer-1\">Przyk\u0142ad<\/h3>\n<p><\/p>\n<p>SymmetricDS mo\u017cna skonfigurowa\u0107 na jeden z dw\u00f3ch sposob\u00f3w:<br \/>\nW\u0119ze\u0142 nadrz\u0119dny, kt\u00f3ry centralnie koordynuje replikacj\u0119 danych mi\u0119dzy dwoma w\u0119z\u0142ami podrz\u0119dnymi, a wymiana danych mi\u0119dzy w\u0119z\u0142ami podrz\u0119dnymi odbywa si\u0119 tylko przez w\u0119ze\u0142 nadrz\u0119dny.<br \/>\nAktywny w\u0119ze\u0142 (w\u0119ze\u0142 1) mo\u017ce wymienia\u0107 dane do replikacji z innym aktywnym w\u0119z\u0142em (w\u0119ze\u0142 2) bez po\u015brednika.<\/p>\n<p><\/p>\n<p>W obu wariantach wymiana danych odbywa si\u0119 za pomoc\u0105 Push i Pull. W tym przyk\u0142adzie zaprezentujemy konfiguracj\u0119 'aktywny-aktywny'. Opisanie ca\u0142ej architektury zajmie zbyt du\u017co czasu, wi\u0119c zajrzyj do <noindex><a rel=\"nofollow\" href=\"https:\/\/www.symmetricds.org\/doc\/3.10\/html\/user-guide.html#_architecture\">przewodnik<\/a><\/noindex>, aby dowiedzie\u0107 si\u0119 wi\u0119cej o architekturze SymmetricDS.<\/p>\n<p><\/p>\n<p>Zainstalowanie SymmetricDS jest bardzo proste: pobierz wersj\u0119 open-source w formacie zip <noindex><a rel=\"nofollow\" href=\"https:\/\/www.symmetricds.org\/download\">st\u0105d<\/a><\/noindex> i wypakuj j\u0105 w dowolnym miejscu. W poni\u017cszej tabeli znajduj\u0105 si\u0119 informacje o lokalizacji instalacji i wersji SymmetricDS w tym przyk\u0142adzie, a tak\u017ce wersje baz danych, wersje Linux, adresy IP i porty dla obu w\u0119z\u0142\u00f3w.<\/p>\n<p><\/p>\n<p>Host<br \/>\nvm1<br \/>\nvm2<\/p>\n<p><strong>Wersja systemu operacyjnego<\/strong><br \/>\nCentOS Linux 7.6 x86_64<br \/>\nCentOS Linux 7.6 x86_64<\/p>\n<p><strong>Wersja serwera bazy danych<\/strong><br \/>\nMySQL 5.7.26<br \/>\nPostgreSQL 10.5<\/p>\n<p><strong>Port bazy danych<\/strong><br \/>\n3306<br \/>\n5832<\/p>\n<p><strong>Adres IP<\/strong><br \/>\n192.168.1.107<br \/>\n192.168.1.112<\/p>\n<p><strong>Wersja SymmetricDS<\/strong><br \/>\nSymmetricDS 3.9<br \/>\nSymmetricDS 3.9<\/p>\n<p><strong>\u015acie\u017cka instalacji SymmetricDS<\/strong><br \/>\n\/usr\/local\/symmetric-server-3.9.20<br \/>\n\/usr\/local\/symmetric-server-3.9.20<\/p>\n<p><strong>Nazwa w\u0119z\u0142a SymmetricDS<\/strong><br \/>\ncorp-000<br \/>\nstore-001<\/p>\n<p><\/p>\n<p>Tutaj instalujemy SymmetricDS w \/usr\/local\/symmetric-server-3.9.20, a r\u00f3\u017cne zagnie\u017cd\u017cone katalogi i pliki b\u0119d\u0105 przechowywane w tym miejscu. Interesuj\u0105 nas zagnie\u017cd\u017cone katalogi samples i engines. W katalogu samples znajduj\u0105 si\u0119 przyk\u0142ady plik\u00f3w konfiguracyjnych z w\u0142a\u015bciwo\u015bciami w\u0119z\u0142a, a tak\u017ce przyk\u0142ady skrypt\u00f3w SQL do szybkiego uruchamiania demonstracji.<\/p>\n<p><\/p>\n<p>W katalogu samples widzimy trzy pliki konfiguracyjne z w\u0142a\u015bciwo\u015bciami w\u0119z\u0142a \u2014 nazwa wskazuje na charakter w\u0119z\u0142a w okre\u015blonej schemacie.<\/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>W SymmetricDS znajduj\u0105 si\u0119 wszystkie niezb\u0119dne pliki konfiguracyjne dla podstawowej schemy z 3 w\u0119z\u0142ami (wariant 1), a te same pliki mo\u017cna u\u017cy\u0107 dla schemy z 2 w\u0119z\u0142ami (wariant 2). Kopiujemy potrzebny plik konfiguracyjny z katalogu samples do engines na ho\u015bcie vm1. Wygl\u0105da to tak:<\/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>Ten w\u0119ze\u0142 w konfiguracji SymmetricDS nosi nazw\u0119 corp-000, a po\u0142\u0105czenie z baz\u0105 danych jest obs\u0142ugiwane przez sterownik mysql jdbc, kt\u00f3ry wykorzystuje powy\u017cej podany \u0142a\u0144cuch po\u0142\u0105czenia oraz dane logowania. \u0141\u0105czymy si\u0119 z baz\u0105 danych replica_db, a podczas tworzenia schemy zostan\u0105 utworzone tabele. sync.url pokazuje miejsce po\u0142\u0105czenia z w\u0119z\u0142em do synchronizacji.<\/p>\n<p><\/p>\n<p>W\u0119ze\u0142 2 na ho\u015bcie vm2 jest konfigurowany jako store-001, a reszta jest okre\u015blona w pliku node.properties, kt\u00f3ry jest podany poni\u017cej. W\u0119ze\u0142 store-001 obs\u0142uguje baz\u0119 danych PostgreSQL, a pgdb_replica to baza danych do replikacji. registration.url umo\u017cliwia hostowi vm2 nawi\u0105zanie po\u0142\u0105czenia z hostem vm1 i uzyskanie od niego szczeg\u00f3\u0142\u00f3w konfiguracji.<\/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>Gotowy przyk\u0142ad SymmetricDS zawiera parametry do konfiguracji dwukierunkowej replikacji mi\u0119dzy dwoma serwerami baz danych (dwoma w\u0119z\u0142ami). Poni\u017csze kroki s\u0105 wykonywane na ho\u015bcie vm1 (corp-000), kt\u00f3ry utworzy przyk\u0142adow\u0105 schem\u0119 z 4 tabelami. Nast\u0119pnie wykonanie polecenia create-sym-tables za pomoc\u0105 symadmin tworzy tabele katalog\u00f3w, gdzie b\u0119d\u0105 przechowywane zasady i kierunek replikacji mi\u0119dzy w\u0119z\u0142ami. Na koniec do tabeli wczytywane s\u0105 przyk\u0142adowe dane.<\/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>W przyk\u0142adzie tabele item i item_selling_price s\u0105 automatycznie konfigurowane do replikacji z corp-000 do store-001, a tabele sale (sale_transaction i sale_return_line_item) s\u0105 automatycznie konfigurowane do replikacji z store-001 do corp-000. Teraz tworzymy schem\u0119 w bazie danych PostgreSQL na ho\u015bcie vm2 (store-001), aby przygotowa\u0107 j\u0105 do odbioru danych z 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>Koniecznie sprawdzamy, czy w bazie danych MySQL na vm1 s\u0105 przyk\u0142adowe tabele i tabele katalog\u00f3w SymmetricDS. Zauwa\u017c, \u017ce tabele systemowe SymmetricDS (z prefiksem sym_) s\u0105 obecnie dost\u0119pne tylko na w\u0119\u017ale corp-000, poniewa\u017c tam wykonali\u015bmy polecenie create-sym-tables i b\u0119dziemy zarz\u0105dza\u0107 replikacj\u0105. Dodatkowo w bazie danych na w\u0119\u017ale store-001 b\u0119dzie tylko 4 przyk\u0142adowe tabele bez danych.<\/p>\n<p><\/p>\n<p>Wszystko. \u015arodowisko jest gotowe do uruchomienia proces\u00f3w serwerowych sym na obu w\u0119z\u0142ach, jak pokazano poni\u017cej.<\/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>Rejestry log\u00f3w s\u0105 wysy\u0142ane do pliku logu w tle (symmetric.log) w folderze log\u00f3w w katalogu, gdzie zainstalowano SymmetricDS, a tak\u017ce do standardowego wyj\u015bcia. Serwer sym mo\u017cna teraz zainicjowa\u0107 na w\u0119\u017ale 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>Je\u017celi uruchomimy proces serwera sym na ho\u015bcie vm2, utworzy on tabele katalogu SymmetricDS tak\u017ce w bazie danych PostgreSQL. Gdy uruchomimy proces serwera sym na obu w\u0119z\u0142ach, b\u0119d\u0105 one wsp\u00f3\u0142pracowa\u0107 ze sob\u0105 w celu replikacji danych z corp-000 na store-001. Je\u015bli po kilku sekundach zapytamy o wszystkie 4 tabele po obu stronach, zobaczymy, \u017ce replikacja zako\u0144czy\u0142a si\u0119 pomy\u015blnie. Mo\u017cna r\u00f3wnie\u017c wys\u0142a\u0107 wst\u0119pne za\u0142adowanie do w\u0119z\u0142a store-001 z corp-000 nast\u0119puj\u0105c\u0105 komend\u0105.<\/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>Na tym etapie do tabeli item w bazie danych MySQL na w\u0119\u017ale corp-000 (host: vm1) dodawany jest nowy wpis, kt\u00f3ry mo\u017cna sprawdzi\u0107 pod k\u0105tem replikacji w bazie danych PostgreSQL na w\u0119\u017ale store-001. Widzimy operacj\u0119 Pull w celu przeniesienia danych z corp-000 do 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>Aby wykona\u0107 operacj\u0119 Push w celu przeniesienia danych z store-001 do corp-000, dodajemy wpis do tabeli sale_transaction i sprawdzamy, czy replikacja zosta\u0142a wykonana.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/xpaste.pro\/p\/B23cJ4sP\">Wynik.<\/a><\/noindex><\/p>\n<p><\/p>\n<p>Widzimy udane skonfigurowanie dwustronnej replikacji tabel przyk\u0142adu mi\u0119dzy bazami danych MySQL a PostgreSQL. Aby skonfigurowa\u0107 replikacj\u0119 dla nowych tabel u\u017cytkownik\u00f3w, wykonujemy nast\u0119puj\u0105ce kroki. Tworzymy tabel\u0119 t1 jako przyk\u0142ad i konfigurujemy zasady jej replikacji w nast\u0119puj\u0105cy spos\u00f3b. W ten spos\u00f3b konfigurowana jest tylko replikacja z corp-000 do 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>Nast\u0119pnie konfiguracja otrzymuje powiadomienie o zmianie schematu, czyli dodaniu nowej tabeli, za pomoc\u0105 polecenia symadmin z argumentem sync-triggers, kt\u00f3re odtwarza wyzwalacze do dopasowania definicji tabel. Wykonywana jest send-schema w celu wys\u0142ania zmian schematu do w\u0119z\u0142a store-001, a replikacja tabeli t1 jest skonfigurowana.<\/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\">Zalety SymmetricDS<\/h3>\n<p><\/p>\n<p>Prosta instalacja i konfiguracja, w tym gotowy zestaw plik\u00f3w z parametrami do tworzenia schematu z trzema lub dwoma w\u0119z\u0142ami.<br \/>\nKrosplatformowo\u015b\u0107 baz danych i niezale\u017cno\u015b\u0107 od platformy, w tym serwery, laptopy i urz\u0105dzenia mobilne.<br \/>\nReplikacja dowolnej bazy danych do innej bazy danych lokalnie, w WAN lub w chmurze.<br \/>\nMo\u017cliwo\u015b\u0107 optymalnej pracy z par\u0105 baz danych lub z kilkoma tysi\u0105cami w celu wygodnej replikacji.<br \/>\nP\u0142atna wersja z graficznym interfejsem i doskona\u0142ym wsparciem.<\/p>\n<p><\/p>\n<h3 id=\"nedostatki-symmetricds\">Wady SymmetricDS<\/h3>\n<p><\/p>\n<p>Trzeba r\u0119cznie okre\u015bla\u0107 w wierszu polece\u0144 zasady i kierunek replikacji za pomoc\u0105 operator\u00f3w SQL do za\u0142adowania tabel katalog\u00f3w, co bywa niewygodne.<br \/>\nKonfiguracja wielu tabel do replikacji mo\u017ce by\u0107 uci\u0105\u017cliwa, je\u015bli nie korzysta si\u0119 ze skrypt\u00f3w do tworzenia operator\u00f3w SQL, kt\u00f3re definiuj\u0105 zasady i kierunek replikacji.<br \/>\nDo log\u00f3w trafia zbyt wiele informacji, a czasem trzeba uporz\u0105dkowa\u0107 plik loga, aby nie zajmowa\u0142 zbyt du\u017co miejsca.<\/p>\n<p><\/p>\n<h3 id=\"itogi-po-symmetricds\">Podsumowanie SymmetricDS<\/h3>\n<p><\/p>\n<p>SymmetricDS umo\u017cliwia konfigurowanie dwukierunkowej replikacji mi\u0119dzy dwoma, trzema a nawet kilkoma tysi\u0105cami w\u0119z\u0142\u00f3w, aby realizowa\u0107 replikacj\u0119 i synchronizowa\u0107 pliki. To unikalne narz\u0119dzie, kt\u00f3re samodzielnie wykonuje wiele zada\u0144, takich jak automatyczne przywracanie danych po d\u0142ugim okresie przestoju na w\u0119\u017ale, zabezpieczona i efektywna wymiana danych mi\u0119dzy w\u0119z\u0142ami przez HTTPS, automatyczne zarz\u0105dzanie konfliktami na podstawie zestawu zasad itd. SymmetricDS wykonuje replikacj\u0119 mi\u0119dzy dowolnymi bazami danych, dlatego mo\u017cna go u\u017cywa\u0107 w r\u00f3\u017cnych scenariuszach, w tym migracji, przeprowadzce na now\u0105 wersj\u0119, dystrybucji, filtrowaniu i transformacji danych na r\u00f3\u017cnych platformach.<\/p>\n<p><\/p>\n<p>Przyk\u0142ad zosta\u0142 stworzony na podstawie oficjalnego <noindex><a rel=\"nofollow\" href=\"https:\/\/www.symmetricds.org\/doc\/3.9\/html\/tutorials.html\">kr\u00f3tkiego przewodnika<\/a><\/noindex> po SymmetricDS. W <noindex><a rel=\"nofollow\" href=\"https:\/\/www.symmetricds.org\/doc\/3.9\/html\/user-guide.html\">podr\u0119czniku u\u017cytkownika<\/a><\/noindex> Szczeg\u00f3\u0142owo opisano r\u00f3\u017cne poj\u0119cia zwi\u0105zane z konfiguracj\u0105 replikacji za pomoc\u0105 SymmetricDS.<\/p>\n<p>\u0179r\u00f3d\u0142o: <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.1.1 - 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\/pl\/blog\/administrirovanie\/perekrestnaya-replikatsiya-mezhdu-postgresql-i-mysql\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\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\/pl\/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\udd47Replikacja krzy\u017cowa mi\u0119dzy PostgreSQL a MySQL | ProHoster","description":"W og\u00f3lnych zarysach opowiem o.","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/perekrestnaya-replikatsiya-mezhdu-postgresql-i-mysql","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","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\/pl\/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\/pl\/wp-json\/wp\/v2\/posts\/38146","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=38146"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/38146\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/28635"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=38146"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=38146"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=38146"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}