您的位置:首页 > 数据库 > MySQL

MySql数据库表数据合并同步

2016-09-26 22:43 363 查看
最近遇到一个项目,一个系统要部署在两个网络区里,由于安全限制,这两个区域A和B无法保持长链接,只能是Http协议,数据交互只能只能一方(A)请求另一方(B)被动响应,数据还要定时从A汇总到B,B区的数据是全量的,A区的数据只能是A区自身可见的数据。
实现思路:
由于mysql连接是长连接所以无法使用一个数据库,所以A和B区内各有一个数据结构完全相同的数据库存储,定时把A区数据发送到B区。
通过MySql Client提供的脚本mysqldump和mysql导出导入sql语句文件,实现将A区的增量修改数据(通过where条件)同步到B区的数据库中。
具体实现:
关键代码如下


public class ProcessUtil {

/**
* mysqldump导出表数据结构和全部数据
* @param tableName
*/
public static void dumpFull(String tableName,String fileDir){
List<String> cmdList = new ArrayList<String>();
cmdList.add(SynConstatns.mysqlBinDir+"mysqldump");

cmdList.add("-u"+SynConstatns.userName);
cmdList.add("-p"+SynConstatns.passwd);

cmdList.add("--host");
cmdList.add(SynConstatns.host);

cmdList.add("--port");
cmdList.add(SynConstatns.port);

//      cmdList.add("--no-create-info");
//      cmdList.add("--replace");
cmdList.add("--complete-insert");

cmdList.add(SynConstatns.schema);
cmdList.add(tableName);
cmdList.add("--result-file="+fileDir+File.separator+tableName+".sql");

process(cmdList);
}

/**
* mysqldump导出表的where条件数据
* @param tableName
* @param whereCondition
*/
public static void dumpWhereData(String tableName,String whereCondition,String fileDir){
List<String> cmdList = new ArrayList<String>();
cmdList.add(SynConstatns.mysqlBinDir+"mysqldump");//程序中mysqldump的路径

cmdList.add("-u"+SynConstatns.userName);
cmdList.add("-p"+SynConstatns.passwd);

cmdList.add("--host");
cmdList.add(SynConstatns.host);

cmdList.add("--port");
cmdList.add(SynConstatns.port);

cmdList.add("--no-create-info");//去掉删表、建表的语句
cmdList.add("--replace");//之所以用replace生成的语句是replace into可以用于覆盖掉update操作
cmdList.add("--complete-insert");

cmdList.add(SynConstatns.schema);
cmdList.add(tableName);
cmdList.add("--where="+whereCondition);//表数据过滤条件
cmdList.add("--result-file="+fileDir+File.separator+tableName+".sql");//sql文件保存路径

process(cmdList);
}

/**
* 导入执行sql文件
*
* @param filePath
*/
public static void importData(String filePath){
List<String> cmdList = new ArrayList<String>();
cmdList.add(SynConstatns.mysqlBinDir+"mysql");
cmdList.add("-u"+SynConstatns.userName);
cmdList.add("-p"+SynConstatns.passwd);
cmdList.add("-h"+SynConstatns.host);
cmdList.add("-P"+SynConstatns.port);
cmdList.add(SynConstatns.schema);
cmdList.add("--execute=source "+filePath);
process(cmdList);
}

/**
* process执行
* @param cmds
*/
public static void process(List<String> cmds){
ProcessBuilder builder = new ProcessBuilder();
builder.redirectErrorStream(true);
try {
Process process = builder.command(cmds).start();
InputStream is = process.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is, "utf8"));
String tmp = br.readLine();
do{
System.out.println(tmp);
}while((tmp =br.readLine())!=null);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}


缺点:

只能记录insert和update操作的数据,不能记录生成删除操作的sql语句

建议对于删除操作可以不做物理删除,通过逻辑修改数据可见性的方式达到删除规避不能生成

或者创建一张删除记录表,对每张表加触发器,将删除数据的主键key和tablename记录,同步后进行关联删除记录,也可以实现删除记录的同步。

具体命令参数参考mysql官方文档

http://dev.mysql.com/doc/refman/5.7/en/mysql.html

http://dev.mysql.com/doc/refman/5.7/en/mysqldump.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息