生产线的sqlserver数据库infoservice星期日做全盘备份,备份名为:infoservice_database.7,星期一做差异备份:infoservice_database.1,星期二:infoservice_database.2...
对应的本地模拟库infoserviceonline要定期恢复,恢复顺序与备份顺序相反. 如今天是星期一,要先还原
上个星期日的全盘备份,再还原今天的差异备份.
本程序支持在数据库服务器恢复,也支持在工作站恢复.
断开数据库的存储过程(创建于master库):
Create proc DisconnectDB(@dbname varchar(20),@reason nvarchar(200)=null,@delay varchar(8)='00:00:30')
declare @sql nvarchar(500),@cmd nvarchar(500)
declare @spid int
declare @hostname nvarchar(255),@pgname nvarchar(255)
declare @flag bit
set @reason=isnull(@reason,N'未知')
set @flag=0
set @sql='declare getspid cursor for select spid,hostname,program_name from master..sysprocesses where dbid=db_id('''+@dbname+''')'
exec (@sql)
open getspid
print 'ready'
fetch next from getspid into @spid,@hostname,@pgname
while @@fetch_status <>-1
begin
set @flag=1
set @cmd='net send '+ltrim(rtrim(@hostname))+' 请及时保存你的程序:'+ltrim(rtrim(@pgname))+'的相关数据,'+'数据库:'+@dbname+'将于'+@delay+'后断开连接.'+'原因:'+@reason
print @cmd
exec master.dbo.xp_cmdshell @cmd
fetch next from getspid into @spid,@hostname,@pgname
end
close getspid
deallocate getspid
if @flag=1
waitfor delay @delay
exec (@sql)
open getspid
fetch next from getspid into @spid,@hostname,@pgname
while @@fetch_status <>-1
begin
exec('kill '+@spid)
fetch next from getspid into @spid,@hostname,@pgname
end
close getspid
deallocate getspid
print 'disconnect db:'+@dbname+' completely!'
return 0
python脚本
import logging
import os,shutil,subprocess
import re
import datetime
from datetime import timedelta
from datetime import date
global_log='D:\\tmp\\RestoreInfoServiceDB.log'
global_smb_db_filepath='\\\\192.168.0.84\\f$\\ftproot\\infoservice.online\\'
global_localtmpdir='d:\\tmp\\'
global_notify_user=['192.168.0.129','192.168.0.124']
global_sqlserver_user='sa'
global_sqlserver_password='hpsystem'
global_sqlserver_source='192.168.0.86'
global_sqlserver_db='infoserviceonline'
global_disconnectdb_delay='00:00:30'
# filemode='r',只读,清除原有内容(默认方式) filemode='r+',读写,清除原有内容
# filemode='w',只写,创建一个新的文件覆盖旧的 filemode='w+',读写,创建一个新的文件覆盖旧的
# filemode='a',只写,追加 filemode='a+',读写,追加
# filemode='b',二进制模式
logging.basicConfig(level=logging.DEBUG,format='[%(asctime)s] [%(levelname)s] %(message)s',filename=global_log,filemode='a')
logging.getLogger(global_log)
def NotifyUser(level,message):
logging.debug("进入消息通知函数:NotifyUser")
if level==1:
messagekind='提示:'
if level==2:
messagekind='警告:'
if level==3:
messagekind='错误:'
for user in global_notify_user:
hint=messagekind+message
cmd=['net','send',user,hint]
rst=subprocess.call(cmd)
def search_file(filename, search_path):
logging.debug("进入文件搜索函数:search_file")
dbfilelist=os.listdir(search_path)
for dbfile in dbfilelist:
p=re.compile(filename)
m=p.match(dbfile)
if m:
if os.path.exists(search_path+m.group()):
return m.group()
else:
continue
return None
def CopyFileFromSmbToLocal(host,local,format):
logging.debug("进入文件拷贝函数:CopyFileFromSmbToLocal")
i=date.today().weekday()
tmpdate=date.today()-datetime.timedelta(days=i+1)
while tmpdate<=date.today():
filename=tmpdate.strftime(format)
filefullname=search_file(filename,host)
if filefullname:
localfile=local+filefullname
if os.path.exists(localfile):
tmpdate=tmpdate+datetime.timedelta(days=1)
continue
else:
hostfile=host+filefullname
shutil.copy(hostfile,localfile)
else:
logging.info('数据库压缩文件:'+filefullname+'不存在')
NotifyUser(2,'数据库压缩文件:'+filefullname+'不存在')
return None
tmpdate=tmpdate+datetime.timedelta(days=1)
logging.info('拷贝文件成功')
return 1
def pickfile(filename):
logging.debug("进入文件提取函数:pickfile")
destfile='*infoservice_database.*'
cmd=['winrar','e',filename,destfile,'-r','e',global_localtmpdir]
rst=subprocess.call(cmd)
if rst==0:
return 1
else:
return 0
def Decompress(local,format):
logging.debug("进入解压函数:Decompress")
i=date.today().weekday()
tmpdate=date.today()-datetime.timedelta(days=i+1)
i=tmpdate.weekday()
while tmpdate<=date.today():
localdbfile='infoservice_database.'+str(i+1)
filename=tmpdate.strftime(format)
filefullname=search_file(filename,local)
if os.path.exists(local+localdbfile):
tmpdate=tmpdate+datetime.timedelta(days=1)
i=tmpdate.weekday()
continue
else:
source=local+filefullname
pickfile(source)
tmpdate=tmpdate+datetime.timedelta(days=1)
i=tmpdate.weekday()
logging.info('解压文件成功')
return 1
def RemoveOldFile(local):
logging.debug("进入删除旧文件函数:RemoveOldFile")
i=date.today().weekday()
if i==6 or i==0:
logging.info('del '+local+'infoservice_database.*')
logging.info('del '+local+'*.bz2')
os.system('del '+local+'infoservice_database.*')
os.system('del '+local+'*.bz2')
return 1
def ExecSQL(command):
logging.debug("进入SQL语句执行函数:ExecSQL")
logging.info("执行的SQL语句:"+command)
cmd=['isql','/U',global_sqlserver_user,'/P',global_sqlserver_password,'/S',global_sqlserver_source,'/d','master','/Q',command]
rst=subprocess.call(cmd)
if rst==0:
return 1
else:
return 0
def DisConnectDB():
logging.debug("进入断开数据库连接函数:DisConnectDB")
command='Exec DisconnectDB "'+global_sqlserver_db+'","数据库还原","'+global_disconnectdb_delay+'"'
print command
rst=ExecSQL(command)
return rst
def doRestoreDB(IsInHost):
logging.debug("进入还原主函数:doRestoreDB")
RemoveOldFile(global_localtmpdir)
CopyFileFromSmbToLocal(global_smb_db_filepath,global_localtmpdir,'backup-%Y%m%d\d{6}\.tar\.bz2')
Decompress(global_localtmpdir,'backup-%Y%m%d\d{6}\.tar\.bz2')
if not IsInHost:
hostLocation='\\\\'+global_sqlserver_source+'\\'
hostLocation=hostLocation+global_localtmpdir.replace(':','$')
os.system('del '+hostLocation+'infoservice_database.*')
os.system('copy '+global_localtmpdir+'infoservice_database.* '+hostLocation)
result=DisConnectDB()
if result==0:
NotifyUser(3,'还原库失败,原因:断开连接失败')
return -3
i=date.today().weekday()
tmpdate=date.today()-datetime.timedelta(days=i+1)
j=tmpdate.weekday()
while tmpdate<=date.today():
localdbfile='infoservice_database.'+str(j+1)
filefullname=global_localtmpdir+localdbfile
if os.path.exists(filefullname):
if j+1==7:
cmd='restore database '+global_sqlserver_db+' from Disk="'+filefullname+'" with file=1, NORECOVERY'
if tmpdate==date.today():
cmd='restore database '+global_sqlserver_db+' from Disk="'+filefullname+'" with RECOVERY'
else:
cmd='restore database '+global_sqlserver_db+' from Disk="'+filefullname+'" with file=1,NORECOVERY'
if tmpdate==date.today():
cmd='restore database '+global_sqlserver_db+' from Disk="'+filefullname+'" with file=1,RECOVERY'
rst=ExecSQL(cmd)
if rst==0:
NotifyUser(3,'还原库失败,原因:执行'+cmd+'失败')
return -1
else:
NotifyUser(3,'还原库失败,原因:文件'+filefullname+'不存在')
return -2
tmpdate=tmpdate+datetime.timedelta(days=1)
j=tmpdate.weekday()
NotifyUser(1,'还原库'+global_sqlserver_db+'成功')
logging.info('还原库'+global_sqlserver_db+'成功')
return 1
if __name__ == "__main__":
doRestoreDB(3<2)
logging.shutdown()
分享到:
- 2007-01-15 12:55
- 浏览 1601
- 评论(0)
- 论坛回复 / 浏览 (0 / 2035)
- 查看更多
相关推荐
LNH_MySQL 27-更多MySQL数据库增量恢复大讨论及大总结.mp4
MySQL数据库增量备份是一种高效的数据保护策略,它只备份自上次备份以来发生更改的数据,从而显著减少备份所需的存储空间和时间。在本项目中,通过编写预处理程序并设置服务器定时任务,成功实现了MySQL的增量备份...
在Windows环境下,MySQL数据库的管理和维护是至关重要的任务,其中包括数据的安全备份与恢复。本教程将详细介绍如何利用`mysqldump`和`mysqlbinlog`工具进行全量备份、增量备份以及数据库的还原操作。 全量备份是...
### Oracle 增量恢复详解 #### 一、Oracle RMAN 增量备份概述 在Oracle数据库管理系统中,RMAN(Recovery Manager)是一种强大的工具,用于执行数据库的备份与恢复操作。其中,增量备份作为一种高效的方式,在实际...
MySQL数据库的备份与恢复是确保数据安全性的重要环节。在本测试报告中,主要涉及了全量备份和增量备份的恢复过程,并对恢复后的数据进行了验证。以下是对这些知识点的详细说明: 1. **全量备份**:全量备份是数据库...
SQL数据库备份恢复助手是一款专为数据库管理员设计的实用工具,旨在简化SQL数据库的备份与恢复过程,确保数据的安全性和可恢复性。在IT行业中,数据库是存储和管理信息的核心,而有效的备份和恢复策略是防止数据丢失...
本工具"Oracle数据库备份恢复工具"是基于MFC(Microsoft Foundation Classes)界面开发的,旨在提供一个简单易用的平台,帮助用户轻松完成Oracle数据库的备份与恢复任务。 首先,我们来了解Oracle数据库备份的基本...
综上所述,Oracle数据库的备份和恢复策略涉及多个层面,从全备份、增量备份、EXP导出到恢复步骤的规划,都需要精确操作和谨慎管理,以确保在数据丢失或系统故障时能快速有效地恢复服务。同时,定期检查和更新备份...
Oracle数据库增量备份是数据库管理中的一个重要环节,它能够有效地节省存储空间并提高备份效率,特别是在大型数据库环境中。本文将深入探讨Oracle数据库增量备份的概念、原理以及实现方法。 首先,了解什么是增量...
标题提到的“SVN数据库增量备份脚本”是为了定期或按需备份SVN服务器的数据,特别是针对数据库的变化部分。这种脚本通常基于shell、Python或其他编程语言编写,可以自动化执行备份任务,提高效率并减少人为错误。 ...
MySQL 数据库全量和增量备份 MySQL 数据库全量和增量备份是指对 MySQL 数据库进行的完整备份和增量备份,以确保数据的安全和可靠性。本篇文章将对 MySQL 全量和增量备份进行详细的介绍,包括 binlog 日志的说明、...
Oracle-RMAN增量备份恢复测试记录是指使用Oracle Recovery Manager(RMAN)工具对Oracle数据库进行增量备份和恢复的测试记录。本记录涵盖了增量备份的基本概念、备份策略及恢复、备份过程、第一次全备份、第一次...
MySQL数据库在日常运维中扮演着至关重要的角色,因此掌握如何进行完整备份、增量备份与还原是每个IT专业人员必备的技能。在这个主题中,我们将深入探讨如何使用Java来实现这些功能。 首先,让我们理解什么是数据库...
SQL数据库是信息系统中不可或缺的一部分,它负责存储、管理和检索数据,而SQL数据库备份与恢复则是保障数据安全的重要环节。"SQL数据库备份恢复助手v1.0b 绿色版" 提供了一种方便的方式来处理这一过程,使得用户无需...
RMAN,全称为Recovery Manager,是Oracle数据库提供的一个强大的工具,主要用于数据库的备份与恢复操作。本篇文章将深入探讨如何使用RMAN进行数据库的管理,包括如何创建恢复目录、连接数据库、执行各种RMAN命令以及...
Oracle数据库逻辑增量备份是数据库管理中的重要组成部分,它允许管理员以高效的方式备份和恢复数据,尤其是在数据频繁更新的环境中。本文将深入探讨Oracle数据库中使用exp/imp工具进行逻辑增量备份的方法及其恢复...
LNH_MySQL 23-企业场景数据库需要增量恢复的条件分析.mp4
差异备份和增量备份是两种常见的备份类型,它们都旨在减少全量备份所需的存储空间和时间,但在策略和恢复过程上有所不同。 首先,我们要明确全量备份、差异备份和增量备份的基本概念: 1. **全量备份**:全量备份...