1、为什么使用归档模式
1)归档模式只要有磁盘,不会丢失数据,哪怕处理再慢也没关系。
2)对性能的消耗最小。
package com.topnet.log.service;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import com.topnet.quick.frame.FastDao;
import com.topnet.quick.frame.OtherCondition;
import com.topnet.quick.frame.ds.DataSourceAnnotation;
@Service
@DataSourceAnnotation("logMiner")
public class LogMinerService {
@Autowired
FastDao fastDao;
@Value("${log.scnFile}")
String scnFile;
public void get() {
Long scn = getScn();
while (true) {
List<OtherCondition> otherConditions = new ArrayList<OtherCondition>();
if (scn != null) {
otherConditions.add(new OtherCondition("FIRST_CHANGE#", OtherCondition.GT, scn));
}
// 得到归档日志文件
String archivedLogSql =
"select sequence#, FIRST_CHANGE#, NEXT_CHANGE#,name from v$archived_log where name is not null";
List<Map<String, Object>> ls =
fastDao.findBySql(archivedLogSql, null, otherConditions, null, " sequence# ", 0, 3);
if (ls.size() == 0) {
break;
}
String build =
"begin\n dbms_logmnr_d.build(dictionary_filename => 'dictionary.ora', dictionary_location =>'/home/data/oracle'); \nend;";
fastDao.execute(build);
String app = "dbms_logmnr.new";
Long firstChange = null;
Long nextChange = null;
for (Map<String, Object> map : ls) {
// 记录第一给scn,和最后一个scn
if (firstChange == null) {
firstChange = Long.valueOf(map.get("firstChange#").toString());
}
nextChange = Long.valueOf(map.get("nextChange#").toString());
String addFIle = "begin\n dbms_logmnr.add_logfile('" + map.get("name").toString() + "',"
+ app + "); \nend;";
fastDao.execute(addFIle);
app = "dbms_logmnr.addfile";
}
String start =
"begin\n dbms_logmnr.start_logmnr(dictfilename=>'/home/data/oracle/dictionary.ora'); \nend; ";
fastDao.execute(start);
String sql = "SELECT scn, sql_redo, sql_undo FROM v$logmnr_contents WHERE SEG_OWNER='LPF' ";
String countSql = "SELECT count(*) FROM v$logmnr_contents WHERE SEG_OWNER='LPF' ";
Long n = fastDao.findCountByCustomSql(countSql, null, null, null);
if (n == 0) {// 如果当前没有数据,那么就
scn = nextChange;
String end = "begin\n DBMS_LOGMNR.END_LOGMNR ; \nend; ";
fastDao.execute(end);
writeScn(scn);
continue;
}
int startNum = 0;
int limit = 1000;
while (startNum < n) {
ls = fastDao.findBySql(sql, null, null, null, " scn ", startNum, limit);
for (Map<String, Object> map : ls) {
scn = Long.valueOf(map.get("scn").toString());
System.out.println(JSON.toJSON(map));
}
writeScn(scn);
startNum = startNum + limit;
}
String end = "begin\n DBMS_LOGMNR.END_LOGMNR ; \nend; ";
fastDao.execute(end);
}
}
/**
* 手动归档
*/
public void archive() {
String sql = "alter system archive log current";
fastDao.execute(sql);
}
/**
* 得到当前scn号
*
* @return
*/
public Long getScn() {
File f = new File(scnFile);
if (!f.exists()) {
return null;
}
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(f));
String str = br.readLine();
return Long.valueOf(str);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(br);
}
return null;
}
/**
* 记录当前的scn号
*
* @param scn
*/
public void writeScn(Long scn) {
File f = new File(scnFile);
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(f, false));
bw.write(scn.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(bw);
}
}
}
来源:oschina
链接:https://my.oschina.net/internetafei/blog/4528745