ืฉื›ืคื•ืœ ืฆื•ืœื‘ ื‘ื™ืŸ PostgreSQL ืœ-MySQL

ืฉื›ืคื•ืœ ืฆื•ืœื‘ ื‘ื™ืŸ PostgreSQL ืœ-MySQL

ืืชืืจ ืฉื›ืคื•ืœ ืฆื•ืœื‘ ื‘ื™ืŸ PostgreSQL ืœ-MySQL, ื›ืžื• ื’ื ืฉื™ื˜ื•ืช ืœื”ื’ื“ืจืช ืฉื›ืคื•ืœ ืฆื•ืœื‘ ื‘ื™ืŸ ืฉื ื™ ืฉืจืชื™ ืžืกื“ ื”ื ืชื•ื ื™ื. ื‘ื“ืจืš ื›ืœืœ, ืžืกื“ื™ ื ืชื•ื ื™ื ืžืฉื•ื›ืคืœื™ื ื ืงืจืื™ื ื”ื•ืžื•ื’ื ื™ื™ื, ื•ื–ื• ืฉื™ื˜ื” ื ื•ื—ื” ืœืขื‘ื•ืจ ืžืฉืจืช RDBMS ืื—ื“ ืœืื—ืจ.

ืžืกื“ื™ ื ืชื•ื ื™ื PostgreSQL ื•-MySQL ื ื—ืฉื‘ื™ื ื‘ื“ืจืš ื›ืœืœ ืœื™ื—ืกื™ื, ืืš ืขื ื”ืจื—ื‘ื•ืช ื ื•ืกืคื•ืช ื”ื ืžืฆื™ืขื™ื ื™ื›ื•ืœื•ืช NoSQL. ื›ืืŸ ื ื“ื•ืŸ ื‘ืฉื›ืคื•ืœ ื‘ื™ืŸ PostgreSQL ืœ-MySQL ืžื ืงื•ื“ืช ืžื‘ื˜ ืฉืœ DBMS ื™ื—ืกื™.

ืœื ื ืชืืจ ืืช ื›ืœ ื”ืคืขื•ืœื•ืช ื”ืคื ื™ืžื™ื•ืช, ืจืง ืืช ื”ืขืงืจื•ื ื•ืช ื”ื‘ืกื™ืกื™ื™ื ื›ื“ื™ ืฉืชืงื‘ืœ ืžื•ืฉื’ ืขืœ ื”ื’ื“ืจืช ืฉื›ืคื•ืœ ื‘ื™ืŸ ืฉืจืชื™ ืžืกื“ ื ืชื•ื ื™ื, ื™ืชืจื•ื ื•ืช, ืžื’ื‘ืœื•ืช ื•ืžืงืจื™ ืฉื™ืžื•ืฉ.

ื‘ื“ืจืš ื›ืœืœ, ืฉื›ืคื•ืœ ื‘ื™ืŸ ืฉื ื™ ืฉืจืชื™ ืžืกื“ ื ืชื•ื ื™ื ื–ื”ื™ื ืžืชื‘ืฆืข ื‘ืžืฆื‘ ื‘ื™ื ืืจื™ ืื• ื‘ืืžืฆืขื•ืช ืฉืื™ืœืชื•ืช ื‘ื™ืŸ ืžืืกื˜ืจ (ื”ืžื›ื•ื ื” ืžืคืจืกื, ืžืืกื˜ืจ ืื• ืืงื˜ื™ื‘ื™) ืœื‘ื™ืŸ ืขื‘ื“ (ืžื ื•ื™, ื”ืžืชื ื” ืื• ืคืกื™ื‘ื™). ืžื˜ืจืช ื”ืฉื›ืคื•ืœ ื”ื™ื ืœืกืคืง ืขื•ืชืง ื‘ื–ืžืŸ ืืžืช ืฉืœ ืžืกื“ ื”ื ืชื•ื ื™ื ื”ืจืืฉื™ ื‘ืฆื“ ื”ืขื‘ื“. ื‘ืžืงืจื” ื–ื”, ื ืชื•ื ื™ื ืžื•ืขื‘ืจื™ื ืžืืกื˜ืจ ืœืขื‘ื“, ื›ืœื•ืžืจ ืžืืงื˜ื™ื‘ื™ ืœืคืกื™ื‘ื™, ืžื›ื™ื•ื•ืŸ ืฉื›ืคื•ืœ ืžื‘ื•ืฆืข ืจืง ื‘ื›ื™ื•ื•ืŸ ืื—ื“. ืื‘ืœ ืืชื” ื™ื›ื•ืœ ืœื”ื’ื“ื™ืจ ืฉื›ืคื•ืœ ื‘ื™ืŸ ืฉื ื™ ืžืกื“ื™ ื ืชื•ื ื™ื ื‘ืฉื ื™ ื”ื›ื™ื•ื•ื ื™ื, ื›ืš ืฉื”ื ืชื•ื ื™ื ืžื•ืขื‘ืจื™ื ืžืขื‘ื“ ืœืžืืกื˜ืจ ื‘ืชืฆื•ืจื” ืืงื˜ื™ื‘ื™ืช-ืืงื˜ื™ื‘ื™ืช. ื›ืœ ื–ื”, ื›ื•ืœืœ ืฉื›ืคื•ืœ ืžื“ื•ืจื’, ืืคืฉืจื™ ื‘ื™ืŸ ืฉื ื™ ืฉืจืชื™ ืžืกื“ ื ืชื•ื ื™ื ื–ื”ื™ื ืื• ื™ื•ืชืจ. ืชืฆื•ืจื” ืืงื˜ื™ื‘ื™ืช-ืืงื˜ื™ื‘ื™ืช ืื• ืืงื˜ื™ื‘ื™ืช-ืคืืกื™ื‘ื™ืช ืชืœื•ื™ื” ื‘ืฆื•ืจืš, ื–ืžื™ื ื•ืช ืฉืœ ื™ื›ื•ืœื•ืช ื›ืืœื” ื‘ืชืฆื•ืจื” ื”ืจืืฉื•ื ื™ืช ืื• ื‘ืฉื™ืžื•ืฉ ื‘ืคืชืจื•ื ื•ืช ืชืฆื•ืจื” ื—ื™ืฆื•ื ื™ื™ื ื•ื—ื™ืœื•ืคื™ื ืงื™ื™ืžื™ื.

ื”ืชืฆื•ืจื” ื”ืžืชื•ืืจืช ืืคืฉืจื™ืช ื‘ื™ืŸ ืฉืจืชื™ ืžืกื“ ื ืชื•ื ื™ื ืฉื•ื ื™ื. ื ื™ืชืŸ ืœื”ื’ื“ื™ืจ ืืช ื”ืฉืจืช ืœืงื‘ืœ ื ืชื•ื ื™ื ืžืฉื•ื›ืคืœื™ื ืžืฉืจืช ืžืกื“ ื ืชื•ื ื™ื ืื—ืจ ื•ืขื“ื™ื™ืŸ ืœืฉืžื•ืจ ืขืœ ืฆื™ืœื•ืžื™ ืžืฆื‘ ื‘ื–ืžืŸ ืืžืช ืฉืœ ื”ื ืชื•ื ื™ื ื”ืžืฉื•ื›ืคืœื™ื. MySQL ื•-PostgreSQL ืžืฆื™ืขื•ืช ืืช ืจื•ื‘ ื”ืชืฆื•ืจื•ืช ื”ืœืœื• ื‘ืชื•ืš ื”ื‘ื™ืช ืื• ื‘ืืžืฆืขื•ืช ื”ืจื—ื‘ื•ืช ืฉืœ ืฆื“ ืฉืœื™ืฉื™, ื›ื•ืœืœ ืฉื™ื˜ื•ืช ื™ื•ืžืŸ ื‘ื™ื ืืจื™ื•ืช, ื ืขื™ืœืช ื“ื™ืกืงื™ื ื•ืฉื™ื˜ื•ืช ืžื‘ื•ืกืกื•ืช ื”ืฆื”ืจื•ืช ื•ืฉื•ืจื•ืช.

ื™ืฉ ืฆื•ืจืš ื‘ืฉื›ืคื•ืœ ืฆื•ืœื‘ ื‘ื™ืŸ MySQL ืœ-PostgreSQL ืขื‘ื•ืจ ื”ืขื‘ืจื” ื—ื“ ืคืขืžื™ืช ืžืฉืจืช ืžืกื“ ื ืชื•ื ื™ื ืื—ื“ ืœืžืฉื ื”ื•. ืžืื’ืจื™ ืžื™ื“ืข ืืœื• ืžืฉืชืžืฉื™ื ื‘ืคืจื•ื˜ื•ืงื•ืœื™ื ืฉื•ื ื™ื, ื›ืš ืฉืœื ื ื™ืชืŸ ืœืงืฉืจ ืื•ืชื ื™ืฉื™ืจื•ืช. ื›ื“ื™ ืœื™ืฆื•ืจ ื—ื™ืœื•ืคื™ ื ืชื•ื ื™ื, ืืชื” ื™ื›ื•ืœ ืœื”ืฉืชืžืฉ ื‘ื›ืœื™ ืงื•ื“ ืคืชื•ื— ื—ื™ืฆื•ื ื™, ืœืžืฉืœ pg_chameleon.

ืžื” ื–ื” pg_chameleon

pg_chameleon ื”ื™ื ืžืขืจื›ืช ืฉื›ืคื•ืœ ืž-MySQL ืœ-PostgreSQL ื‘-Python 3. ื”ื™ื ืžืฉืชืžืฉืช ื‘ืกืคืจื™ื™ืช ื”ืงื•ื“ ื”ืคืชื•ื— mysql-replication, ื’ื ื‘-Python. ืชืžื•ื ื•ืช ืฉื•ืจื•ืช ืžื—ื•ืœืฆื•ืช ืžื˜ื‘ืœืื•ืช MySQL ื•ืžืื•ื—ืกื ื•ืช ื›ืื•ื‘ื™ื™ืงื˜ื™ JSONB ื‘ืžืกื“ ื”ื ืชื•ื ื™ื ืฉืœ PostgreSQL, ื•ืœืื—ืจ ืžื›ืŸ ืžืคื•ืขื ื—ื•ืช ืขืœ ื™ื“ื™ ื”ืคื•ื ืงืฆื™ื” pl/pgsql ื•ืžืฉื•ื›ืคืœื™ื ื‘ืžืกื“ ื”ื ืชื•ื ื™ื PostgreSQL.

ืชื›ื•ื ื•ืช ืฉืœ pg_chameleon

ื ื™ืชืŸ ืœืฉื›ืคืœ ืกื›ื™ืžื•ืช MySQL ืžืจื•ื‘ื•ืช ืžืื•ืชื• ืืฉื›ื•ืœ ืœืžืกื“ ื ืชื•ื ื™ื PostgreSQL ื™ืขื“ ื™ื—ื™ื“ ื‘ืชืฆื•ืจื” ืฉืœ ืื—ื“ ืœืจื‘ื™ื
ืฉืžื•ืช ืกื›ื™ืžืช ื”ืžืงื•ืจ ื•ื”ื™ืขื“ ืื™ื ื ื™ื›ื•ืœื™ื ืœื”ื™ื•ืช ื–ื”ื™ื.
ื ื™ืชืŸ ืœืื—ื–ืจ ื ืชื•ื ื™ ืฉื›ืคื•ืœ ืžืขืชืง ืฉืœ MySQL ืžื“ื•ืจื’.
ื˜ื‘ืœืื•ืช ืฉืื™ื ืŸ ื™ื›ื•ืœื•ืช ืœืฉื›ืคืœ ืื• ืœื™ื™ืฆืจ ืฉื’ื™ืื•ืช ืื™ื ืŸ ื ื›ืœืœื•ืช.
ื›ืœ ืคื•ื ืงืฆื™ื™ืช ืฉื›ืคื•ืœ ื ืฉืœื˜ืช ืขืœ ื™ื“ื™ ื“ืžื•ื ื™ื.
ืฉืœื™ื˜ื” ื‘ืืžืฆืขื•ืช ืคืจืžื˜ืจื™ื ื•ืงื‘ืฆื™ ืชืฆื•ืจื” ืžื‘ื•ืกืกื™ YAML.

ื“ื•ื’ืžื”

ืžืืจื—
Vm1
Vm2

ื’ืจืกืช ืžืขืจื›ืช ื”ื”ืคืขืœื”
CentOS Linux 7.6 x86_64
CentOS Linux 7.5 x86_64

ื’ืจืกืช ืฉืจืช DB
MySQL 5.7.26
ืคื•ืกื˜ื’ืจืกืœ 10.5

ื™ืฆื™ืืช DB
3306
5433

ื›ืชื•ื‘ืช IP
192.168.56.102
192.168.56.106

ื›ื“ื™ ืœื”ืชื—ื™ืœ, ื”ื›ื™ื ื• ืืช ื›ืœ ื”ืจื›ื™ื‘ื™ื ื”ื“ืจื•ืฉื™ื ืœื”ืชืงื ืช pg_chameleon. ื“ื•ื’ืžื” ื–ื• ืžืชืงื™ื ื” ืืช Python 3.6.8, ืฉื™ื•ืฆืจืช ื•ืžืคืขื™ืœื” ืืช ื”ืกื‘ื™ื‘ื” ื”ื•ื™ืจื˜ื•ืืœื™ืช.

$> wget https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tar.xz
$> tar -xJf Python-3.6.8.tar.xz
$> cd Python-3.6.8
$> ./configure --enable-optimizations
$> make altinstall

ืœืื—ืจ ื”ืชืงื ืช Python3.6 ื‘ื”ืฆืœื—ื”, ืขืœื™ืš ืœื”ืฉืœื™ื ืืช ืฉืืจ ื”ื“ืจื™ืฉื•ืช, ื›ื’ื•ืŸ ื™ืฆื™ืจื” ื•ื”ืคืขืœื” ืฉืœ ืกื‘ื™ื‘ื” ื•ื™ืจื˜ื•ืืœื™ืช. ื‘ื ื•ืกืฃ, ืžื•ื“ื•ืœ ื”-pip ืžืชืขื“ื›ืŸ ืœื’ืจืกื” ื”ืขื“ื›ื ื™ืช ื‘ื™ื•ืชืจ ื•ืžืฉืžืฉ ืœื”ืชืงื ืช pg_chameleon. ื”ืคืงื•ื“ื•ืช ืœืžื˜ื” ืžืชืงื™ื ื•ืช ื‘ื›ื•ื•ื ื” ืืช pg_chameleon 2.0.9, ืœืžืจื•ืช ืฉื”ื’ืจืกื” ื”ืื—ืจื•ื ื” ื”ื™ื 2.0.10. ื–ื” ื”ื›ืจื—ื™ ื›ื“ื™ ืœืžื ื•ืข ื‘ืื’ื™ื ื—ื“ืฉื™ื ื‘ื’ืจืกื” ื”ืžืขื•ื“ื›ื ืช.

$> python3.6 -m venv venv
$> source venv/bin/activate
(venv) $> pip install pip --upgrade
(venv) $> pip install pg_chameleon==2.0.9

ืœืื—ืจ ืžื›ืŸ ืื ื• ืงื•ืจืื™ื ืœ-pg_chameleon (chameleon ื”ื™ื ืคืงื•ื“ื”) ืขื ื”ืืจื’ื•ืžื ื˜ set_configuration_files ื›ื“ื™ ืœื”ืคืขื™ืœ ืืช pg_chameleon ื•ืœื™ืฆื•ืจ ืกืคืจื™ื•ืช ื‘ืจื™ืจืช ืžื—ื“ืœ ื•ืงื•ื‘ืฆื™ ืชืฆื•ืจื”.

(venv) $> chameleon set_configuration_files
creating directory /root/.pg_chameleon
creating directory /root/.pg_chameleon/configuration/
creating directory /root/.pg_chameleon/logs/
creating directory /root/.pg_chameleon/pid/
copying configuration  example in /root/.pg_chameleon/configuration//config-example.yml

ื›ืขืช ืื ื• ื™ื•ืฆืจื™ื ืขื•ืชืง ืฉืœ config-example.yml ื‘ืชื•ืจ default.yml ื›ืš ืฉื”ื•ื ื™ื”ืคื•ืš ืœืงื•ื‘ืฅ ืชืฆื•ืจืช ื‘ืจื™ืจืช ื”ืžื—ื“ืœ. ืงื•ื‘ืฅ ืชืฆื•ืจื” ืœื“ื•ื’ืžื” ืขื‘ื•ืจ ื“ื•ื’ืžื” ื–ื• ืžืกื•ืคืง ืœื”ืœืŸ.

$> cat default.yml
---
#global settings
pid_dir: '~/.pg_chameleon/pid/'
log_dir: '~/.pg_chameleon/logs/'
log_dest: file
log_level: info
log_days_keep: 10
rollbar_key: ''
rollbar_env: ''

# type_override allows the user to override the default type conversion into a different one.
type_override:
  "tinyint(1)":
    override_to: boolean
    override_tables:
      - "*"

#postgres  destination connection
pg_conn:
  host: "192.168.56.106"
  port: "5433"
  user: "usr_replica"
  password: "pass123"
  database: "db_replica"
  charset: "utf8"

sources:
  mysql:
    db_conn:
      host: "192.168.56.102"
      port: "3306"
      user: "usr_replica"
      password: "pass123"
      charset: 'utf8'
      connect_timeout: 10
    schema_mappings:
      world_x: pgworld_x
    limit_tables:
#      - delphis_mediterranea.foo
    skip_tables:
#      - delphis_mediterranea.bar
    grant_select_to:
      - usr_readonly
    lock_timeout: "120s"
    my_server_id: 100
    replica_batch_size: 10000
    replay_max_rows: 10000
    batch_retention: '1 day'
    copy_max_memory: "300M"
    copy_mode: 'file'
    out_dir: /tmp
    sleep_loop: 1
    on_error_replay: continue
    on_error_read: continue
    auto_maintenance: "disabled"
    gtid_enable: No
    type: mysql
    skip_events:
      insert:
        - delphis_mediterranea.foo #skips inserts on the table delphis_mediterranea.foo
      delete:
        - delphis_mediterranea #skips deletes on schema delphis_mediterranea
      update:

ืงื•ื‘ืฅ ื”ืชืฆื•ืจื” ื‘ื“ื•ื’ืžื” ื–ื• ื”ื•ื ืงื•ื‘ืฅ pg_chameleon ืœื“ื•ื’ืžื” ืขื ืฉื™ื ื•ื™ื™ื ืงืœื™ื ื›ื“ื™ ืœื”ืชืื™ื ืœืกื‘ื™ื‘ื•ืช ื”ืžืงื•ืจ ื•ื”ื™ืขื“, ื•ืœื”ืœืŸ ืกืงื™ืจื” ื›ืœืœื™ืช ืฉืœ ื”ื—ืœืงื™ื ื”ืฉื•ื ื™ื ืฉืœ ืงื•ื‘ืฅ ื”ืชืฆื•ืจื”.

ื‘ืงื•ื‘ืฅ ื”ืชืฆื•ืจื” default.yml ื™ืฉื ื• ืงื˜ืข ืฉืœ ื”ื’ื“ืจื•ืช ื’ืœื•ื‘ืœื™ื•ืช, ืฉื‘ื• ื ื™ืชืŸ ืœื ื”ืœ ื”ื’ื“ืจื•ืช ื›ืžื• ืžื™ืงื•ื ืงื•ื‘ืฅ ื”ื ืขื™ืœื”, ืžื™ืงื•ื ื”ื™ื•ืžื ื™ื, ืชืงื•ืคืช ื”ืื—ืกื•ืŸ ืฉืœ ื™ื•ืžื ื™ื ื•ื›ื•'. ืœืื—ืจ ืžื›ืŸ ืžื’ื™ืข ืกืขื™ืฃ ื“ืจื™ืกืช ื”ืกื•ื’, ืฉื‘ื• ืงื‘ื•ืฆื” ืฉืœ ื›ืœืœื™ื ืœืขืงื•ืฃ ื˜ื™ืคื•ืกื™ื ื‘ืžื”ืœืš ืฉื›ืคื•ืœ. ื”ื“ื•ื’ืžื” ื›ื‘ืจื™ืจืช ืžื—ื“ืœ ืœื›ืœืœ ืขื•ืงืฃ ืกื•ื’ ื”ืžืžื™ืจ ืืช tinyint(1) ืœืขืจืš ื‘ื•ืœื™ืื ื™. ื‘ืกืขื™ืฃ ื”ื‘ื, ืื ื• ืžืฆื™ื™ื ื™ื ืืช ืคืจื˜ื™ ื”ื—ื™ื‘ื•ืจ ืœืžืกื“ ื”ื ืชื•ื ื™ื ื”ื™ืขื“. ื‘ืžืงืจื” ืฉืœื ื•, ื–ื”ื• ืžืกื“ ื ืชื•ื ื™ื PostgreSQL, ื”ืžื›ื•ื ื” pg_conn. ื‘ืกืขื™ืฃ ื”ืื—ืจื•ืŸ, ืื ื• ืžืฆื™ื™ื ื™ื ืืช ื ืชื•ื ื™ ื”ืžืงื•ืจ, ื›ืœื•ืžืจ, ืคืจืžื˜ืจื™ ื”ื—ื™ื‘ื•ืจ ืฉืœ ืžืกื“ ื”ื ืชื•ื ื™ื ืฉืœ ื”ืžืงื•ืจ, ืกื›ื™ืžืช ื”ืžื™ืคื•ื™ ื‘ื™ืŸ ืžืกื“ื™ ื”ื ืชื•ื ื™ื ืฉืœ ื”ืžืงื•ืจ ืœืžื˜ืจื”, ื˜ื‘ืœืื•ืช ืฉื™ืฉ ืœื“ืœื’ ืขืœื™ื”ืŸ, ื–ืžืŸ ื”ืžืชื ื”, ื–ื™ื›ืจื•ืŸ, ื’ื•ื“ืœ ื—ื‘ื™ืœื”. ืฉื™ื ืœื‘ ืฉ"ืžืงื•ืจื•ืช" ื”ื•ื ืจื‘ื™ื, ื›ืœื•ืžืจ ืื ื• ื™ื›ื•ืœื™ื ืœื”ื•ืกื™ืฃ ืžืกื“ื™ ื ืชื•ื ื™ื ืžืจื•ื‘ื™ื ืฉืœ ืžืงื•ืจื•ืช ืœืžืกื“ ื ืชื•ื ื™ื ื™ืขื“ ื™ื—ื™ื“ ื›ื“ื™ ืœื”ื’ื“ื™ืจ ืชืฆื•ืจื” ืฉืœ ืจื‘ื™ื ืœืื—ื“.

ืžืกื“ ื”ื ืชื•ื ื™ื ืœื“ื•ื’ืžื” world_x ืžื›ื™ืœ 4 ื˜ื‘ืœืื•ืช ืขื ืฉื•ืจื•ืช ืฉืงื”ื™ืœืช MySQL ืžืฆื™ืขื” ื›ื“ื•ื’ืžืื•ืช. ื ื™ืชืŸ ืœื”ื•ืจื™ื“ ืื•ืชื• ื›ืืŸ. ืžืกื“ ื”ื ืชื•ื ื™ื ืœื“ื•ื’ืžื” ืžื’ื™ืข ื›ื–ืคืช ื•ืืจื›ื™ื•ืŸ ื“ื—ื•ืก ืขื ื”ื•ืจืื•ืช ืœื™ืฆื™ืจื” ื•ื™ื™ื‘ื•ื โ€‹โ€‹ืฉืœ ืฉื•ืจื•ืช.

ื‘ืžืกื“ื™ ื ืชื•ื ื™ื MySQL ื•-PostgreSQL ื ื•ืฆืจ ืžืฉืชืžืฉ ืžื™ื•ื—ื“ ื‘ืื•ืชื• ืฉื usr_replica. ื‘-MySQL ื ื™ืชื ื•ืช ืœื• ื–ื›ื•ื™ื•ืช ืงืจื™ืื” ื ื•ืกืคื•ืช ืœื›ืœ ื”ื˜ื‘ืœืื•ืช ื”ืžืฉื•ื›ืคืœื•ืช.

mysql> CREATE USER usr_replica ;
mysql> SET PASSWORD FOR usr_replica='pass123';
mysql> GRANT ALL ON world_x.* TO 'usr_replica';
mysql> GRANT RELOAD ON *.* to 'usr_replica';
mysql> GRANT REPLICATION CLIENT ON *.* to 'usr_replica';
mysql> GRANT REPLICATION SLAVE ON *.* to 'usr_replica';
mysql> FLUSH PRIVILEGES;

ื‘ืฆื“ PostgreSQL ื ื•ืฆืจ ืžืกื“ ื ืชื•ื ื™ื db_replica ืฉื™ืงื‘ืœ ืฉื™ื ื•ื™ื™ื ืžืžืกื“ ื”ื ืชื•ื ื™ื ืฉืœ MySQL. ื”ืžืฉืชืžืฉ usr_replica ื‘-PostgreSQL ืžื•ื’ื“ืจ ื‘ืื•ืคืŸ ืื•ื˜ื•ืžื˜ื™ ื›ื‘ืขืœื™ื ืฉืœ ืฉืชื™ ืกื›ืžื•ืช, pgworld_x ื•-sch_chameleon, ื”ืžื›ื™ืœื•ืช ืืช ื”ื˜ื‘ืœืื•ืช ื”ืžืฉื•ื›ืคืœื•ืช ื‘ืคื•ืขืœ ื•ืืช ื˜ื‘ืœืื•ืช ืกืคืจื™ื•ืช ื”ืฉื›ืคื•ืœ, ื‘ื”ืชืืžื”. ื”ืืจื’ื•ืžื ื˜ create_replica_schema ืื—ืจืื™ ืขืœ ืชืฆื•ืจื” ืื•ื˜ื•ืžื˜ื™ืช, ื›ืคื™ ืฉืชืจืื” ืœื”ืœืŸ.

postgres=# CREATE USER usr_replica WITH PASSWORD 'pass123';
CREATE ROLE
postgres=# CREATE DATABASE db_replica WITH OWNER usr_replica;
CREATE DATABASE

ืžืกื“ ื”ื ืชื•ื ื™ื ืฉืœ MySQL ืžื•ื’ื“ืจ ืขื ื›ืžื” ืฉื™ื ื•ื™ื™ื ื‘ืคืจืžื˜ืจื™ื ื›ื“ื™ ืœื”ื›ื™ืŸ ืื•ืชื• ืœืฉื›ืคื•ืœ ื›ืคื™ ืฉืžื•ืฆื’ ืœื”ืœืŸ. ืชืฆื˜ืจืš ืœื”ืคืขื™ืœ ืžื—ื“ืฉ ืืช ืฉืจืช ืžืกื“ ื”ื ืชื•ื ื™ื ื›ื“ื™ ืฉื”ืฉื™ื ื•ื™ื™ื ื™ื™ื›ื ืกื• ืœืชื•ืงืฃ.

$> vi /etc/my.cnf
binlog_format= ROW
binlog_row_image=FULL
log-bin = mysql-bin
server-id = 1

ื›ืขืช ื—ืฉื•ื‘ ืœื‘ื“ื•ืง ืืช ื”ื—ื™ื‘ื•ืจ ืœืฉื ื™ ืฉืจืชื™ ืžืกื“ ื”ื ืชื•ื ื™ื ื›ื“ื™ ืฉืœื ื™ื”ื™ื• ื‘ืขื™ื•ืช ื‘ื”ืคืขืœืช ื”ืคืงื•ื“ื•ืช pg_chameleon.

ื‘ืฆื•ืžืช PostgreSQL:

$> mysql -u usr_replica -Ap'admin123' -h 192.168.56.102 -D world_x

ื‘ืฆื•ืžืช MySQL:

$> psql -p 5433 -U usr_replica -h 192.168.56.106 db_replica

ืฉืœื•ืฉ ื”ืคืงื•ื“ื•ืช ื”ื‘ืื•ืช ืฉืœ pg_chameleon (ื–ื™ืงื™ืช) ืžื›ื™ื ื•ืช ืืช ื”ืกื‘ื™ื‘ื”, ืžื•ืกื™ืคื™ื ืืช ื”ืžืงื•ืจ ื•ืžืืชื—ืœื™ื ืืช ื”ืขืชืง. ื”ืืจื’ื•ืžื ื˜ create_replica_schema ืœ-pg_chameleon ื™ื•ืฆืจ ืกื›ื™ืžืช ื‘ืจื™ืจืช ืžื—ื“ืœ (sch_chameleon) ื•ืกื›ื™ืžืช ืจืคืœื™ืงืฆื™ื” (pgworld_x) ื‘ืžืกื“ ื”ื ืชื•ื ื™ื PostgreSQL, ื›ืคื™ ืฉื›ื‘ืจ ื“ื™ื‘ืจื ื•. ื”ืืจื’ื•ืžื ื˜ add_source ืžื•ืกื™ืฃ ื‘ืกื™ืก ื ืชื•ื ื™ื ืžืงื•ืจ ืœืชืฆื•ืจื” ืขืœ ื™ื“ื™ ืงืจื™ืืช ืงื•ื‘ืฅ ื”ืชืฆื•ืจื” (default.yml), ื•ื‘ืžืงืจื” ืฉืœื ื• ื–ื” mysql, ื•-init_replica ืžืืชื—ืœ ืืช ื”ืชืฆื•ืจื” ืขืœ ืกืžืš ื”ืคืจืžื˜ืจื™ื ื‘ืงื•ื‘ืฅ ื”ืชืฆื•ืจื”.

$> chameleon create_replica_schema --debug
$> chameleon add_source --config default --source mysql --debug
$> chameleon init_replica --config default --source mysql --debug

ื”ืคืœื˜ ืฉืœ ืฉืœื•ืฉ ื”ืคืงื•ื“ื•ืช ื”ืœืœื• ืžืขื™ื“ ื‘ื‘ื™ืจื•ืจ ืฉื”ืŸ ื‘ื•ืฆืขื• ื‘ื”ืฆืœื—ื”. ื›ืœ ืงืจื™ืกื•ืช ืื• ืฉื’ื™ืื•ืช ืชื—ื‘ื™ืจ ืžื“ื•ื•ื—ื•ืช ื‘ื”ื•ื“ืขื•ืช ืคืฉื•ื˜ื•ืช ื•ื‘ืจื•ืจื•ืช ืขื ืจืžื–ื™ื ื›ื™ืฆื“ ืœืชืงืŸ ืืช ื”ื‘ืขื™ื”.

ืœื‘ืกื•ืฃ, ืื ื• ืžืชื—ื™ืœื™ื ืœืฉื›ืคืœ ื‘ืืžืฆืขื•ืช start_replica ื•ืžืงื‘ืœื™ื ื”ื•ื“ืขืช ื”ืฆืœื—ื”.

$> chameleon start_replica --config default --source mysql 
output: Starting the replica process for source mysql

ื ื™ืชืŸ ืœืฉืื•ืœ ืืช ืžืฆื‘ ื”ืฉื›ืคื•ืœ ื‘ืืžืฆืขื•ืช ื”ืืจื’ื•ืžื ื˜ show_status, ื•ื ื™ืชืŸ ืœืฆืคื•ืช ื‘ืฉื’ื™ืื•ืช ื‘ืืžืฆืขื•ืช ื”ืืจื’ื•ืžื ื˜ show_errors.

ื”ืชื•ืฆืื”.

ื›ืคื™ ืฉื›ื‘ืจ ืืžืจื ื•, ื›ืœ ืคื•ื ืงืฆื™ื™ืช ืฉื›ืคื•ืœ ื ืฉืœื˜ืช ืขืœ ื™ื“ื™ ื“ืžื•ื ื™ื. ื›ื“ื™ ืœื”ืฆื™ื’ ืื•ืชื, ืื ื• ืฉื•ืœืœื™ื ืืช ื˜ื‘ืœืช ื”ืชื”ืœื™ืš ื‘ืืžืฆืขื•ืช ืคืงื•ื“ืช Linux ps, ื›ืคื™ ืฉืžื•ืฆื’ ืœื”ืœืŸ.

ื”ืชื•ืฆืื”.

ื”ืฉื›ืคื•ืœ ืื™ื ื• ื ื—ืฉื‘ ืžื•ื’ื“ืจ ืขื“ ืฉื ื‘ื“ื•ืง ืื•ืชื• ื‘ื–ืžืŸ ืืžืช, ื›ืคื™ ืฉืžื•ืฆื’ ืœื”ืœืŸ. ืื ื• ื™ื•ืฆืจื™ื ื˜ื‘ืœื”, ืžื›ื ื™ืกื™ื ื›ืžื” ืจืฉื•ืžื•ืช ืœืžืกื“ ื”ื ืชื•ื ื™ื ืฉืœ MySQL ื•ืงื•ืจืื™ื ืœืืจื’ื•ืžื ื˜ sync_tables ื‘-pg_chameleon ื›ื“ื™ ืœืขื“ื›ืŸ ืืช ื”ื“ืžื•ื ื™ื ื•ืœืฉื›ืคืœ ืืช ื”ื˜ื‘ืœื” ืขื ื”ืจืฉื•ืžื•ืช ืœืžืกื“ ื”ื ืชื•ื ื™ื PostgreSQL.

mysql> create table t1 (n1 int primary key, n2 varchar(10));
Query OK, 0 rows affected (0.01 sec)
mysql> insert into t1 values (1,'one');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t1 values (2,'two');
Query OK, 1 row affected (0.00 sec)

$> chameleon sync_tables --tables world_x.t1 --config default --source mysql
Sync tables process for source mysql started.

ื›ื“ื™ ืœืืฉืจ ืืช ืชื•ืฆืื•ืช ื”ื‘ื“ื™ืงื”, ืื ื• ืฉื•ืœืœื™ื ืืช ื”ื˜ื‘ืœื” ืžืžืกื“ ื”ื ืชื•ื ื™ื ืฉืœ PostgreSQL ื•ืžื•ืฆื™ืื™ื ืืช ื”ืฉื•ืจื•ืช.

$> psql -p 5433 -U usr_replica -d db_replica -c "select * from pgworld_x.t1";
 n1 |  n2
----+-------
  1 | one
  2 | two

ืื ืื ื—ื ื• ืžื‘ืฆืขื™ื ื”ื’ื™ืจื”, ื”ืคืงื•ื“ื•ืช ืฉืœ pg_chameleon ื”ื‘ืื•ืช ื™ื”ื™ื• ื”ืกื•ืฃ ืฉืœื”. ื™ืฉ ืœื‘ืฆืข ืืช ื”ืคืงื•ื“ื•ืช ืœืื—ืจ ืฉืื ื• ื‘ื˜ื•ื—ื™ื ืฉื”ืฉื•ืจื•ืช ืฉืœ ื›ืœ ื˜ื‘ืœืื•ืช ื”ื™ืขื“ ืฉื•ื›ืคืœื•, ื•ื”ืชื•ืฆืื” ืชื”ื™ื” ืžืกื“ ื ืชื•ื ื™ื PostgreSQL ืžื•ืขื‘ืจ ื‘ืฆื•ืจื” ืžืกื•ื“ืจืช ืœืœื ื”ืคื ื™ื•ืช ืœืžืกื“ ื”ื ืชื•ื ื™ื ืฉืœ ื”ืžืงื•ืจ ืื• ืœืกื›ื™ืžืช ื”ืฉื›ืคื•ืœ (sch_chameleon).

$> chameleon stop_replica --config default --source mysql 
$> chameleon detach_replica --config default --source mysql --debug

ืื ืชืจืฆื”, ืชื•ื›ืœ ืœื”ืฉืชืžืฉ ื‘ืคืงื•ื“ื•ืช ื”ื‘ืื•ืช ื›ื“ื™ ืœืžื—ื•ืง ืืช ื”ืชืฆื•ืจื” ื”ืžืงื•ืจื™ืช ื•ืืช ืขืจื›ืช ื”ืฉื›ืคื•ืœ.

$> chameleon drop_source --config default --source mysql --debug
$> chameleon drop_replica_schema --config default --source mysql --debug

ื”ื™ืชืจื•ื ื•ืช ืฉืœ pg_chameleon

ื”ื’ื“ืจื” ื•ืชืฆื•ืจื” ืงืœื”.
ืคืชื•ืจ ื‘ืขื™ื•ืช ื•ื–ื™ื”ื•ื™ ื—ืจื™ื’ื•ืช ื‘ืงืœื•ืช ื‘ืืžืฆืขื•ืช ื”ื•ื“ืขื•ืช ืฉื’ื™ืื” ื‘ืจื•ืจื•ืช.
ื ื™ืชืŸ ืœื”ื•ืกื™ืฃ ื˜ื‘ืœืื•ืช ืžื™ื•ื—ื“ื•ืช ื ื•ืกืคื•ืช ืœืฉื›ืคื•ืœ ืœืื—ืจ ื”ืืชื—ื•ืœ ืžื‘ืœื™ ืœืฉื ื•ืช ืืช ืฉืืจ ื”ืชืฆื•ืจื”.
ืืคืฉืจ ืœื”ื’ื“ื™ืจ ืžืกื“ื™ ื ืชื•ื ื™ื ืžืจื•ื‘ื™ื ืขื‘ื•ืจ ืžืกื“ ื ืชื•ื ื™ื ื™ืขื“ ืื—ื“, ื•ื–ื” ืฉื™ืžื•ืฉื™ ืžืื•ื“ ืื ืืชื” ืžืฉืœื‘ ื ืชื•ื ื™ื ืžืžืกื“ ื ืชื•ื ื™ื ืื—ื“ ืื• ื™ื•ืชืจ ืฉืœ MySQL ืœืžืกื“ ื ืชื•ื ื™ื ื‘ื•ื“ื“ ืฉืœ PostgreSQL.
ืื™ื ืš ืฆืจื™ืš ืœืฉื›ืคืœ ืืช ื”ื˜ื‘ืœืื•ืช ืฉื ื‘ื—ืจื•.

ื”ื—ืกืจื•ื ื•ืช ืฉืœ pg_chameleon

ื ืชืžืš ืจืง ืขื MySQL 5.5 ื•ืžืขืœื” ื›ืžืงื•ืจ ื•-PostgreSQL 9.5 ื•ืžืขืœื” ื›ืžืกื“ ื ืชื•ื ื™ื ื™ืขื“.
ืœื›ืœ ื˜ื‘ืœื” ื—ื™ื™ื‘ ืœื”ื™ื•ืช ืžืคืชื— ืจืืฉื™ ืื• ื™ื™ื—ื•ื“ื™, ืื—ืจืช ื”ื˜ื‘ืœืื•ืช ืžืืชื—ืœื•ืช ื‘ืžื”ืœืš ืชื”ืœื™ืš init_replica ืืš ืื™ื ืŸ ืžืฉื•ื›ืคืœื•ืช.
ืฉื›ืคื•ืœ ื—ื“ ื›ื™ื•ื•ื ื™ - ืจืง ืž-MySQL ืœ-PostgreSQL. ืœื›ืŸ, ื”ื•ื ืžืชืื™ื ืจืง ืœืžืขื’ืœ "ืืงื˜ื™ื‘ื™-ืคืืกื™ื‘ื™".
ื”ืžืงื•ืจ ื™ื›ื•ืœ ืœื”ื™ื•ืช ืžืกื“ ื ืชื•ื ื™ื MySQL ื‘ืœื‘ื“, ื•ื”ืชืžื™ื›ื” ื‘ืžืกื“ ื ืชื•ื ื™ื PostgreSQL ื›ืžืงื•ืจ ื”ื™ื ื ื™ืกื™ื•ื ื™ ื‘ืœื‘ื“ ื•ืขื ืžื’ื‘ืœื•ืช (ืœืžื™ื“ืข ื ื•ืกืฃ ื›ืืŸ)

ืชื•ืฆืื•ืช ืขื‘ื•ืจ pg_chameleon

ืฉื™ื˜ืช ื”ืฉื›ืคื•ืœ ื‘-pg_chameleon ืžืฆื•ื™ื ืช ืœื”ืขื‘ืจืช ืžืกื“ ื ืชื•ื ื™ื ืž-MySQL ืœ-PostgreSQL. ื”ื—ื™ืกืจื•ืŸ ื”ืžืฉืžืขื•ืชื™ ื”ื•ื ืฉื”ืฉื›ืคื•ืœ ื”ื•ื ื—ื“-ื›ื™ื•ื•ื ื™ ื‘ืœื‘ื“, ื›ืš ืฉืžืงืฆื•ืขื ื™ ืžืกื“ื™ ื”ื ืชื•ื ื™ื ืœื ืกื‘ื™ืจ ืฉื™ืจืฆื• ืœื”ืฉืชืžืฉ ื‘ื• ืœืฉื•ื ื“ื‘ืจ ืžืœื‘ื“ ื”ื’ื™ืจื”. ืื‘ืœ ืืช ื‘ืขื™ื™ืช ื”ืฉื›ืคื•ืœ ื”ื—ื“-ื›ื™ื•ื•ื ื™ ื ื™ืชืŸ ืœืคืชื•ืจ ื‘ืขื–ืจืช ื›ืœื™ ืงื•ื“ ืคืชื•ื— ืื—ืจ - SymmetricDS.

ืงืจื ืขื•ื“ ื‘ืชื™ืขื•ื“ ื”ืจืฉืžื™ ื›ืืŸ. ื ื™ืชืŸ ืœืžืฆื•ื ืขื–ืจื” ื‘ืฉื•ืจืช ื”ืคืงื•ื“ื” ื›ืืŸ.

ืกืงื™ืจื” ื›ืœืœื™ืช ืฉืœ SymmetricDS

SymmetricDS ื”ื•ื ื›ืœื™ ืงื•ื“ ืคืชื•ื— ื”ืžืฉื›ืคืœ ื›ืœ ืžืกื“ ื ืชื•ื ื™ื ืœื›ืœ ืžืกื“ ื ืชื•ื ื™ื ื ืคื•ืฅ ืื—ืจ: Oracle, MongoDB, PostgreSQL, MySQL, SQL Server, MariaDB, DB2, Sybase, Greenplum, Informix, H2, Firebird ื•ืžื•ืคืขื™ ืžืกื“ื™ ื ืชื•ื ื™ื ืื—ืจื™ื ื‘ืขื ืŸ, ืœืžืฉืœ Redshift, ื• Azure ื•ื›ื•' ืชื›ื•ื ื•ืช ื–ืžื™ื ื•ืช: ืกื ื›ืจื•ืŸ ืžืกื“ ื ืชื•ื ื™ื ื•ืงื‘ืฆื™ื, ืฉื›ืคื•ืœ ืžืกื“ ื ืชื•ื ื™ื ืจื‘ ืžืืกื˜ืจ, ืกื ื›ืจื•ืŸ ืžืกื•ื ืŸ, ื˜ืจื ืกืคื•ืจืžืฆื™ื” ื•ืขื•ื“. ื–ื”ื• ื›ืœื™ Java ื•ื“ื•ืจืฉ ืžื”ื“ื•ืจื” ืกื˜ื ื“ืจื˜ื™ืช ืฉืœ JRE ืื• JDK (ื’ืจืกื” 8.0 ื•ืžืขืœื”). ื›ืืŸ, ื ื™ืชืŸ ืœื”ืงืœื™ื˜ ืฉื™ื ื•ื™ื™ื ื‘ื ืชื•ื ื™ื ืœื˜ืจื™ื’ืจื™ื ื‘ืžืกื“ ื”ื ืชื•ื ื™ื ืฉืœ ื”ืžืงื•ืจ ื•ืœืฉืœื•ื— ืื•ืชื ืœืžืกื“ ื”ื ืชื•ื ื™ื ื”ืžืชืื™ื ื‘ืฆื•ืจืช ืืฆื•ื•ืช.

ืชื›ื•ื ื•ืช SymmetricDS

ื”ื›ืœื™ ืื™ื ื• ืชืœื•ื™ ื‘ืคืœื˜ืคื•ืจืžื”, ื›ืœื•ืžืจ ืฉื ื™ ืžืกื“ื™ ื ืชื•ื ื™ื ืฉื•ื ื™ื ืื• ื™ื•ืชืจ ื™ื›ื•ืœื™ื ืœื”ื—ืœื™ืฃ ื ืชื•ื ื™ื.
ืžืกื“ื™ ื ืชื•ื ื™ื ื™ื—ืกื™ื™ื ืžืกื•ื ื›ืจื ื™ื ื‘ืืžืฆืขื•ืช ืจืฉื•ืžื•ืช ืฉื™ื ื•ื™ ื ืชื•ื ื™ื, ื‘ืขื•ื“ ืฉืžืกื“ื™ ื ืชื•ื ื™ื ืžื‘ื•ืกืกื™ ืžืขืจื›ืช ืงื‘ืฆื™ื ืžืฉืชืžืฉื™ื ื‘ืกื ื›ืจื•ืŸ ืงื‘ืฆื™ื.
ืฉื›ืคื•ืœ ื“ื•-ื›ื™ื•ื•ื ื™ ื‘ืืžืฆืขื•ืช ืฉื™ื˜ื•ืช Push ื•-Pull ื”ืžื‘ื•ืกืกื•ืช ืขืœ ืžืขืจื›ืช ื›ืœืœื™ื.
ื”ืขื‘ืจืช ื ืชื•ื ื™ื ืืคืฉืจื™ืช ื‘ืจืฉืชื•ืช ืžืื•ื‘ื˜ื—ื•ืช ื•ื‘ืจื•ื—ื‘ ืคืก ื ืžื•ืš.
ืฉื—ื–ื•ืจ ืื•ื˜ื•ืžื˜ื™ ื›ืืฉืจ ื”ืฆืžืชื™ื ื—ื•ื–ืจื™ื ืœืคืขื•ืœ ืœืื—ืจ ื›ืฉืœ ื•ืคืชืจื•ืŸ ืกื›ืกื•ื›ื™ื ืื•ื˜ื•ืžื˜ื™.
ืžืžืฉืงื™ API ืชื•ืืžื™ื ืœืขื ืŸ ื•ืขื•ืฆืžืชื™ื™ื.

ื“ื•ื’ืžื”

ื ื™ืชืŸ ืœื”ื’ื“ื™ืจ ืืช SymmetricDS ื‘ืื—ืช ืžืฉืชื™ ื“ืจื›ื™ื:
ืฆื•ืžืช ืžืืกื˜ืจ (ื”ื•ืจื”) ืฉืžืชืื ื‘ืื•ืคืŸ ืžืจื›ื–ื™ ืืช ืฉื›ืคื•ืœ ื”ื ืชื•ื ื™ื ื‘ื™ืŸ ืฉื ื™ ืฆืžืชื™ื ืขื‘ื“ื™ื (ื™ืœื“ื™ื), ื•ืชืงืฉื•ืจืช ื‘ื™ืŸ ืฆืžืชื™ ืฆืืฆื ืžืชืจื—ืฉืช ืจืง ื“ืจืš ื”ืื‘.
ืฆื•ืžืช ืคืขื™ืœ (ืฆื•ืžืช 1) ื™ื›ื•ืœ ืœืชืงืฉืจ ืœืฆื•ืจืš ืฉื›ืคื•ืœ ืขื ืฆื•ืžืช ืคืขื™ืœ ืื—ืจ (ืฆื•ืžืช 2) ืœืœื ืžืชื•ื•ืš.

ื‘ืฉืชื™ ื”ืืคืฉืจื•ื™ื•ืช, ื—ื™ืœื•ืคื™ ื ืชื•ื ื™ื ืžืชืจื—ืฉื™ื ื‘ืืžืฆืขื•ืช Push ื•-Pull. ื‘ื“ื•ื’ืžื” ื–ื• ื ืฉืงื•ืœ ืชืฆื•ืจื” ืืงื˜ื™ื‘ื™ืช-ืืงื˜ื™ื‘ื™ืช. ื–ื” ื™ื™ืงื— ื™ื•ืชืจ ืžื“ื™ ื–ืžืŸ ืœืชืืจ ืืช ื”ืืจื›ื™ื˜ืงื˜ื•ืจื” ื›ื•ืœื”, ืื– ื‘ืฆืข ืืช ื”ืžื—ืงืจ ืฉืœืš. ืžึทื ื”ึดื™ื’ื•ึผืชืœืžื™ื“ืข ื ื•ืกืฃ ืขืœ ื”ืชืงืŸ SymmetricDS.

ื”ืชืงื ืช SymmetricDS ื”ื™ื ืคืฉื•ื˜ื” ืžืื•ื“: ื”ื•ืจื“ ืืช ื’ืจืกืช ื”ืงื•ื“ ื”ืคืชื•ื— ืฉืœ ืงื•ื‘ืฅ ื”-zip ืžื›ืืŸ ื•ืœื”ื•ืฆื™ื ืื•ืชื• ืœืืŸ ืฉืชืจืฆื”. ื”ื˜ื‘ืœื” ืฉืœื”ืœืŸ ืžืกืคืงืช ืžื™ื“ืข ืขืœ ืžื™ืงื•ื ื”ื”ืชืงื ื” ื•ื”ื’ืจืกื” ืฉืœ SymmetricDS ื‘ื“ื•ื’ืžื” ื–ื•, ื›ืžื• ื’ื ืืช ื’ืจืกืื•ืช ืžืกื“ ื”ื ืชื•ื ื™ื, ื’ืจืกืื•ืช ืœื™ื ื•ืงืก, ื›ืชื•ื‘ื•ืช IP ื•ื™ืฆื™ืื•ืช ืขื‘ื•ืจ ืฉื ื™ ื”ืฆืžืชื™ื.

ืžืืจื—
Vm1
Vm2

ื’ืจืกืช ืžืขืจื›ืช ื”ื”ืคืขืœื”
CentOS Linux 7.6 x86_64
CentOS Linux 7.6 x86_64

ื’ืจืกืช ืฉืจืช DB
MySQL 5.7.26
ืคื•ืกื˜ื’ืจืกืœ 10.5

ื™ืฆื™ืืช DB
3306
5832

ื›ืชื•ื‘ืช IP
192.168.1.107
192.168.1.112

ื’ืจืกืช SymmetricDS
SymmetricDS 3.9
SymmetricDS 3.9

ื ืชื™ื‘ ื”ืชืงื ืช SymmetricDS
/usr/local/symmetric-server-3.9.20
/usr/local/symmetric-server-3.9.20

ืฉื ืฆื•ืžืช SymmetricDS
corp-000
ื—ื ื•ืช-001

ื›ืืŸ ืื ื• ืžืชืงื™ื ื™ื ืืช SymmetricDS ื‘-/usr/local/symmetric-server-3.9.20, ื•ืฉื ื™ืื•ื—ืกื ื• ืกืคืจื™ื•ืช ืžืฉื ื” ื•ืงื‘ืฆื™ื ืฉื•ื ื™ื. ืื ื• ืžืขื•ื ื™ื™ื ื™ื ื‘ืชืชื™ ื”ืกืคืจื™ื•ืช ืฉืœ ื”ื“ื•ื’ืžืื•ืช ื•ื”ืžื ื•ืขื™ื. ืกืคืจื™ื™ืช ื”ื“ื•ื’ืžืื•ืช ืžื›ื™ืœื” ืงื•ื‘ืฆื™ ืชืฆื•ืจื” ืœื“ื•ื’ืžื” ืขื ืžืืคื™ื™ื ื™ ืฆื•ืžืช, ื›ืžื• ื’ื ืกืงืจื™ืคื˜ื™ื ืฉืœ SQL ืœื“ื•ื’ืžื” ื›ื“ื™ ืœื”ืชื—ื™ืœ ื‘ืžื”ื™ืจื•ืช.

ื‘ืกืคืจื™ื™ืช ื”ื“ื•ื’ืžืื•ืช ืื ื• ืจื•ืื™ื ืฉืœื•ืฉื” ืงื‘ืฆื™ ืชืฆื•ืจื” ืขื ืžืืคื™ื™ื ื™ ืฆื•ืžืช - ื”ืฉื ืžืฆื™ื’ ืืช ืื•ืคื™ ื”ืฆื•ืžืช ื‘ืกื›ื™ืžื” ืžืกื•ื™ืžืช.

corp-000.properties
store-001.properties
store-002.properties

ืœ-SymmetricDS ื™ืฉ ืืช ื›ืœ ืงื‘ืฆื™ ื”ืชืฆื•ืจื” ื”ื“ืจื•ืฉื™ื ืœืขื™ืฆื•ื‘ ื‘ืกื™ืกื™ ืฉืœ 3 ืฆืžืชื™ื (ืืคืฉืจื•ืช 1), ื•ื ื™ืชืŸ ืœื”ืฉืชืžืฉ ื‘ืื•ืชื ืงื‘ืฆื™ื ืœืขื™ืฆื•ื‘ ืฉืœ 2 ืฆืžืชื™ื (ืืคืฉืจื•ืช 2). ื”ืขืชืง ืืช ืงื•ื‘ืฅ ื”ืชืฆื•ืจื” ื”ื ื“ืจืฉ ืžืกืคืจื™ื™ืช ื”ื“ื•ื’ืžืื•ืช ืœืžื ื•ืขื™ื ื‘ืžืืจื— vm1. ื–ื” ื™ื•ืฆื ื›ืš:

$> cat engines/corp-000.properties
engine.name=corp-000
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://192.168.1.107:3306/replica_db?autoReconnect=true&useSSL=false
db.user=root
db.password=admin123
registration.url=
sync.url=http://192.168.1.107:31415/sync/corp-000
group.id=corp
external.id=000

ื”ืฆื•ืžืช ื”ื–ื” ื‘ืชืฆื•ืจืช SymmetricDS ื ืงืจื corp-000, ื•ื—ื™ื‘ื•ืจ ืžืกื“ ื”ื ืชื•ื ื™ื ืžื˜ื•ืคืœ ืขืœ ื™ื“ื™ ืžื ื”ืœ ื”ื”ืชืงืŸ mysql jdbc, ื”ืžืฉืชืžืฉ ื‘ืžื—ืจื•ื–ืช ื”ื—ื™ื‘ื•ืจ ืฉืœืžืขืœื” ื•ื‘ืื™ืฉื•ืจื™ ื”ื›ื ื™ืกื”. ืื ื• ืžืชื—ื‘ืจื™ื ืœืžืกื“ ื”ื ืชื•ื ื™ื replica_db ื•ื˜ื‘ืœืื•ืช ื™ื™ื•ื•ืฆืจื• ื‘ืžื”ืœืš ื™ืฆื™ืจืช ื”ืกื›ื™ืžื”. sync.url ืžืฆื™ื’ ืืช ืžื™ืงื•ื ื”ื—ื™ื‘ื•ืจ ืœืฆื•ืžืช ืœืฆื•ืจืš ืกื ื›ืจื•ืŸ.

ืฆื•ืžืช 2 ื‘ืžืืจื— vm2 ืžื•ื’ื“ืจ ื›-store-001 ื•ื”ืฉืืจ ืžืฆื•ื™ืŸ ื‘ืงื•ื‘ืฅ node.properties ืœืžื˜ื”. Node store-001 ืžืจื™ืฅ ืืช ืžืกื“ ื”ื ืชื•ื ื™ื PostgreSQL ื•-pgdb_replica ื”ื•ื ืžืกื“ ื”ื ืชื•ื ื™ื ืฉืœ ื”ืฉื›ืคื•ืœ. registration.url ืžืืคืฉืจ ืœืžืืจื— vm2 ืœื™ืฆื•ืจ ืงืฉืจ ืขื ื”ืžืืจื— vm1 ื•ืœืงื‘ืœ ืžืžื ื• ืคืจื˜ื™ ืชืฆื•ืจื”.

$> cat engines/store-001.properties
engine.name=store-001
db.driver=org.postgresql.Driver
db.url=jdbc:postgresql://192.168.1.112:5832/pgdb_replica
db.user=postgres
db.password=admin123
registration.url=http://192.168.1.107:31415/sync/corp-000
group.id=store
external.id=001

ื”ื“ื•ื’ืžื” ื”ืฉืœืžื” ืฉืœ SymmetricDS ืžื›ื™ืœื” ืคืจืžื˜ืจื™ื ืœื”ื’ื“ืจืช ืฉื›ืคื•ืœ ื“ื•-ื›ื™ื•ื•ื ื™ ื‘ื™ืŸ ืฉื ื™ ืฉืจืชื™ ืžืกื“ ื ืชื•ื ื™ื (ืฉื ื™ ืฆืžืชื™ื). ื”ืฉืœื‘ื™ื ืฉืœื”ืœืŸ ืžื‘ื•ืฆืขื™ื ืขืœ host vm1 (corp-000), ืืฉืจ ื™ืฆื•ืจ ืกื›ืžื” ืœื“ื•ื’ืžื” ืขื 4 ื˜ื‘ืœืื•ืช. ืœืื—ืจ ืžื›ืŸ ื”ืคืขืœืช create-sym-tables ืขื ื”ืคืงื•ื“ื” symadmin ื™ื•ืฆืจืช ื˜ื‘ืœืื•ืช ืกืคืจื™ื•ืช ืฉื‘ื”ืŸ ื™ื™ืฉืžืจื• ื”ื›ืœืœื™ื ื•ื›ื™ื•ื•ืŸ ื”ืฉื›ืคื•ืœ ื‘ื™ืŸ ื”ืฆืžืชื™ื. ืœื‘ืกื•ืฃ, ื ืชื•ื ื™ื ืœื“ื•ื’ืžื” ื ื˜ืขื ื™ื ืœื˜ื‘ืœืื•ืช.

vm1$> cd /usr/local/symmetric-server-3.9.20/bin
vm1$> ./dbimport --engine corp-000 --format XML create_sample.xml
vm1$> ./symadmin --engine corp-000 create-sym-tables
vm1$> ./dbimport --engine corp-000 insert_sample.sql

ื‘ื“ื•ื’ืžื”, ื˜ื‘ืœืื•ืช ื”ืคืจื™ื˜ ื•ื”ืคืจื™ื˜_selling_price ืžื•ื’ื“ืจื•ืช ืื•ื˜ื•ืžื˜ื™ืช ืœืฉื›ืคื•ืœ ืž-corp-000 ืœ-store-001, ื•ื˜ื‘ืœืื•ืช ื”ืžื›ื™ืจื” (sale_transaction ื•-sale_return_line_item) ืžื•ื’ื“ืจื•ืช ืื•ื˜ื•ืžื˜ื™ืช ืœืฉื›ืคื•ืœ ืž-store-001 ืœ-corp-000. ื›ืขืช ืื ื• ื™ื•ืฆืจื™ื ืกื›ื™ืžื” ื‘ืžืกื“ ื”ื ืชื•ื ื™ื PostgreSQL ื‘ืžืืจื— vm2 (store-001) ื›ื“ื™ ืœื”ื›ื™ืŸ ืื•ืชื• ืœืงื‘ืœ ื ืชื•ื ื™ื ืž-corp-000.

vm2$> cd /usr/local/symmetric-server-3.9.20/bin
vm2$> ./dbimport --engine store-001 --format XML create_sample.xml

ื”ืงืคื“ ืœื‘ื“ื•ืง ืฉื‘ื‘ืกื™ืก ื”ื ืชื•ื ื™ื ืฉืœ MySQL ื‘-vm1 ื™ืฉ ื˜ื‘ืœืื•ืช ืœื“ื•ื’ืžื” ื•ื˜ื‘ืœืื•ืช ืงื˜ืœื•ื’ SymmetricDS. ืฉื™ืžื• ืœื‘ ืฉื˜ื‘ืœืื•ืช ื”ืžืขืจื›ืช ืฉืœ SymmetricDS (ืขื ืงื™ื“ื•ืžืช sym_) ื–ืžื™ื ื•ืช ื›ืจื’ืข ืจืง ื‘-node corp-000 ืžื›ื™ื•ื•ืŸ ืฉืฉื ื”ืจืฆื ื• ืืช ื”ืคืงื•ื“ื” create-sym-tables ื•ื ื ื”ืœ ืืช ื”ืฉื›ืคื•ืœ. ื•ื‘ื‘ืกื™ืก ื”ื ืชื•ื ื™ื ืขืœ node store-001 ื™ื”ื™ื• ืจืง 4 ื˜ื‘ืœืื•ืช ืœื“ื•ื’ืžื” ืœืœื ื ืชื•ื ื™ื.

ืืช ื›ืœ. ื”ืกื‘ื™ื‘ื” ืžื•ื›ื ื” ืœื”ืจื™ืฅ ืชื”ืœื™ื›ื™ ืฉืจืช ืกื™ืžื ื™ื ื‘ืฉื ื™ ื”ืฆืžืชื™ื ื›ืคื™ ืฉืžื•ืฆื’ ืœื”ืœืŸ.

vm1$> cd /usr/local/symmetric-server-3.9.20/bin
vm1$> sym 2>&1 &

ืจืฉื•ืžื•ืช ื™ื•ืžืŸ ื ืฉืœื—ื•ืช ืœืงื•ื‘ืฅ ื™ื•ืžืŸ ืจืงืข (symmetric.log) ื‘ืชื™ืงื™ื™ืช ื”ื™ื•ืžื ื™ื ื‘ืกืคืจื™ื™ื” ืฉื‘ื” ืžื•ืชืงืŸ SymmetricDS, ื›ืžื• ื’ื ืœืคืœื˜ ืกื˜ื ื“ืจื˜ื™. ื›ืขืช ื ื™ืชืŸ ืœื”ืคืขื™ืœ ืืช ืฉืจืช ื”-Sym ื‘-Node store-001.

vm2$> cd /usr/local/symmetric-server-3.9.20/bin
vm2$> sym 2>&1 &

ืื ืชืคืขื™ืœ ืืช ืชื”ืœื™ืš ืฉืจืช sym ืขืœ ื”ืžืืจื— vm2, ื”ื•ื ื’ื ื™ืฆื•ืจ ื˜ื‘ืœืื•ืช ืงื˜ืœื•ื’ SymmetricDS ื‘ืžืกื“ ื”ื ืชื•ื ื™ื PostgreSQL. ืื ืืชื” ืžืคืขื™ืœ ืืช ืชื”ืœื™ืš ืฉืจืช ื”-Sym ื‘ืฉื ื™ ื”ืฆืžืชื™ื, ื”ื ืžืชื•ืืžื™ื ื–ื” ืขื ื–ื” ื›ื“ื™ ืœืฉื›ืคืœ ื ืชื•ื ื™ื ืž-corp-000 ืœ-store-001. ืื ืœืื—ืจ ืžืกืคืจ ืฉื ื™ื•ืช ื ื‘ืฆืข ืฉืื™ืœืชื” ื‘ื›ืœ 4 ื”ื˜ื‘ืœืื•ืช ืžืฉื ื™ ื”ืฆื“ื“ื™ื, ื ืจืื” ืฉื”ืฉื›ืคื•ืœ ื”ืฆืœื™ื—. ืื• ืฉืืชื” ื™ื›ื•ืœ ืœืฉืœื•ื— ืืช ื”-bootstrap ืœ-node store-001 ืž-corp-000 ืขื ื”ืคืงื•ื“ื” ื”ื‘ืื”.

vm1$> ./symadmin --engine corp-000 reload-node 001

ื‘ืฉืœื‘ ื–ื”, ืจืฉื•ืžื” ื—ื“ืฉื” ืžื•ื›ื ืกืช ืœื˜ื‘ืœืช ื”ืคืจื™ื˜ื™ื ื‘ืžืกื“ ื”ื ืชื•ื ื™ื ืฉืœ MySQL ื‘-node corp-000 (ืžืืจื—: vm1), ื•ืชื•ื›ืœ ืœื‘ื“ื•ืง ืืช ื”ืฉื›ืคื•ืœ ืฉืœื” ืœืžืกื“ ื”ื ืชื•ื ื™ื PostgreSQL ื‘-node store-001 (ืžืืจื—: vm2). ืื ื• ืจื•ืื™ื ืคืขื•ืœืช Pull ืœื”ืขื‘ืจืช ื ืชื•ื ื™ื ืž-corp-000 ืœ-store-001.

mysql> insert into item values ('22000002','Jelly Bean');
Query OK, 1 row affected (0.00 sec)

vm2$> psql -p 5832 -U postgres pgdb_replica -c "select * from item"
 item_id  |   name
----------+-----------
 11000001 | Yummy Gum
 22000002 | Jelly Bean
(2 rows)

ื›ื“ื™ ืœื‘ืฆืข ืคืขื•ืœืช Push ืœื”ืขื‘ืจืช ื ืชื•ื ื™ื ืž-store-001 ืœ-corp-000, ืื ื• ืžื›ื ื™ืกื™ื ืจืฉื•ืžื” ืœื˜ื‘ืœืช sale_transaction ื•ืžื•ื•ื“ืื™ื ืฉื”ืฉื›ืคื•ืœ ื”ืฆืœื™ื—.

ื”ืชื•ืฆืื”.

ืื ื• ืจื•ืื™ื ืืช ื”ื”ื’ื“ืจื” ื”ืžื•ืฆืœื—ืช ืฉืœ ืฉื›ืคื•ืœ ื“ื•-ื›ื™ื•ื•ื ื™ ืฉืœ ื”ื˜ื‘ืœืื•ืช ืœื“ื•ื’ืžื” ื‘ื™ืŸ ืžืกื“ื™ ื ืชื•ื ื™ื ืฉืœ MySQL ื•-PostgreSQL. ื›ื“ื™ ืœื”ื’ื“ื™ืจ ืฉื›ืคื•ืœ ืขื‘ื•ืจ ื˜ื‘ืœืื•ืช ืžืฉืชืžืฉื™ื ื—ื“ืฉื•ืช, ื‘ืฆืข ืืช ื”ืฉืœื‘ื™ื ื”ื‘ืื™ื: ืื ื• ื™ื•ืฆืจื™ื ืœืžืฉืœ ืืช ื˜ื‘ืœื” t1 ื•ืžื’ื“ื™ืจื™ื ืืช ื›ืœืœื™ ื”ืฉื›ืคื•ืœ ืฉืœื” ื‘ืื•ืคืŸ ื”ื‘ื. ื‘ื“ืจืš ื–ื• ืื ื• ืžื’ื“ื™ืจื™ื ืจืง ืฉื›ืคื•ืœ ืž-corp-000 ืœ-store-001.

mysql> create table  t1 (no integer);
Query OK, 0 rows affected (0.01 sec)

mysql> insert into sym_channel (channel_id,create_time,last_update_time) 
values ('t1',current_timestamp,current_timestamp);
Query OK, 1 row affected (0.01 sec)

mysql> insert into sym_trigger (trigger_id, source_table_name,channel_id,
last_update_time, create_time) values ('t1', 't1', 't1', current_timestamp,
current_timestamp);
Query OK, 1 row affected (0.01 sec)

mysql> insert into sym_trigger_router (trigger_id, router_id,
Initial_load_order, create_time,last_update_time) values ('t1',
'corp-2-store-1', 1, current_timestamp,current_timestamp);
Query OK, 1 row affected (0.01 sec)

ืœืื—ืจ ืžื›ืŸ, ื”ืชืฆื•ืจื” ืžืงื‘ืœืช ื”ื•ื“ืขื” ืขืœ ืฉื™ื ื•ื™ ื”ืกื›ื™ืžื”, ื›ืœื•ืžืจ ื”ื•ืกืคืช ื˜ื‘ืœื” ื—ื“ืฉื”, ื‘ืืžืฆืขื•ืช ืคืงื•ื“ืช symadmin ืขื ื”ืืจื’ื•ืžื ื˜ sync-triggers, ืืฉืจ ื™ื•ืฆืจ ืžื—ื“ืฉ ืืช ื”ื˜ืจื™ื’ืจื™ื ืœืžื™ืคื•ื™ ื”ื’ื“ืจื•ืช ื”ื˜ื‘ืœื”. send-schema ืžื‘ื•ืฆืข ื›ื“ื™ ืœืฉืœื•ื— ืฉื™ื ื•ื™ื™ื ื‘ืกื›ื™ืžื” ืœ- node store-001, ื•ืฉื›ืคื•ืœ ืฉืœ ื˜ื‘ืœื” t1 ืžื•ื’ื“ืจ.

vm1$> ./symadmin -e corp-000 --node=001 sync-triggers    
vm1$> ./symadmin send-schema -e corp-000 --node=001 t1

ื”ื™ืชืจื•ื ื•ืช ืฉืœ SymmetricDS

ื”ืชืงื ื” ื•ืชืฆื•ืจื” ืงืœื”, ื›ื•ืœืœ ืกื˜ ืžื•ื›ืŸ ืฉืœ ืงื‘ืฆื™ื ืขื ืคืจืžื˜ืจื™ื ืœื™ืฆื™ืจืช ืžืขื’ืœ ืฉืœ ืฉืœื•ืฉื” ืื• ืฉื ื™ ืฆืžืชื™ื.
ืžืกื“ื™ ื ืชื•ื ื™ื ื—ื•ืฆื™ ืคืœื˜ืคื•ืจืžื•ืช ื•ืขืฆืžืื•ืช ืคืœื˜ืคื•ืจืžื”, ื›ื•ืœืœ ืฉืจืชื™ื, ืžื—ืฉื‘ื™ื ื ื™ื™ื“ื™ื ื•ืžื›ืฉื™ืจื™ื ื ื™ื™ื“ื™ื.
ืฉื›ืคืœ ื›ืœ ืžืกื“ ื ืชื•ื ื™ื ืœื›ืœ ืžืกื“ ื ืชื•ื ื™ื ืื—ืจ ื‘ืื•ืคืŸ ืžืงื•ืžื™, ื‘-WAN ืื• ื‘ืขื ืŸ.
ืืคืฉืจื•ืช ืœืขื‘ื•ื“ื” ืžื™ื˜ื‘ื™ืช ืขื ื›ืžื” ืžืกื“ื™ ื ืชื•ื ื™ื ืื• ื›ืžื” ืืœืคื™ื ืœืฉื›ืคื•ืœ ื ื•ื—.
ื’ืจืกื” ื‘ืชืฉืœื•ื ืขื GUI ื•ืชืžื™ื›ื” ืžืฆื•ื™ื ืช.

ื—ืกืจื•ื ื•ืช ืฉืœ SymmetricDS

ืขืœื™ืš ืœื”ื’ื“ื™ืจ ื‘ืื•ืคืŸ ื™ื“ื ื™ ืืช ื”ื›ืœืœื™ื ื•ืืช ื›ื™ื•ื•ืŸ ื”ืฉื›ืคื•ืœ ื‘ืฉื•ืจืช ื”ืคืงื•ื“ื” ื‘ืืžืฆืขื•ืช ื”ืฆื”ืจื•ืช SQL ื›ื“ื™ ืœื˜ืขื•ืŸ ื˜ื‘ืœืื•ืช ืงื˜ืœื•ื’, ื“ื‘ืจ ืฉืขืœื•ืœ ืœื”ื™ื•ืช ืœื ื ื•ื—.
ื”ื’ื“ืจืช ื˜ื‘ืœืื•ืช ืจื‘ื•ืช ืœืฉื›ืคื•ืœ ืขืฉื•ื™ื” ืœื”ื™ื•ืช ืžื™ื™ื’ืขืช, ืืœื ืื ื›ืŸ ืืชื” ืžืฉืชืžืฉ ื‘ืกืงืจื™ืคื˜ื™ื ืœื™ืฆื™ืจืช ื”ืฆื”ืจื•ืช SQL ืฉืžื’ื“ื™ืจื•ืช ืืช ื”ื›ืœืœื™ื ื•ืืช ื›ื™ื•ื•ืŸ ื”ืฉื›ืคื•ืœ.
ื™ืฉ ื™ื•ืชืจ ืžื“ื™ ืžื™ื“ืข ืฉื ืจืฉื ื‘ื™ื•ืžื ื™ื, ื•ืœืคืขืžื™ื ืฆืจื™ืš ืœืกื“ืจ ืืช ืงื•ื‘ืฅ ื”ื™ื•ืžืŸ ื›ื“ื™ ืฉืœื ื™ืชืคื•ืก ื™ื•ืชืจ ืžื“ื™ ืžืงื•ื.

ืชื•ืฆืื•ืช ืขื‘ื•ืจ SymmetricDS

SymmetricDS ืžืืคืฉืจ ืœืš ืœื”ื’ื“ื™ืจ ืฉื›ืคื•ืœ ื“ื•-ื›ื™ื•ื•ื ื™ ื‘ื™ืŸ ืฉื ื™ื™ื, ืฉืœื•ืฉื”, ืื• ืืคื™ืœื• ื›ืžื” ืืœืคื™ ืฆืžืชื™ื ื›ื“ื™ ืœืฉื›ืคืœ ื•ืœืกื ื›ืจืŸ ืงื‘ืฆื™ื. ืžื“ื•ื‘ืจ ื‘ื›ืœื™ ื™ื™ื—ื•ื“ื™ ื”ืžื‘ืฆืข ื‘ืื•ืคืŸ ืขืฆืžืื™ ืžืฉื™ืžื•ืช ืจื‘ื•ืช, ื›ื’ื•ืŸ ืฉื—ื–ื•ืจ ื ืชื•ื ื™ื ืื•ื˜ื•ืžื˜ื™ ืœืื—ืจ ืชืงื•ืคื” ืืจื•ื›ื” ืฉืœ ื”ืฉื‘ืชื” ื‘ืฆื•ืžืช, ื—ื™ืœื•ืคื™ ื ืชื•ื ื™ื ืžืื•ื‘ื˜ื—ื™ื ื•ื™ืขื™ืœื™ื ื‘ื™ืŸ ืฆืžืชื™ื ื‘ืืžืฆืขื•ืช HTTPS, ื ื™ื”ื•ืœ ืงื•ื ืคืœื™ืงื˜ื™ื ืื•ื˜ื•ืžื˜ื™ ื”ืžื‘ื•ืกืก ืขืœ ืžืขืจื›ืช ื›ืœืœื™ื ื•ืขื•ื“. SymmetricDS ืžื‘ืฆืขืช ืฉื›ืคื•ืœ ื‘ื™ืŸ ื›ืœ ืžืกื“ื™ ื ืชื•ื ื™ื, ืœืคื™ื›ืš, ื ื™ืชืŸ ืœื”ืฉืชืžืฉ ื‘ื• ืขื‘ื•ืจ ืžื’ื•ื•ืŸ ืจื—ื‘ ืฉืœ ืชืจื—ื™ืฉื™ื, ื›ื•ืœืœ ื”ื’ื™ืจื”, ื”ื’ื™ืจื”, ื”ืคืฆื”, ืกื™ื ื•ืŸ ื•ื”ืžืจืช ื ืชื•ื ื™ื ื‘ื™ืŸ ืคืœื˜ืคื•ืจืžื•ืช.

ื”ื“ื•ื’ืžื” ืžื‘ื•ืกืกืช ืขืœ ื”ืจืฉืžื™ ืžื“ืจื™ืš ืžื”ื™ืจ ืžืืช SymmetricDS. IN ืžื“ืจื™ืš ืœืžืฉืชืžืฉ ืžืชืืจ ื‘ืคื™ืจื•ื˜ ืืช ื”ืžื•ืฉื’ื™ื ื”ืฉื•ื ื™ื ื”ื›ืจื•ื›ื™ื ื‘ื”ื’ื“ืจืช ืฉื›ืคื•ืœ ืขื SymmetricDS.

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”