博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
oracle创建Javasource实现数据库备份
阅读量:5011 次
发布时间:2019-06-12

本文共 15172 字,大约阅读时间需要 50 分钟。

 

因客户需求,需要在业务系统中,菜单中的网页中的按钮中加入一个按钮,用于点击备份数据库

(环境:只配置了数据源连接oralce ,应用服务器和数据服务器不在一台机器,且数据库机器oracle操作系统账号密码不知道无法远程登陆机器进行备份,)

思索许久实现思路如下:

第一步:编写一个java小程序,用于执行传入的备份命令,如expdp ls 等,

第二步:创建javasource 用于执行备份命令。

第三步:创建过程用于调用Java source。

 

创建java测试类如下:

 

import java.io.BufferedReader;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.UnknownHostException;
public class Test
{
public static String list_cmd(String str){
Runtime runtime=Runtime.getRuntime();
StringBuffer enco = new StringBuffer();
enco.append("GBK");
try{
Process proc =runtime.exec(str);
InputStream inp_suc=proc.getInputStream();
InputStream inp_err=proc.getErrorStream();
BufferedReader bfr_err = new BufferedReader(new InputStreamReader(inp_err,enco.toString()));
BufferedReader bfr_suc = new BufferedReader(new InputStreamReader(inp_suc,enco.toString()));
String strLine;
while( (strLine=(bfr_suc.readLine())) != null){
System.out.println(strLine);
}
while( (strLine=(bfr_err.readLine())) != null){
System.out.println(strLine);
}
proc.destroy();
inp_suc.close();
inp_err.close();
}catch (Exception e) {
System.out.println("EXECUTE IS ERROR!");
System.out.println(e.getMessage());
}
return "";
}
public static void main(String[] args){
list_cmd(args[0]);
}
}

 

测试java类运行输出

 

创建用户测试

  SQL> conn / as sysdba

  已连接。
  

  SQL> create user wx identified by 123;

用户已创建。SQL> grant  dba  to wx;授权成功。SQL>

 

 将java 类改装成创建javasource语法,如下:(将测试的main方法注释掉)

 

 

create or replace and compile java source named exe_linux asimport java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.net.UnknownHostException;public class Test{  public  static  String list_cmd(String str){     Runtime runtime=Runtime.getRuntime();    StringBuffer  enco  =  new  StringBuffer();     enco.append("GBK");    try{    Process proc =runtime.exec(str);    InputStream inp_suc=proc.getInputStream();    InputStream inp_err=proc.getErrorStream();    BufferedReader bfr_err = new BufferedReader(new InputStreamReader(inp_err,enco.toString()));    BufferedReader bfr_suc = new BufferedReader(new InputStreamReader(inp_suc,enco.toString()));     String strLine;        while( (strLine=(bfr_suc.readLine())) != null){              System.out.println(strLine);           }    while( (strLine=(bfr_err.readLine())) != null){             System.out.println(strLine);     }         proc.destroy();         inp_suc.close();         inp_err.close();     }catch (Exception e) {        System.out.println("EXECUTE IS ERROR!");        System.out.println(e.getMessage());      }     return "";    }          /*  public static void main(String[] args){              list_cmd(args[0]);      }      **/}/

 

使用sqlplus  连接oracle 数据库

创建Javasource  

SQL> create or replace and compile java source named exe_linux as  2  import java.io.BufferedReader;  3  import java.io.InputStream;  4  import java.io.InputStreamReader;  5  import java.net.UnknownHostException;  6  public class Test  7  {  8    public  static  String list_cmd(String str){  9   Runtime runtime=Runtime.getRuntime(); 10      StringBuffer  enco  =  new  StringBuffer(); 11      enco.append("GBK"); 12      try{ 13      Process proc =runtime.exec(str); 14      InputStream inp_suc=proc.getInputStream(); 15      InputStream inp_err=proc.getErrorStream(); 16      BufferedReader bfr_err = new BufferedReader(new InputStreamReader(inp_err,enco.toString())); 17      BufferedReader bfr_suc = new BufferedReader(new InputStreamReader(inp_suc,enco.toString())); 18       String strLine; 19          while( (strLine=(bfr_suc.readLine())) != null){ 20 21         System.out.println(strLine); 22             } 23      while( (strLine=(bfr_err.readLine())) != null){ 24 25        System.out.println(strLine); 26       } 27           proc.destroy(); 28           inp_suc.close(); 29           inp_err.close(); 30       }catch (Exception e) { 31          System.out.println("EXECUTE IS ERROR!"); 32          System.out.println(e.getMessage()); 33        } 34       return ""; 35  } 36 37  /*  public static void main(String[] args){ 38 39  list_cmd(args[0]); 40    } 41    **/ 42  } 43 44  /Java 已创建。

 

创建存储过程,(执行过程,传参数给Javasource)

 

create or replace procedure p_exe_linux(str varchar2) as language javaname 'Test.list_cmd(java.lang.String)';/

 

SQL中创建如下

 

SQL> create or replace procedure p_exe_linux(str varchar2) as language java  2  name 'Test.list_cmd(java.lang.String)';  3  /过程已创建。

 

执行测试,

 

SQL> SET SERVEROUTPUT ON    --打开服务器输出SQL> EXEC P_EXE_LINUX('ls -l')PL/SQL 过程已成功完成。  --此时没有任何输出,即使java 执行错误。SQL> exec dbms_java.set_output(1111111111111);   --打开java 输出PL/SQL 过程已成功完成。SQL> EXEC P_EXE_LINUX('ls -l')EXECUTE IS ERROR!the Permission ("java.io.FilePermission" "<
>" "execute") has not been granted to WX. ThePL/SQL to grant this is dbms_java.grant_permission( 'WX', 'SYS:java.io.FilePermission', '<
>', 'execute' )PL/SQL 过程已成功完成。SQL>

 

出现以上错误解决办法:

 

SQL> conn / as sysdba    --切换sys用户已连接。SQL> exec dbms_java.grant_permission( 'WX', 'SYS:java.io.FilePermission', '<
>', 'execute' ) PL/SQL 过程已成功完成。SQL> conn wx/123 --切换普通用户已连接。SQL> EXEC P_EXE_LINUX('ls -l') PL/SQL 过程已成功完成。 --执行没有输出,切换用户后,需要重新执行dbms_java.set_output和 set serveroutput on SQL> exec dbms_java.set_output(1111111111111);PL/SQL 过程已成功完成。SQL> EXEC P_EXE_LINUX('ls -l')PL/SQL 过程已成功完成。SQL> SET SERVEROUTPUT ONSQL> EXEC P_EXE_LINUX('ls -l') 成功执行total 48-rwxrwx---+ 1 Administrators None 3584 Oct 22 17:59 PWDwx.ora-rwxrwx---+ 1 Unknown+User Unknown+Group 3584 Nov 1 16:39 SPFILEWX.ORAdrwxrwx---+ 1 Administrators None 0 Oct 19 09:58 archive-rwxrwx---+ 1 Unknown+User Unknown+Group 2048 Oct 19 12:23 hc_wx.dat-rwxrwx---+ 1 Administrators None 31744 Dec 21 2005 oradba.exe-rwxrwx---+ 1 Unknown+User Unknown+Group 2647 Nov 1 16:27 oradim.logtotal 48-rwxrwx---+ 1 Administrators None 3584 Oct 22 17:59 PWDwx.ora-rwxrwx---+ 1 Unknown+User Unknown+Group 3584 Nov 1 16:39 SPFILEWX.ORAdrwxrwx---+ 1 Administrators None 0 Oct 19 09:58 archive-rwxrwx---+ 1 Unknown+User Unknown+Group 2048 Oct 19 12:23 hc_wx.dat-rwxrwx---+ 1 Administrators None 31744 Dec 21 2005 oradba.exe-rwxrwx---+ 1 Unknown+User Unknown+Group 2647 Nov 1 16:27 oradim.logPL/SQL 过程已成功完成。SQL>

 

 执行导出,要确保用户具有导出数据库的权限,这里我的用户授予了dba角色,演示如下:

  C:\Users\nantian>sqlplus / as sysdba

  SQL*Plus: Release 12.2.0.1.0 Production on 星期五 11月 2 08:37:46 2018

  Copyright (c) 1982, 2016, Oracle. All rights reserved.

  连接到:
  Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

  SQL> grant dba to wx;

  授权成功。

  SQL>

C:\Users\nantian>sqlplus wx/123SQL*Plus: Release 12.2.0.1.0 Production on 星期四 11月 1 16:51:00 2018Copyright (c) 1982, 2016, Oracle.  All rights reserved.上次成功登录时间: 星期四 11月 01 2018 16:50:47 +08:00连接到:Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit ProductionSQL> set serveroutput onSQL> exec dbms_java.set_output(1111111111111);PL/SQL 过程已成功完成。SQL> exec p_exe_linux('expdp zhjf/123 dumpfile=111111111.dmp logfile=1111111.log tables=SYS_PARAM')Export: Release 12.2.0.1.0 - Production on 星期四 11月 1 16:51:37 2018Copyright (c) 1982, 2017, Oracle and/or its affiliates.  All rights reserved.连接到: Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bitProduction启动 "ZHJF"."SYS_EXPORT_TABLE_01":  zhjf/******** dumpfile=111111111.dmplogfile=1111111.log tables=SYS_PARAM处理对象类型 TABLE_EXPORT/TABLE/TABLE_DATA处理对象类型 TABLE_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS处理对象类型 TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS处理对象类型 TABLE_EXPORT/TABLE/STATISTICS/MARKER处理对象类型 TABLE_EXPORT/TABLE/TABLE处理对象类型 TABLE_EXPORT/TABLE/INDEX/INDEX处理对象类型 TABLE_EXPORT/TABLE/CONSTRAINT/CONSTRAINT. . 导出了 "ZHJF"."SYS_PARAM"                              0 KB       0 行已成功加载/卸载了主表 "ZHJF"."SYS_EXPORT_TABLE_01"******************************************************************************ZHJF.SYS_EXPORT_TABLE_01 的转储文件集为:E:\APP\NANTIAN\VIRTUAL\ADMIN\WX\DPDUMP\111111111.DMP作业 "ZHJF"."SYS_EXPORT_TABLE_01" 已于 星期四 11月 1 16:52:22 2018 elapsed 000:00:40 成功完成PL/SQL 过程已成功完成。SQL>

 

此处只演示了实现例子,如备份文件名重复会导致备份失败,,可在java中将dmp文件名拼接为日期精确到时分秒,可解决备份文件存在错误。

 

 

自动生成文件名备份,传入参数总无需写入文件名

 创建javasource 名称为Auto_Exp如下:

SQL> create or replace and compile java source named Auto_Exp as  2  import java.io.BufferedReader;  3  import java.io.InputStream;  4  import java.io.InputStreamReader;  5  import java.net.UnknownHostException;  6  import java.text.DateFormat;  7  import java.text.SimpleDateFormat;  8  import java.util.Date;  9  public class Auto_Exp 10  { 11 12    public  static  String exe_cmd(String str,String schema){ 13    String exe_str=""; 14     Runtime runtime=Runtime.getRuntime(); 15      StringBuffer  enco  =  new  StringBuffer(); 16      enco.append("GBK"); 17         Date date = new Date(); 18         SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 19  //UUID uuid=UUID.randomUUID(); 20        String dmpName=df2.format(date).replaceAll("\\s", "").replaceAll(":", "").replaceAll("-", ""); 21  System.out.println("FileName:"+schema+"_"+dmpName+".dmp"); 22      exe_str=str+" "+"dumpfile="+schema+"_"+dmpName+".dmp"+" "+"logfile="+schema+"_"+dmpName+".log"; 23      System.out.println("Exe_Message:"+exe_str); 24   try{ 25 26      Process proc =runtime.exec(exe_str); 27      InputStream inp_suc=proc.getInputStream(); 28      InputStream inp_err=proc.getErrorStream(); 29      BufferedReader bfr_err = new BufferedReader(new InputStreamReader(inp_err,enco.toString())); 30      BufferedReader bfr_suc = new BufferedReader(new InputStreamReader(inp_suc,enco.toString())); 31       String strLine; 32           while( (strLine=(bfr_suc.readLine())) != null){ 33 34         System.out.println(strLine); 35             } 36      while( (strLine=(bfr_err.readLine())) != null){ 37 38        System.out.println(strLine); 39       } 40           proc.destroy(); 41           inp_suc.close(); 42           inp_err.close(); 43       }catch (Exception e) { 44          System.out.println("EXECUTE IS ERROR!"); 45          System.out.println(e.getMessage()); 46        } 47        System.out.println("FINISHED !"); 48 49 50      return ""; 51    } 52 53  } 54  /Java 已创建。

 

创建过程

 

SQL> create or replace procedure auto_exp(str varchar2,str2 varchar2) as language java  2  name 'Auto_Exp.exe_cmd(java.lang.String,java.lang.String)';  3  /过程已创建。SQL>

 

开始执行测试

 exec Auto_Exp('expdp zhjf/1 ','zhjf')

 

传入参数解释:第一个参数导出完整命令,详细命令格式参见expdp help=y 查看,第二个我参数为导出的用户,文件名和日志名自动生成,规则可以在java代码中修改,

 

linux和unix 中执行 exec Auto_Exp('expdp zhjf/1 ','zhjf') 可能报错误,请参见上述部署中键入 EXEC P_EXE_LINUX('env') 

这里我连接了一台Linux oralce 服务器,
查看环境变量信息,如下:

C:\Users\nantian>sqlplus ecmapp/ecmapp@10.10.54.253:1521/ecmdb

SQL*Plus: Release 12.2.0.1.0 Production on 星期四 11月 1 17:32:33 2018

Copyright (c) 1982, 2016, Oracle. All rights reserved.

上次成功登录时间: 星期五 11月 02 2018 00:30:23 +08:00

连接到:

Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options

SQL> set serveroutput onSQL> exec dbms_java.set_output(111111111);PL/SQL 过程已成功完成。SQL> EXEC P_EXE_LINUX('env')LESSKEY=/etc/lesskey.binXDG_VTNR=1NNTPSERVER=newsMANPATH=/usr/local/man:/usr/share/manXDG_SESSION_ID=1HOSTNAME=ecmosXKEYSYMDB=/usr/X11R6/lib/X11/XKeysymDBHOST=ecmosSHELL=/bin/bashTERM=linuxPROFILEREAD=trueHISTSIZE=1000MORE=-slUSER=oracleLD_LIBRARY_PATH=/oracle/product/12.1.0/lib:LS_COLORS=no=00:fi=00:di=01;34:ln=00;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=41;33;01:ex=00;32:*.cmd=00;32:*.exe=01;32:*.com=01;32:*.bat=01;32:*.btm=01;32:*.dll=01;32:*.tar=00;31:*.tbz=00;31:*.tgz=00;31:*.rpm=00;31:*.deb=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.lzma=00;31:*.zip=00;31:*.zoo=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.tb2=00;31:*.tz2=00;31:*.tbz2=00;31:*.xz=00;31:*.avi=01;35:*.bmp=01;35:*.fli=01;35:*.gif=01;35:*.jpg=01;35:*.jpeg=01;35:*.mng=01;35:*.mov=01;35:*.mpg=01;35:*.pcx=01;35:*.pbm=01;35:*.pgm=01;35:*.png=01;35:*.ppm=01;35:*.tga=01;35:*.tif=01;35:*.xbm=01;35:*.xpm=01;35:*.dl=01;35:*.gl=01;35:*.wmv=01;35:*.aiff=00;32:*.au=00;32:*.mid=00;32:*.mp3=00;32:*.ogg=00;32:*.voc=00;32:*.wav=00;32:ORACLE_SID=ecmdbXNLSPATH=/usr/share/X11/nlsORACLE_BASE=/oracleQEMU_AUDIO_DRV=paHOSTTYPE=x86_64FROM_HEADER=PAGER=lessCSHEDIT=emacsXDG_CONFIG_DIRS=/etc/xdgMINICOM=-c onMAIL=/var/spool/mail/oraclePATH=CPU=x86_64INPUTRC=/etc/inputrcPWD=/oracleLANG=en_US.UTF-8PYTHONSTARTUP=/etc/pythonstartGPG_TTY=/dev/tty1AUDIODRIVER=pulseaudioQT_SYSTEM_DIR=/usr/share/desktop-dataSHLVL=1XDG_SEAT=seat0HOME=/oracleALSA_CONFIG_PATH=/etc/alsa-pulse.confSDL_AUDIODRIVER=pulseLESS_ADVANCED_PREPROCESSOR=noOSTYPE=linuxLS_OPTIONS=-N --color=tty -T 0XCURSOR_THEME=DMZWINDOWMANAGER=env GNOME_SHELL_SESSION_MODE=sle-classic gnome-session --sessionsle-classicG_FILENAME_ENCODING=@locale,UTF-8,ISO-8859-15,CP1252LESS=-M -I -RMACHTYPE=x86_64-suse-linuxLOGNAME=oracleCVS_RSH=sshXDG_DATA_DIRS=/usr/shareLESSOPEN=lessopen.sh %sXDG_RUNTIME_DIR=/run/user/1001ORACLE_HOME=/oracle/product/12.1.0LESSCLOSE=lessclose.sh %s %sG_BROKEN_FILENAMES=1COLORTERM=1_=/oracle/product/12.1.0/bin/sqlplusORA_NET2_DESC=17,20ORACLE_SPAWNED_PROCESS=1PL/SQL 过程已成功完成。SQL>

 

请尝试键入绝对路径查看ORACLE_HOME变量,使用绝对路径执行解决错误,如下:

exec Auto_Exp('/oracle/product/12.1.0/bin/expdp zhjf/1 ','zhjf')

 

windown 导出文件名日志名自动成示例:

C:\Users\nantian>sqlplus wx/123SQL*Plus: Release 12.2.0.1.0 Production on 星期四 11月 1 17:39:34 2018Copyright (c) 1982, 2016, Oracle.  All rights reserved.上次成功登录时间: 星期四 11月 01 2018 17:36:23 +08:00连接到:Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit ProductionSQL> set serveroutput onSQL> exec dbms_java.set_output(11111111111);PL/SQL 过程已成功完成。SQL>   exec Auto_Exp('expdp zhjf/123  tables=SYS_LOGGER','zhjf')FileName:zhjf_20181101174028.dmpExe_Message:expdp zhjf/123  tables=SYS_LOGGER dumpfile=zhjf_20181101174028.dmplogfile=zhjf_20181101174028.logExport: Release 12.2.0.1.0 - Production on 星期四 11月 1 17:40:29 2018Copyright (c) 1982, 2017, Oracle and/or its affiliates.  All rights reserved.连接到: Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bitProduction启动 "ZHJF"."SYS_EXPORT_TABLE_01":  zhjf/******** tables=SYS_LOGGERdumpfile=zhjf_20181101174028.dmp logfile=zhjf_20181101174028.log处理对象类型 TABLE_EXPORT/TABLE/TABLE_DATA处理对象类型 TABLE_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS处理对象类型 TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS处理对象类型 TABLE_EXPORT/TABLE/STATISTICS/MARKER处理对象类型 TABLE_EXPORT/TABLE/TABLE. . 导出了 "ZHJF"."SYS_LOGGER"                         735.9 MB 5455743 行已成功加载/卸载了主表 "ZHJF"."SYS_EXPORT_TABLE_01"******************************************************************************ZHJF.SYS_EXPORT_TABLE_01 的转储文件集为:E:\APP\NANTIAN\VIRTUAL\ADMIN\WX\DPDUMP\ZHJF_20181101174028.DMP作业 "ZHJF"."SYS_EXPORT_TABLE_01" 已于 星期四 11月 1 17:41:28 2018 elapsed 000:00:57 成功完成FINISHED !PL/SQL 过程已成功完成。SQL>

 

如上文件名为自动生成,且不易重复。

linux 示例命令有所不同需要将命令修改为绝对路径的expdp 执行 exec Auto_Exp('/u01/app/oracle/product/11.2.0/db_1/bin/expdp zhjf/1 ','zhjf')

ORACLE_HOME为/u01/app/oracle/product/11.2.0/db_1

 

问题1:需要自动备份,可在Oracle中建一个定时任务,每天执行即可,也可将其做成函数,使用select 查询及进行备份,

问题2:web页面无法获取日志问题,可将生成的日志文件作为oracle外部表,使用select 查询及进行日志读取。

附件下载地址:

参考链接:

数据库包api :DBMS_DATAPUMP   

 

转载于:https://www.cnblogs.com/wenxiao1-2-3-4/p/9889621.html

你可能感兴趣的文章
poj1061——扩展gcd水题
查看>>
UVa400.Unix ls
查看>>
POJ 2299 Ultra-QuickSort 归并排序、二叉排序树,求逆序数
查看>>
Educational Codeforces Round 60 (Rated for Div. 2) C. Magic Ship
查看>>
Windows 2008 R2系统开机时如何不让Windows进行磁盘检测?
查看>>
WP7应用开发笔记(18) 本地化与多语言
查看>>
解决 .so文件64与32不兼容问题
查看>>
归并排序法
查看>>
【剑指offer】面试题26:复杂链表的复制
查看>>
spark开发生成EXE
查看>>
Vue 全家桶介绍
查看>>
WPF Bitmap转Imagesource
查看>>
Java compiler level does not match the version of the installed Java project facet.解决方法
查看>>
笔记_小结
查看>>
Linux lsof命令 umount U盘
查看>>
自定义Font
查看>>
linux svn 服务端搭建
查看>>
maven用途、核心概念、用法、常用参数和命令、扩展
查看>>
linux时间同步ntp服务的安装与配置
查看>>
django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法...
查看>>