# database-sync **Repository Path**: ayrz2010/database-sync ## Basic Information - **Project Name**: database-sync - **Description**: 数据库表同步工具、数据仓库工具、数据集市工具,数据抽取。传入一定的参数,即可在相同或不同的数据库间进行表的同步,包括表结构的同步及数据的同步。作业由调试工具进行调度,本项目旨在提供支持各种数据库间表同步的能力 - **Primary Language**: Java - **License**: AGPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 25 - **Created**: 2021-03-22 - **Last Updated**: 2021-03-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # [database-sync](https://gitee.com/somenzz/database-sync) ## 介绍 需求背景: - 快速同步不同数据库的指定表的数据。 - 能自动同步表结构 - 支持增量或全量同步数据 - 支持指定字段同步 - 支持主流的关系型数据库: mysql、db2、postgresql、oracle、sqlserver 本程序由 java 编写,基于 1.8 版本,方便打包移植。本程序的最大用处就是构建集市或数仓所需要的基础层数据源。 简单的传入一定的参数,即可**跨数据库**实现以下功能: 1. 两个表之间数据的同步,可以增量或全量更新。 2. 两个表表结构的同步,包括自动建表,原表扩字段长度或增加字段,目标表也做相同动作。 3. 支持指定原表或目标表的字段序列,更灵活。默认按目标表的字段序列查询原表的字段序列。 4. 支持视图到表的数据抽取。 5. 日志记录、插入记录数统计、耗时统计。 结合调度工具,您可以轻松搭建一个数据仓库或集市。目前项目已经投入生产使用 ,欢迎感兴趣的朋友一起加入。 ## 程序的使用方法 数据库的信息写在配置文件中,支持各种主流关系型数据库,如 MysqL、Db2、Oracle、PostgreSQL、SqlServer ### Docker 方式: 涉及数据库及测试数据,有点麻烦,后续会弄一个... ### 普通方式 程序运行前确保已安装 java 1.8 或后续版本,已经安装 maven,如果没有请安装一下,网上到处都是安装教程。 然后 clone 源码,打包: ```sh git clone https://gitee.com/somenzz/database-sync.git cd database-sync mvn package cd target java -jar database-sync-1.3.jar ``` 将 target 下的 lib 目录 和 database-sync-1.3.jar 复制出来,放在同一目录下,然后再创建一个 config 目录,在 config 下新建一个 config.json 文件写入配置信息,然后将这个目录压缩,就可以传到服务器运行了,请注意先充分测试,jdk 要求 1.8+ ```sh [aaron@hdp002 /home/aaron/App/Java/database-sync]$ ls -ltr total 48 drwxr-xr-x 2 aaron aaron 4096 Apr 23 2020 lib -rwxrw-r-- 1 aaron aaron 157 Jun 23 2020 run.sh drwxrwxr-x 2 aaron aaron 4096 Jul 3 2020 logs -rw-rw-r-- 1 aaron aaron 24773 Mar 16 2021 database-sync-1.3.jar drwxr-xr-x 7 aaron aaron 4096 Aug 3 2020 jdk1.8.0_231 drwxrwxr-x 2 aaron aaron 4096 Feb 19 17:07 config ``` 你也可以直接下载我打包好的使用。 程序名称叫 database-sync,运行方式是这样的: ```sh (py38env) ➜ target git:(master) ✗ java -jar database-sync-1.3.jar -h Usage: java -jar database-sync-1.0.jar [options] {fromDB} {fromSchema} {fromTable} {toDB} {toSchema} {toTable} [whereClause] options: --version or -v :print version then exit --help or -h :print help info then exit --sync-ddl or -sd :auto synchronize table structure --from_fields=col1,col2 or -ff=col3,col4 :specify from fields --to_fields=col1,col2 or -tf=col3,col4 :specify to fields --no-feture or -nf :will not use database's feture ``` 比如程序的运行输出如下: ``` (py38env) ➜ target git:(master) ✗ java -jar database-sync-1.3.jar edw_test edw source_table elk_test omm target_table -nf -sd [INFO ][2021/03/17 10:57:57.95 ] Your input params are: <=== fromDb=edw_test, fromSchema=edw, fromTable=source_table, fromTableFields=[toTableFields], whereClause= ===> toDb=elk_test, toSchema=omm, toTable=target_table, toTableFields=* [INFO ][2021/03/17 10:57:57.99 ] argList=edw_test,edw,source_table,elk_test,omm,target_table [INFO ][2021/03/17 10:57:57.100] current path: D:\github\database-sync\database-sync [INFO ][2021/03/17 10:57:57.100] begin (edw_test)edw.source_table -> (elk_test)omm.target_table [INFO ][2021/03/17 10:57:57.752] jdbc:db2://192.168.169.99:60620/edwdb connection establied. [INFO ][2021/03/17 10:58:04.189] jdbc:postgresql://192.168.170.102:25108/postgres connection establied. [INFO ][2021/03/17 10:58:04.257] The varchar column length of target table is 2 times that of the source table [INFO ][2021/03/17 10:58:04.442] toTable -> (elk_test) omm.target_table not exists, create it. [INFO ][2021/03/17 10:58:04.465] get ddl from EDW.SOURCE_TABLE [INFO ][2021/03/17 10:58:04.468] create table omm.target_table( JGM VARCHAR(80) not null , ....此处省略 )WITH (compression=no, orientation=orc, version=0.12) tablespace hdfs ; alter table omm.target_table add constraint pk_target_table primary key (JGM); comment on table omm.target_table is '测试'; ....此处省略 [INFO ][2021/03/17 10:58:08.250] get table columns from omm.target_table [INFO ][2021/03/17 10:58:11.970] read data from edw.source_table [INFO ][2021/03/17 10:58:11.971] select jgm, cjgmc, ejgmc, jgjc, jgdz, jgdh, jshzh, jhhh, lhhh, dzlhhh, dezfhh, tchbz, tchjgm, deqsjgm, xgbz, rzclbz, dqyyzt, jglx, kbrq, hzjgm, qsjgm, czys, sqqqxh, pjscf, ipadd, gyzbz, sfbz, fctsxh, sdtsxh, yjhkxh, sfxh, xded, sysid, bfjed, jhlx, kykz, tdjb, lhbdh, bz, lscqxh, etlcycledate from edw.source_table [INFO ][2021/03/17 10:58:11.979] begin insert into omm.target_table... [INFO ][2021/03/17 10:58:11.980] clear data for omm.target_table is begin... [INFO ][2021/03/17 10:58:11.980] clearSql : delete from omm.target_table [INFO ][2021/03/17 10:58:17.729] clear data for omm.target_table is done [INFO ][2021/03/17 10:58:26.898] rows insert into omm.target_table is 88 [INFO ][2021/03/17 10:58:26.899] insert into omm.target_table 88 rows has been completed, cost 7.103 seconds [INFO ][2021/03/17 10:58:26.900] finished (edw_test)edw.source_table -> (elk_test)omm.target_table ``` 帮助说明: [] 中括号里的内容表示选填,例如 [options] 表示 options 下的参数不是必须的。 1、其中 options 参数解释如下: `--simple` 或者 `-s` : 简单模式,此时只进行数据传输,不进行表构的同步。 `--from_fields=col1,col2` 或者 `-ff=col1,col2` : 指定原表的字段序列,注意 = 前后不能有空格。 `--to_fields=col3,col4` 或者 `-tf=col3,col4` : 指定目标表的字段序列,注意 = 前后不能有空格。 2、whereClause 表示 where 条件,用于增量更新,程序再插入数据前先按照 where 条件进行清理数据,然后按照 where 条件从原表进行读取数据。 whereClause 最好使用双引号包起来,表示一个完整的参数。如:"jyrq='2020-12-31'" {} 大括号里的内容表示必填。 `fromDb` 是指配置在 config.json 的数据库信息,假如有以下配置文件: ```json { "postgres":{ "type":"postgres", "driver":"org.postgresql.Driver", "url":"jdbc:postgresql://localhost:5432/apidb", "user": "postgres", "password":"aaron" }, "aarondb":{ "type":"mysql", "driver":"com.mysql.cj.jdbc.Driver", "url":"jdbc:mysql://localhost:3306/aarondb?useSSL=false&characterEncoding=utf8&serverTimezone=UTC", "user": "aaron", "password":"aaron" } } ``` 则 fromDb、toDb 可以是 aarondb 或者 postgres。 - `fromSchema` 读取数据的表的模式名,可以填写 "". - `fromTable` 读取数据的表明,必须提供。 - `toSchema` 写入数据表的模式名,可以填写 "",可以和 fromSchema 不同. - `toTable` 写入数据表的表名,必须提供,当写入表不存在时,自动按读取表的表结构创建,可以和 fromTable 不同。 ## 增量更新 ```sh java -jar database-sync.jar {fromDb} {fromSchema} {fromTable} {toDb} {toSchema} {toTable} [whereClause] ``` 与全量更新的唯一区别是可以提供 where 条件,程序按 where 条件自动清理数据,写入数据。 ## 配置文件说明 配置文件位于 config/config.json,如下所示: ```json { "sjwb":{ "type":"db2", "driver":"com.ibm.db2.jcc.DB2Driver", "url":"jdbc:db2://192.168.1.*:50000/wbsj", "user": "****", "password":"****", "tbspace_ddl": "/*这里可以放置指定表空间的语句*/" "encoding":"utf-8" }, "dw_test":{ "type":"db2", "driver":"com.ibm.db2.jcc.DB2Driver", "url":"jdbc:db2://192.168.169.*:60990/dwdb", "user": "****", "password":"****", "encoding":"gbk" }, "postgres":{ "type":"postgres", "driver":"org.postgresql.Driver", "url":"jdbc:postgresql://10.99.**.**:5432/apidb", "user": "****", "password":"****", "tbspace_ddl": "WITH (compression=no, orientation=orc, version=0.12)\ntablespace hdfs\n", "encoding":"utf-8" }, "aarondb":{ "type":"mysql", "driver":"com.mysql.cj.jdbc.Driver", "url":"jdbc:mysql://localhost:3306/aarondb?useSSL=false&characterEncoding=utf8&serverTimezone=UTC", "user": "****", "password":"****", "encoding":"utf-8" }, "buffer-rows": 100000 } ``` 配置文件说明: `buffer-rows` 表示读取多少行时一块写入目标数据库,根据服务器内存大小自己做调整,100000 行提交一次满足大多数情况了。 `encoding` 用于表结构同步时,utf-8 库的字符串长度应该是 gbk 库字符串长度的 2 倍,可以解决字段含有中文的问题,为什么是 2 倍? 为了字符串的长度不会出现小数位。 ## 编写目的 提高数据库间表的同步效率,如果是轻加工,就丢掉低效的 datastage 和 kettle 吧。