linux服务器导出MYSQL中指定表中2年前的数据

linux系统中要实现一个导出MYSQL中指定表中2年前的数据的功能,有2种解决方案。

1。用SQL语句查询出数据,然后将用JAVA映射将不同的对象的属性值按照指定格式保存到指定目录的文件中。这种解决方法由于在保存数据到文件的时候用了JAVA映射,在性能方面肯定会比较慢,不过更符合面向对象的编程思想。

2。用mysqldump命令导出数据,保存到指定目录下。这种解决方法采用的是MYSQL的内部命令mysqldump实现的,保存的文件名和格式固定,性能比第一种方法好。由于项目需求对保存的文件名和格式并没有做限制,所以决定采用这种解决方案。

编程思路:a.从资源文件中读取出导出数据的表名(用逗号分隔),保存文件的目录,数据库连接的用户名和密码。

               b.将以上参数组成mysqldump命令字符串。

              例如:mysqldump -w"create_time<=date_add(sysdate(),INTERVAL -2 YEAR)" -uroot -plxlw99366  lpdb lp_sms

               c.用Runtime对象执行该命令。

               d.将Runtime执行的结果写入执行文件中。

    首先将上面的命令到liunx服务器上执行,没有任何问题。在将JAVA代码上传到linux服务器的时候报错误:[数据备份错误输出][1]mysqldump: unknown option '-2'。真是奇怪,直接执行的时候解析mysqldump命令没有任何异常,用Runtime执行同样的命令就说不知道的操作'-2'。猜想可能是JAVA虚拟机执行命令时将' -2'解析成mysqldump的一个执行参数,所以就有以上的异常。想想就决定用JAVA将2年前的日期变成字符串再组成新的命令字符串:mysqldump -w"create_time<='2008-08-02'" -uroot -plxlw99366  lpdb lp_sms 。好了没有任何异常了,但是打开备份的文件一看,什么内容都有,就是没有数据。真是奇怪了,好在mysqldump导出的文件中有很详细的参数和执行流程。检查后发现在'--where "create_time<='2008-08-02'"'处多了双引号出来。于是修改代码将双引号去掉,再次上传代码到服务器测试。仍然没有数据。难道mysqldump的条件参数中的日期类型的字段不能直接和'2008-08-02'这样的字符串比较,这样的条件语句在Navicat工具中执行select * from lp_sms where create_time<'2008-08-02'是没有问题的。没办法只有先将create_time字段转成字符串再来比较了。改写JAVA代码生成如下命令:mysqldump -w-wdate_format(create_time,'%Y%m%d')<='2008-08-02' -uroot -plxlw99366  lpdb lp_sms,上传测试通过。这里还要注意一个地方,'2008--08-02'还不能写成'2008-08-02 00:00:00',否则会报错误无法访问的数据库'2008-08...。

    总结以上处理过程,最大的结论就是在linux中用Runtime执行命令和直接在linux下执行命令还是有一些不同的,比如命令参数中带空格和'-'符号的时候就要特别注意了。还好无论怎么样问题还是解决。

 

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Calendar;
import java.util.Date;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.lx.ewm.ifc.DataMoveService;
import com.lx.ewm.tool.DateTimeUtil;

/**
 *
 * @ description:备份2年以上数据
 * @ company lingxun
 * @ author Lancelothe
 * @ date 2010-7-27
 */
@Service("dataMoveService")
@Transactional
public class DataMoveServiceBean extends BaseServiceBean implements DataMoveService
{
   
    /**
     *
     * @ description:用mysqldump命令将2年以前的数据导出保存到指定目录下。
     * @ author Lancelothe
     * @ parameter
     * @ return void
     * @ create_date 2010-7-27
     * @ update_date 2010-7-27
     * @param tableNames
     */
    public void dataMove(String tableNames,String path,String baseComm)
    {
        String[] tableNameArr=tableNames.split(",");
        StringBuffer comm;
//        String fileName;
        Runtime rt = Runtime.getRuntime();
        Process process = null;
        String date=DateTimeUtil.getDateTimeByParam(new Date(), "yyyyMMdd", Calendar.YEAR, -2);
        try
        {
            for(int i=0;i<tableNameArr.length;i++)
            {
                comm=new StringBuffer();
//                fileName=path+"/"+tableNameArr[i]+".txt";
                File file=new File(path);
                if(!file.exists())
                {
                    file.mkdirs();
                }
                //修改文件目录的权限。否则后面的mysqldump命令将无法创建数据文件(*.txt)
                rt.exec("chmod 777 "+path);
                //生成命令
                comm.append(baseComm);
                comm.append(" lpdb ");
                comm.append(tableNameArr[i]);
                //-t表示不要创建表的DDL
                //-c表示insert语句中带列名
                //-l表示导出时锁定表
//                comm.append(" -t -c -l");
                /*
                 * 由于在linux下执行mysqldump命令时在带条件导出时,条件中不能包含空格和'-'符号,所以在对日期字段进行处理时必须按照以下格式进行。
                 *mysqldump -uroot -plxlw99366 lpdb lp_sms -t -c -l -wdate_format(create_time,'%Y%m%d')<='20080802'
                 *注意在-w后的参数也不能有双引号出现,虽然直接在Linux中执行该命令时可以带双引号。
                 */
                comm.append(" -wdate_format(create_time,'%Y%m%d')<='"+date+"'");
                /*
                 * -T这个选项将会创建两个文件,一个文件包含DDL语句或者表创建语句,另一个文件包含数据。
                 *DDL文件被命名为table_name.sql,数据文件被命名为table_name.txt.路径名是存放这两个文件的目录。
                 *目录必须已经存在,并且命令的使用者有对文件的特权。
                 */
                comm.append(" -T"+path);
                System.out.println("execu sql:"+comm.toString());
                //执行命令
                process=rt.exec(comm.toString());
//                //保存命令执行结果
//                file = new File(fileName);
//                InputStream in = process.getInputStream();
//                FileOutputStream out = new FileOutputStream(file);
//                byte[] cache = new byte[2048];
//                int length = in.read(cache);
//                while (length != -1)
//                {
//                    out.write(cache, 0, length);
//                    length = in.read(cache);
//                }
//                in.close();
//                out.close();
                //查看执行异常
                InputStream error = process.getErrorStream();
                BufferedReader errorbin = new BufferedReader(new InputStreamReader(error));
                String info = errorbin.readLine();
                int j = 0;
                while (info != null)
                {
                    System.out.println("[数据备份错误输出][" + (++j) + "]" + info);
                    info = errorbin.readLine();
                }
                errorbin.close();
                error.close();
            }
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值