恢復操作時,常常因爲有其他客戶端或進程佔用某個數據庫連接,導致該數據庫恢復失敗。
解決辦法:在恢復前,強制中斷所有的其他數據庫連接,才能保證恢復數據正常。
1、SQL Server 數據庫
1)創建一個存儲過程 close_sqlserver_connect.sql,刪除其他連接功能
create PROCEDURE p_closedblink
@dbname varchar(20)
AS
begin
declare @spid varchar(20)
declare #spid cursor for
select spid=cast(spid as varchar(20)) from master..sysprocesses where dbid=db_id(@dbname)
open #spid
fetch next from #spid into @spid
while @@fetch_status=0
begin
exec('kill '+@spid)
fetch next from #spid into @spid
end
close #spid
deallocate #spid
end
2)在臨時數據庫tempdb中創建存儲過程,刪除數據庫nemgr的客戶端連接。
osql -S"127.0.0.1" -U%1 -P%2 -d"tempdb" -Q"DROP PROCEDURE p_closedblink" >>%global_log_file%
osql -"127.0.0.1" -U%1 -P%2 -d"tempdb" -i"%backup_path%\bin\close_sqlserver_connect.sql" >>%global_log_file%
osql -S"127.0.0.1" -U%1 -P%2 -d"tempdb" -Q"exec p_closedblink nemgr" >>%global_log_file%
osql -S"127.0.0.1" -U%1 -P%2 -d"tempdb" -Q"DROP PROCEDURE p_closedblink" >>%global_log_file%
2、Oracle 數據庫
1) 查詢會話ID SQL
String SQL_QUERY_SESSIONID =
"select SID, SERIAL# from v$session where username is not null and STATUS like 'INACTIVE'";
2) 執行刪除會話 SQL
String SQL_INSERT_KILLSESSION = "alter system kill session ";
3) Java 實現代碼
Connection conn = null;
try
{
conn = getOracleConnect();
final ResultSet rs = execQuery(conn, SQL_QUERY_SESSIONID);
final List<DataResult> lstData = new ArrayList<DataResult>();
while (rs.next())
{
final DataResult data = new DataResult();
data.setSid(rs.getInt("SID");
data.setSerial(rs.getInt("SERIAL#");
lstData.add(data);
}
for (final DataResult data : lstData)
{
final StringBuffer sb = new StringBuffer(SQL_INSERT_KILLSESSION);
sb.append('\'')
.append(Integer.toString(data.getSid()))
.append(',')
.append(Integer.toString(data.getSerial()))
.append('\'');
final int temp = execInsert(conn, sb.toString());
result &= (temp == 0) ? true : false;
}
}