首先說一下場景,我們在阿里雲有幾百臺服務器包括linux 和window,現在要遷移服務器到百度雲這邊。
1.因爲趕到馬上過年,所以年前要將所有的sql數據文件備份一遍(現在想想,在不清楚遷移規則的情況下,最好先備份一個庫然後將流程走通了,在一步一步的來,因爲如果全部備份完成,會造成數據庫日誌無法收縮,導致日誌增長數據很快,不得不購買磁盤擴大)
2.備份時要進行壓縮備份
1.選擇數據庫-右鍵-任務-備份-常規 選擇備份的地址,在備份選項裏選擇壓縮備份 ,然後點擊腳本 在新建窗口中進行 修改stats=1 按照1 遞增,然後運行,在消息中就會看到執行的情況
2.如果備份了,日誌增長太快,想恢復到以前的那種情況,現將數據庫改成簡單模式,然後收縮日誌,完成後在改成完整模式(如果備份後,日誌是不可以收縮的,因爲要做日誌追加操作,如果改動了日誌追加就會出問題)
3.備份完成後 需要將阿里雲的備份數據導入到百度雲的服務器上,這裏採用的是專線 具體的操作不是很熟悉,阿里雲這邊需要將服務器的vpcip 在百度雲這邊的專線路由裏建立路由,阿里這邊的雲企業要建立百度雲服務器的vpc 的路由,要規定到某個可用區,都要創建。然後從百度雲同一個vpc下 ping 阿里雲的某臺服務器的內網ip 如果能ping通就證明可以溝通
4.網絡溝通後 就可以進行內網數據遷移,我採用的是共享文件夾的方式進行copy, 將阿里雲的sql備份文件夾進行共享,然後在百度雲的網絡 \\ip就能看到共享文件,然後進行copy就可以
5.copy完成後要進行sql備份還原操作,數據庫-右鍵-還原數據庫,還原選項要選擇第二項,然後點擊腳本 新建窗口運行 然後運行 最候結果數據庫顯示正在還原中就可以了(用腳本,這個好處就是大數據庫,能看到進度)
4.進行sql日誌備份,並且自動copy到百度雲這邊
1. 創建日誌備份的存儲過程
2.name in ('數據庫') 備份一個,如果全部備份 ,not in('庫1','庫2')
3.需要備份哪個庫要在日誌備份的路徑下建立相應的數據庫名的文件夾
4.創建作業計劃,每隔10分鐘執行一遍(執行 (要加路徑),exec [BackupDBLog] 'D:\DBBackup\log\')
5.有好多都是需要文件夾權限,如果報錯,可以將文件夾權限修改一下
deng USE [master] GO /****** Object: StoredProcedure [dbo].[BackupDBLog] Script Date: 2020/2/9 11:19:43 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER proc [dbo].[BackupDBLog] (@PathStr varchar(256)) as --exec [BackupDBLog] 'E:\sqlback\log\' set nocount on --if not exists (select * from sys.dm_hadr_availability_replica_states where is_local=1 and role=1) --return begin declare @DateStr varchar(128) declare @SqlStr varchar(4000) declare @DBName varchar(128) select @DateStr=replace(replace(replace(replace(convert(varchar(128),getdate(),25),'-',''),' ',''),':',''),'.','') select @DateStr select @DateStr DateStr,name DBName,0 BackupStatus into #Temp from sys.databases where name in ('Aso_app_versions_log') while exists(select * from #Temp where BackupStatus=0) begin select top 1 @DBName=dbname,@DateStr= DateStr from #Temp where BackupStatus=0 set @SqlStr='backup log '+@DBName+' to disk='+''''+@PathStr+@DBName+'\'+@DBName+@DateStr+'.trn'+''''+' WITH COMPRESSION' print (@SqlStr) exec(@SqlStr) set @SqlStr='' update #Temp set BackupStatus=1 where DateStr=@DateStr and DBName=@DBName and BackupStatus=0 end drop table #Temp --declare @sql varchar(2000) --set @sql='forfiles /p D:\DBbackup\log\ /m *.trn /d -2 /s /c "cmd /c if @ISDIR==FALSE DEL /A A @FILE && Echo @path"' --exec master..xp_cmdshell @sql end
5.copy日誌備份到百度雲
1.xx 代表目標服務器的內網ip
2.如果報錯開啓一下xp_cmdshell(運行下面的語句就可以)
3.百度雲也要創建對應的文件夾
4.如果操作一直失敗,目標服務器的權限也有了,還是報權限問題 ,可以加上目標服務器的用戶名和密碼
5.創建計劃任務每10分鐘運行一次
declare @sql nvarchar(4000) set @sql='xcopy E:\DBBackup\DBName\log\*.trn* \\xx.xx.xx.xx\e$\log\DBName\ /y /D ' exec master.dbo.xp_cmdshell @sql
sp_configure 'show advanced options', 1; GO RECONFIGURE; GO exec sp_configure 'xp_cmdshell',1 go reconfigure with override go
declare @sql1 nvarchar(4000) declare @sql2 nvarchar(4000) set @sql1='net use \\xx.xx.xx.xx\D$ 密碼 /user:用戶名' set @sql2='xcopy E:\sqlback\log\Aso_app_versions_log\*.trn* \\xx.xx.xx.xx\d$\sqlback\log\Aso_app_versions_log\ /y/D' exec master.dbo.xp_cmdshell @sql1 exec master.dbo.xp_cmdshell @sql2
6.日誌收縮
1.創建2個sql
2.完成後執行 dbo.sp_block 'r' 查看進程
3.查看數據庫的情況(第三段SQL語句)
4.收縮日誌(第4段sql)
5. usedspace =第三段sql的已使用 ,totalspace=總共的
select @usedspace= 36043,@totalspace =38800
6.執行查看數據庫是否收縮,如果收縮那說明成功了
GO /****** Object: StoredProcedure [dbo].[sp_block] Script Date: 09/27/2013 14:17:48 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE [dbo].[sp_block] @status [varchar](50) = '', @is_output [tinyint] = 1 WITH encryption AS /********************** {VER EDITOR DATE COMMENT } REMARK: 1. 系統進程本身沒有connection,一個sesstion對應一個connection 2. insert data有嚴格的順序 3. 如果sys.dm_exec_requests的列值爲null,表明此requests已經不存在,session_status爲sleeping 4. if a spid is blocking and is blocked,it belong to blocked,but the blocking count has value. 5. if the sp get error info like "The statement terminated. The maximum recursion 100 has been exhausted before statement completion.",then it indicate a deadlock happened,like this: "Transaction (Process ID 67) was deadlocked on lock resources with anot her process and has been chosen as the deadlock victim. Rerun the transaction. 6. sleeping: last_request_end_time>=last_request_start_time 7. 有時查詢結果的數據出現不一致的情況,比如type=sleeping,而status=running,原因是此sp內部多次查詢的時間差 8. 不論@status輸入參數如何,blocking和blocked總是顯示,可以用此特性只顯示blocking和blocked 9. Will only display the blocking spid's query plan. 10. Will filter current spid,but if the current spid is blocking or blocked ,it will display. 11. 系統進程被阻塞,也會顯示 12. session_status 有時不匹配 request_status,原因:存在髒讀;或讀取時間不一致 13. 不考慮自己阻塞自己的情況 EXAMPLE: exec sp_block '%running%' exec sp_block '%block%' sp_block @status ='',@is_output =2 ************************/ set nocount on declare @rowcount int set @status=ltrim(rtrim(@status))+'%' declare @spid_blocked table ( spid int not null ,blocking_spid int null ,blocking_spid_sort varchar(1000) null ,wait_time int null ) declare @cte table(spid smallint ,blocking_spid smallint ,wait_time bigint ) insert @cte select distinct spid,blocked,waittime from master.dbo.sysprocesses where blocked <>0 and spid<>blocked insert into @spid_blocked select a.spid ,coalesce(d.blocking_spid,c.blocking_spid,b.blocking_spid,a.blocking_spid) as blocking_spid ,ltrim(str(a.spid))+'->'+ltrim(str(a.blocking_spid))+isnull('->'+ltrim(str(b.blocking_spid)),'')+isnull('->'+ltrim(str(c.blocking_spid)),'')+isnull('->'+ltrim(str(d.blocking_spid)),'') as blocking_spid_sort ,a.wait_time/1000 as wait_time from @cte a left join @cte b on a.blocking_spid=b.spid left join @cte c on b.blocking_spid=c.spid left join @cte d on c.blocking_spid=d.spid if @@rowcount>0 begin declare @spid_activity table ( type nvarchar(50) not null ,spid int not null ,blocking_spid int null ,blocking_spid_sort varchar(1000) null ,blocked_count int null ,wait_time int null ,blocked_time int null --seconds ) insert into @spid_activity(type,spid,blocking_spid,blocking_spid_sort,blocked_count,wait_time,blocked_time) select distinct '1_blocking',blocking_spid,0,'kill '+ltrim(str(blocking_spid)),count(blocking_spid),0,max(wait_time) from @spid_blocked group by blocking_spid union all select distinct '2_blocked',spid,blocking_spid,blocking_spid_sort,0,wait_time,wait_time from @spid_blocked select @rowcount=@@rowcount if @is_output<>2 begin ----select * from master.dbo.dba_block_debug if object_id('master.dbo.dba_block_debug') is null begin --(可刪除),收集數據 create table master.dbo.dba_block_debug( id int identity primary key, checktime datetime default(getdate()), type nvarchar(50) not null ,spid int not null ,blocking_spid int null ,blocking_spid_sort varchar(1000) null ,blocked_count int null ,wait_time int null ,blocked_time int null --seconds ) end if @rowcount>=5 and @is_output=1 begin insert into master.dbo.dba_block_debug(type,spid,blocking_spid,blocking_spid_sort,blocked_count,wait_time,blocked_time) select type,spid,blocking_spid,blocking_spid_sort,blocked_count,wait_time,blocked_time from @spid_activity delete from master.dbo.dba_block_debug where id<(select max(id) as id from master.dbo.dba_block_debug)-1000 end end end -------------- if object_id('tempdb.dbo.##block') is not null drop table ##block --10 show results ************* select case when st0.type is not null then st0.type when se1.status='running' then '3_Running' when se1.status='Sleeping' then '4_Sleeping' when se1.status='Dormant' then '5_Dormant' when se1.status='Preconnect' then '6_Preconnect' else 'Others' end as type ,se1.session_id as spid ,isnull(st0.blocking_spid_sort,'') as blocking_spid ,isnull(str(st0.blocked_count),'') as blocked_count ,isnull(dbo.udf_Duration_IntToChar(blocked_time),'') as blocked_time ,case when pr.dbid = 0 then '' else db_name(pr.dbid) end as DBname ,se1.login_name /*,db_name(re2.database_id) as DBname --20090817yf*/ ,se1.[host_name] as client_name ,co3.client_net_address as client_IP ,case when charindex('Job 0x',se1.[program_name])>0 then ( select 'SQLAgent Job: '+a.name+' Setp: '+ltrim(str(b.step_id))+' ('+b.step_name+')' from msdb.dbo.sysjobs a with (nolock) join msdb.dbo.sysjobsteps b with (nolock) on a.job_id=b.job_id where right(a.job_id,12) =substring(se1.[program_name],charindex('Job 0x',se1.[program_name])+26,12) and b.step_id=substring(se1.[program_name] ,charindex(' Step ',se1.[program_name])+6 ,charindex(')',se1.[program_name])-charindex(' Step ',se1.[program_name])-6 ) ) else se1.[program_name] end as client_program ,te2.text as running_or_last_text , ( SELECT TOP 1 SUBSTRING(te1.text,statement_start_offset/2, ( (CASE WHEN statement_end_offset= -1 THEN (LEN(CONVERT(nvarchar(max),te1.text))*2) ELSE statement_end_offset END)-statement_start_offset)/2)) AS running_sql --fix bug of "Difference of two datetime columns caused overflow at runtime." ,case when re2.wait_time is not null and se1.last_request_end_time>0 then 'wait '+dbo.udf_Duration_IntToChar(re2.wait_time/1000) when re2.wait_time is null and se1.last_request_end_time>0 then 'idle '+dbo.udf_Duration_IntToChar(datediff(ss,se1.last_request_end_time,getdate())) else 'idle from '+convert(char(20),se1.last_request_end_time,120) end as duration ,se1.status as session_status ,re2.status as request_status ,re2.command ,re2.wait_type ,re2.wait_resource ,re2.open_transaction_count as open_tran ,re2.row_count ,local_net_address as Server_IP,local_tcp_port as Port --,se1.[program_name] as client_program --,user_name(re2.[user_id]) as UserName ,se1.client_interface_name as client_interface ,se1.host_process_id as client_process ,case when st0.blocking_spid=0 then (select query_plan from sys.dm_exec_query_plan (re2.plan_handle) ) else '' end as query_plan ,se1.login_time ,se1.last_request_end_time /*,se1.last_request_start_time --20090817yf*/ ,se1.cpu_time ,se1.reads ,se1.logical_reads ,se1.Writes ,se1.is_user_process /*,se1.memory_usage,re2.cpu_time,re2.reads,re2.logical_reads ,re2.Writes,re2.nest_level --20090817yf*/ --,percent_complete --,re2.transaction_isolation_level --轉換成文字說明 --,re2.prev_error --,dbo.udf_Duration_IntToChar(re2.total_elapsed_time/1000)as total_elapsed_time --,re2.start_time --,re2.last_wait_type --,re2.open_resultset_count --,transaction_id ---,se1.lock_timeout --,re2.granted_query_memory --,re2.executing_managed_code ,blocked_time as blocked_time_ss into ##block from sys.dm_exec_sessions se1 with (nolock) left join master.dbo.sysprocesses pr with (nolock) on se1.session_id=pr.spid left join sys.dm_exec_requests re2 with (nolock) on se1.session_id=re2.session_id left join sys.dm_exec_connections co3 with (nolock) on se1.session_id=co3.session_id left join @spid_activity st0 on se1.session_id=st0.spid outer APPLY sys.dm_exec_sql_text(re2.sql_handle) AS te1 outer APPLY sys.dm_exec_sql_text(co3.most_recent_sql_handle) AS te2 where st0.type is not null or (se1.is_user_process=1 and se1.status like @status and se1.session_id<>@@SPID) order by type,st0.blocked_count desc,st0.blocked_time desc,request_status desc,se1.session_id ------ if @is_output=1 begin select * from ##block print 'select * from ##block order by login_name' print 'select login_name,count(*) as count0 from ##block group by login_name order by login_name ' end else if @is_output=2 begin declare @min_spid int select @min_spid=min(spid) from ##block where type in ('1_blocking','3_Running') select isnull(stuff(@@servername,charindex('\',@@servername),len(@@servername),''),@@servername) as ServerName ,case when a.type is null then b.type else a.type end as type ,a.spid,blocked_count,blocked_time,duration,session_status ,DBname,login_name,client_name,client_IP,client_program ,case when running_sql is null then running_or_last_text else running_sql end as running_or_last_text ,command,wait_type --,client_interface,client_process,blocking_spid,wait_resource from (select * from ##block where type in ('1_blocking','3_Running')) a full outer join (select case when @status like 'b%' then 'No_Blocking'--'當前無阻塞的進程!' when @status like 'r%' then 'No_Running'--'當前無阻塞或正運行的進程!' else 'No_Blocking_or_Running' end as type ,@min_spid as spid ) b on a.spid=b.spid end GO
USE [master] GO /****** Object: UserDefinedFunction [dbo].[udf_Duration_IntToChar] Script Date: 09/27/2013 14:19:16 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER OFF GO create FUNCTION [dbo].[udf_Duration_IntToChar] (@duration int) RETURNS varchar(50) with encryption AS /********************** REMARK: 1. The duration must be seconds EXAMPLE: declare @duration int set @duration=3672+3600*100 select dbo.udf_Duration_IntToChar(@duration) ************************/ BEGIN declare @duration_char varchar(50),@days varchar(30) set @days=case when @duration>=86400 then convert(varchar(20),convert(int,@duration/86400))+'D ' else '' end set @duration=@duration%86400 set @duration_char=@days+case when (@duration/3600)>9 then ltrim(str(@duration/3600)) else right('0'+ltrim(str(@duration/3600)),2) end +':' +right('0'+ltrim(str((@duration%3600)/60)),2)+':' +right('0'+ltrim(str((@duration%3600)%60)),2) RETURN @duration_char END GO
use db SELECT a.name as 邏輯文件名, size/128 [文件大小(兆)], FILEPROPERTY(a.name, 'SpaceUsed')/128 [已用空間(兆)], size/128 - FILEPROPERTY(a.name, 'SpaceUsed')/128 [未用空間(兆)], FILEPROPERTY(a.name, 'SpaceUsed')*100.0/size [使用率(%)], case when max_size=-1 then N'無限制' else convert(char(20),max_size/128) end [最大值(兆)] , case when growth>100 then convert(varchar(20),growth/128) else CONVERT(varchar(20),growth)+'%'end 增長值MB, case when is_percent_growth=0 then N'否'else N'是'end 是否百分比增長, physical_name 物理路徑,b.* FROM sys.database_files a cross join (select recovery_model_desc, log_reuse_wait,log_reuse_wait_desc,is_auto_shrink_on from sys.databases where name=DB_NAME())b
--DBCC SHRINKFILE(LogicalFile) --dbcc loginfo declare @usedspace int ,@totalspace int select @usedspace= 36043,@totalspace =38800 while @totalspace> @usedspace begin set @totalspace= @totalspace-5 *1024 DBCC SHRINKFILE( 收縮日誌名稱,@totalspace ) end