我见过太多的数据库管理员花大量的时间在数据库迁移上,即便在客户的实际环境亦是如此。由于微软频繁的发布新版,基于业务和客户的要求,应用服务不得不同时升级。当然,还有许多用户仍在使用SQL Server 2000 (n 2005)的版本,这些都是接下来的不久需要升级的潜在用户。这里我将提供最简单,也是最快的解决方案把系统停机的时间降到最低。

  有很多方式方法去升级之前的数据库,有人采用数据库备份恢复的方式,从一个数据库实例备份,然后恢复到另一个实例,这可是个耗时的过程,如果我们只有几个数据库需要升级的话还算好,可是假如我们需要升级的是50+甚至是100+个数据库呢?很好,这里将介绍的是最合理的解决方案去减轻这样的管理工作。

  为了最大限度的减少系统停机时间,我们开始升级前需准备好一切事前准备工作,还需要有升级后执行的和出错时回滚的脚本。尽量避免采用GUI去更改实例或数据库的配置,不再多述了,我们开始吧。 -- 我将会在每一个部分尽量的多写备注。

  现假定我们需要把SQL2005实例升级到2012/2014,同样从2000到2008/2008R2的步骤也是一样的。

  请仔细阅读和按步骤执行:

升级前准备清单

  1. 确保目标服务器有足够的硬盘空间用于存放所有的数据库文件。
  2. 确保所需要的端口全部打开。
  3. 确保SQL实例排列方式与源实例相同或者符合应用程序要求。
  4. 如果有一个数据库使用了全文索引 -- 请参考文章后面的引用。
  5. DTS包的升级并不包含在内。
  6. 以下帖出的在目标服务器运行的脚本中只考虑单一LDF文件的情况,如果你有多个LDF文件,要么移除它,要么把它包含在脚本里面。而多个NDF's在所有的脚本里是有考虑到的。
  7. 仔细阅读每一部分的注释(包括脚本中的参数)
  8. 按应用和要求正确的更新参数(目标服务器名,共享文件夹,兼容级别等)。

重要提醒:脚本1-8和步骤2须预先执行并保存好,如果脚本的输出的内容要符合目标应用的要求,那么脚本可能需要稍做一些更改。

步骤 1:

1.  获取源服务器的数据实例和数据库的配置信息,保存其结果到EXCEL文件中以做升级之用。

Sheet 1 -

  1. sp_helpdb

Sheet 2 -

  1. select * from master.sys.master_files

Sheet 3 -

  1. select * from master.sys.configurations -- To run on SQL 2005 and above.
  2. sp_configure -- To run on SQL 2000 (enable show advanced options and rerun).

Sheet 4 -

  1. SELECT * FROM master.sys.sysfulltextcatalogs

STEP 2:

  导出所有logins, jobs, linked servers, operators和系统数据库中的用户对象,SQL MAIL或者DATABASE MAIL等

对于导出登陆对象,请参考以下链接

从链接中得知,先在源实例中创建sp_help_revlogin存储过程,然后拷贝其结果。

注: 需删除系统帐户,只拷贝所需的帐户。

http://support.microsoft.com/kb/918992
http://support.microsoft.com/kb/246133

导出作业和其它的对象

确认哪些作业和哪些对象需要迁移到目标服务器。你可以打开SSMS,定位到所需要导出的对象,然后在对象资源管理器中选中对象,导出脚本到新窗口或文件,然后保存,其它对象类似,然后这些导出的脚本需要在目标服务器的SSMS中运行。

STEP 3:

提供的 t-sql 脚本 [# 1 to # 8] 必须在源服务器中执行从而产生目标服务器执行的脚本,这一动作可以在几天/星期前完成。在具体执行期间,这个产生的脚本将会在目标服务器上执行。

  1. /*============================================================
  2. Script 1 - 产生分离数据库脚本
  3.  
  4. 重要注释:
  5.  
  6. 在源服务器上执行以下语句以在结果窗口产生分离数据库脚本。保存这个结果。万一目标服务器需要回滚,此脚本同样适用。
  7.  
  8. 增加了参数 @keepfulltextindexfile='true' 以防某一用户数据库采用了全文检索索引目录,下一版本中,将会取消此参数
  9.  
  10. 分离命令将会在以下情况中不能正常执行
  11.  
  12. 如果你的数据库用于同步,其必须停止发布。
  13. 必须删掉的有的快照才能分离数据库。
  14. 数据库处于镜像会话,必须停止。
  15. 质疑的数据库不能被分离,除非你更改紧急模式。

  16. Author : Dathuraj Pasarge
  17. Last Edited : 2nd June 2014
  18. ===============================================================*/
  19. declare @dbname varchar(150)
  20. declare @cmd varchar(250)
  21.  
  22. IF CURSOR_STATUS('global','dbcursor')>=-1
  23. BEGIN
  24. CLOSE dbcursor
  25. DEALLOCATE dbcursor
  26.  
  27. END
  28.  
  29. declare dbcursor cursor for
  30. select name from master..sysdatabases where dbid>4 and name not in('ReportServer','ReportServerTempDB','pubs','Northwind','AdventureWorks') -- Include any additional databases in NOT IN clause to exclude the databases from detach.
  31.  
  32. Open dbcursor
  33. Fetch next from dbcursor into @dbname
  34.  
  35. WHILE @@FETCH_STATUS = 0
  36. BEGIN
  37.  
  38. Begin
  39. set @cmd='sp_detach_db '+''''+@dbname+'' +''',''true'''
  40.  
  41. print @cmd
  42. print 'go'
  43. End
  44.  
  45. Fetch next from dbcursor into @dbname
  46. END
  47.  
  48. close dbcursor
  49. deallocate dbcursor

output:

  1. /*===============================================================
  2. Script 2 : 生成脚本 - 生成重新附加数据库的脚本。以防需要回滚。
  3.  
  4. 注意事项
  5. ----------------------
  6. 在源服务器上运行,然后保存输出的结果用于重新附加数据库。此举以防在升级过程中,出现一些不可预见性的错误。
  7.  
  8. Note: Scripts for Rolling back the change.
  9.  
  10. Author : Dathuraj Pasarge.
  11. Last Edited : 2nd June 2014
  12. ================================================================*/
  13. declare @dbname nvarchar(450)
  14. declare @cmd nvarchar(1200)
  15. declare @mdf nvarchar(800)
  16. declare @ldf nvarchar(800)
  17.  
  18. DECLARE @serverVersion varchar(50)
  19. select @serverVersion = CONVERT(varchar(50),SERVERPROPERTY('ProductVersion'))
  20. SET @serverVersion = LEFT(@serverVersion, CHARINDEX('.', @serverVersion) - 1)
  21.  
  22. IF CURSOR_STATUS('global','dbcursor')>=-1
  23. BEGIN
  24. CLOSE dbcursor
  25. DEALLOCATE dbcursor
  26.  
  27. END
  28.  
  29. If convert(int,@serverVersion)<9
  30.  
  31. BEGIN
  32. declare dbcursor cursor for
  33.  
  34. select name from master..sysdatabases where dbid>4 and name not in('ReportServer','ReportServerTempDB','pubs','Northwind','AdventureWorks')
  35. -- Include the db's in NOT IN clause, which are suspect or inaccessible.
  36.  
  37. Open dbcursor
  38.  
  39. Fetch next from dbcursor into @dbname
  40.  
  41. WHILE @@FETCH_STATUS = 0
  42. BEGIN
  43. Begin
  44. set @mdf = RTRIM((select [filename] from master..sysaltfiles where DB_NAME(dbid)=@dbname and fileid=1))
  45. set @ldf= RTRIM((select [filename] from master..sysaltfiles where DB_NAME(dbid)=@dbname and fileid=2))
  46.  
  47. set @cmd='sp_attach_db '+''''+@dbname+''','+ ''''+@mdf+''','''+@ldf+''''
  48.  
  49. print @cmd
  50. print 'go'
  51. End
  52.  
  53. Fetch next from dbcursor into @dbname
  54. END
  55.  
  56. close dbcursor
  57. deallocate dbcursor
  58. END
  59. ELSE
  60. If convert(int,@serverVersion)>=9
  61. BEGIN
  62. declare dbcursor cursor for
  63.  
  64. select name from master..sysdatabases where dbid>4 and name not in('ReportServer','ReportServerTempDB','pubs','Northwind','AdventureWorks')
  65. -- Include the db's in NOT IN clause, which are suspect or inaccessible.
  66.  
  67. Open dbcursor
  68.  
  69. Fetch next from dbcursor into @dbname
  70.  
  71. WHILE @@FETCH_STATUS = 0
  72. BEGIN
  73. Begin
  74.  
  75. set @mdf = (select physical_name from master.sys.master_files where DB_NAME(database_id)=@dbname and file_id=1
  76. and type_desc='ROWS'
  77. )
  78. set @ldf = (select physical_name from master.sys.master_files where DB_NAME(database_id)=@dbname and file_id=2
  79. and type_desc='LOG')
  80.  
  81. set @cmd='sp_attach_db '+''''+@dbname+''','+ ''''+@mdf+''','''+@ldf+''''
  82.  
  83. print @cmd
  84. print 'go'
  85. End
  86.  
  87. Fetch next from dbcursor into @dbname
  88. END
  89. close dbcursor
  90. deallocate dbcursor
  91. END

output:

  1. /*==========================================================
  2. Script 3 : 产生拷贝命令
  3.  
  4. 注意事项 :
  5. 源服务器上运行
  6. 以下脚本产生拷贝命令,把数据文件和日志文件复制到目标服务器上
  7. 设置@DestinationServerName变量为目标服务器名,同样需设置目标服务器的共享文件夹,其权限必须符可读可写
  8.  
  9. Author : Dathuraj Pasarge
  10. Last Edited : 10th Dec 2014
  11. ==============================================================*/
  12.  
  13. declare @dbname nvarchar(150)
  14. declare @cmd NVARCHAR(2000)
  15. declare @MDFSourceFile nvarchar(500)
  16. declare @LDFSourceFile varchar(500)
  17. declare @NDFSourceFile nvarchar(500)
  18. declare @MDFdestinationPath nvarchar(800)
  19. declare @LDFdestinationPath nvarchar(800)
  20. declare @DestinationServerName nvarchar(200)
  21. declare @DestinationShareFolderMDF nvarchar(200)
  22. declare @DestinationShareFolderLDF nvarchar(200)
  23. declare @count1 int, @count2 int, @fileid int
  24.  
  25. set @DestinationServerName='SQL02' -- Update destination serverName
  26. set @DestinationShareFolderMDF='Share1' -- Update ShareFolder created on destination server, for copying all mdf files
  27. set @DestinationShareFolderLDF='Share2' -- Update ShareFolder created on destination server, for copying all ldf files
  28.  
  29. set @MDFdestinationPath='\\'+@DestinationServerName+'\'+@DestinationShareFolderMDF+'\MSSQL\DATA' -- update folder names as per your requirement
  30.  
  31. set @LDFdestinationPath='\\'+@DestinationServerName+'\'+@DestinationShareFolderLDF+'\MSSQL\Logs' -- update folder names as per your requirement
  32.  
  33. IF CURSOR_STATUS('global','dbcursor')>=-1
  34. BEGIN
  35. CLOSE dbcursor
  36. DEALLOCATE dbcursor
  37. END
  38.  
  39. DECLARE @serverVersion varchar(50)
  40. select @serverVersion = CONVERT(varchar(50),SERVERPROPERTY('ProductVersion'))
  41. SET @serverVersion = LEFT(@serverVersion, CHARINDEX('.', @serverVersion) - 1)
  42.  
  43. If convert(int,@serverVersion)>=9
  44. BEGIN
  45. declare dbcursor cursor for
  46. select name from master..sysdatabases where dbid>4 and name not in('ReportServer','ReportServerTempDB','pubs','Northwind','AdventureWorks')
  47. -- Include the db's in NOT IN clause, which are suspect or inaccessible.
  48.  
  49. Open dbcursor
  50. Fetch next from dbcursor into @dbname
  51. WHILE @@FETCH_STATUS = 0
  52. BEGIN
  53.  
  54. set @MDFSourceFile = (select physical_name from master.sys.master_files where DB_NAME(database_id)=@dbname and file_id=1) -- For MDF Files
  55. set @cmd='XCOPY '+'"'+@MDFSourceFile+ '" "' +@MDFdestinationPath+ '"'
  56. PRINT @cmd
  57.  
  58. set @LDFSourceFile = (select physical_name from master.sys.master_files where DB_NAME(database_id)=@dbname and file_id=2) -- For LDF Files
  59. set @cmd='XCOPY '+'"'+@LDFSourceFile+ '" "' +@LDFdestinationPath+ '"'
  60. PRINT @cmd
  61.  
  62. set @count1 = (select count(physical_name) from master.sys.master_files where DB_NAME(database_id)=@dbname and file_id>2)
  63. set @count2=1
  64. set @fileid=3
  65. WHILE (@count2<=@count1)
  66. BEGIN
  67. set @NDFSourceFile = (select physical_name from master.sys.master_files where DB_NAME(database_id)=@dbname and file_id=''+@fileid+'' )
  68. set @cmd='XCOPY '+'"'+@NDFSourceFile+ '" "' +@MDFdestinationPath+ '"'
  69. set @count2=@count2+1
  70. set @fileid=@fileid+1
  71. PRINT @cmd
  72. END
  73. Fetch next from dbcursor into @dbname
  74. PRINT ''
  75. END
  76.  
  77. END
  78.  
  79. If convert(int,@serverVersion)<9
  80. BEGIN
  81. declare dbcursor cursor for
  82. select name from master..sysdatabases where dbid>4 and name not in('ReportServer','ReportServerTempDB','pubs','Northwind','AdventureWorks')
  83. -- Include the db's in NOT IN clause, which are suspect or inaccessible.
  84.  
  85. Open dbcursor
  86. Fetch next from dbcursor into @dbname
  87. WHILE @@FETCH_STATUS = 0
  88. BEGIN
  89.  
  90. set @MDFSourceFile = RTRIM((SELECT [filename] FROM master..sysaltfiles where DB_NAME(dbid)=@dbname and fileid=1)) -- For MDF Files
  91. set @cmd='XCOPY '+'"'+@MDFSourceFile+ '" "' +@MDFdestinationPath+ '"'
  92. PRINT @cmd
  93.  
  94. set @LDFSourceFile = RTRIM((SELECT [filename] FROM master..sysaltfiles where DB_NAME(dbid)=@dbname and fileid=2)) -- For LDF Files
  95. set @cmd='XCOPY '+'"'+@LDFSourceFile+ '" "' +@LDFdestinationPath+ '"'
  96. PRINT @cmd
  97.  
  98. set @count1 = (SELECT count([filename]) FROM master..sysaltfiles where DB_NAME(dbid)=@dbname and fileid>2)
  99. set @count2=1
  100. set @fileid=3
  101. WHILE (@count2<=@count1)
  102. BEGIN
  103. set @NDFSourceFile = RTRIM((SELECT [filename] FROM master..sysaltfiles where DB_NAME(dbid)=@dbname and fileid=''+@fileid+'' ))
  104. set @cmd='XCOPY '+'"'+@NDFSourceFile+ '" "' +@MDFdestinationPath+ '"'
  105. set @count2=@count2+1
  106. set @fileid=@fileid+1
  107. PRINT @cmd
  108. END
  109. Fetch next from dbcursor into @dbname
  110. PRINT ''
  111. END
  112.  
  113. END
  114.  
  115. close dbcursor
  116. deallocate dbcursor

Output

  1. /*==============================================================
  2. Script 4 : 产生脚本 - 用于目标服务器附加数据库的
  3.  
  4. 注意事项:
  5. 源服务器运行以下脚本, 产生附加数据库脚本用于目标服务器。
  6. 取得所有的次数据库文件(.ndf).
  7. 如果存在次日志文件,其路径需手动包含到输出结果中。
  8. 在目标服务器运行前,请保文件有效
  9.  
  10. Author - Dathuraj Pasarge.
  11. Last Modified Date: 28th Nov 2014.
  12. ===========================================================*/
  13. declare @dbname nvarchar(500)
  14. declare @FileName nvarchar(500)
  15. declare @cmd nvarchar(2000)
  16. declare @MdfPath nvarchar(500)
  17. declare @LdfPath nvarchar(500)
  18. declare @count int, @count2 int
  19. declare @fileid int
  20.  
  21. /* IMP NOTE - Set the below paths as per your environment for mdf and ldf location on the destination server*/
  22. set @MdfPath='D:\MSSQL\DATA\'
  23. set @LdfPath='E:\MSSQL\Logs\'
  24.  
  25. IF CURSOR_STATUS('global','dbcursor')>=-1
  26. BEGIN
  27. CLOSE dbcursor
  28. DEALLOCATE dbcursor
  29. END
  30.  
  31. declare dbcursor cursor for
  32. select db_name(dbid),RTRIM([filename]) from master..sysaltfiles where dbid>4
  33. and db_name(dbid) not in ('ReportServer','ReportServerTempDB','pubs','Northwind','AdventureWorks')
  34. and dbid<>32767 and fileid=1 -- Include the db's in NOT IN clause, which are suspect or inaccessible or not in scope.
  35.  
  36. Open dbcursor
  37.  
  38. Fetch next from dbcursor into @dbname,@FileName
  39.  
  40. WHILE @@FETCH_STATUS = 0
  41. BEGIN
  42.  
  43. Begin
  44.  
  45. set @FileName= REVERSE(left(@FileName, CHARINDEX('.mdf', @FileName) + 4))
  46. set @FileName= reverse(left(@FileName, CHARINDEX('\', @FileName) -1 ))
  47. SET @cmd='exec sp_attach_db '+''''+@dbname+''''+', '+''''+@MdfPath+''+@FileName+''','
  48.  
  49. SET @FileName=RTRIM((SELECT filename from master..sysaltfiles where fileid=2 and db_name(dbid)=@dbname))
  50. set @FileName= REVERSE(left(@FileName, CHARINDEX('.ldf', @FileName) + 4))
  51. set @FileName= reverse(left(@FileName, CHARINDEX('\', @FileName) -1 ))
  52. SET @cmd=@cmd + ''''+@LdfPath+''+@FileName+''''
  53.  
  54. set @count=(SELECT COUNT(*) from master..sysaltfiles where fileid>2 and db_name(dbid)=@dbname)
  55.  
  56. set @count2 =1
  57. set @fileid=3
  58. while(@count2<=@count)
  59. begin
  60. SET @FileName=RTRIM((SELECT filename from master..sysaltfiles where fileid=''+@fileid+'' and db_name(dbid)=@dbname))
  61. set @FileName= REVERSE(left(@FileName, CHARINDEX('.ndf', @FileName) + 4))
  62. set @FileName= reverse(left(@FileName, CHARINDEX('\', @FileName) -1 ))
  63. SET @cmd=@cmd + ','''+@MdfPath+''+@FileName+''''
  64. set @fileid=@fileid+1;
  65. set @count2=@count2+1;
  66. end
  67. print @cmd
  68. print 'go'
  69.  
  70. End
  71. Fetch next from dbcursor into @dbname,@FileName
  72. PRINT ''
  73. END
  74.  
  75. close dbcursor
  76. deallocate dbcursor

output

  1. /*=================================================================
  2. Script 5 : 更改数据库兼容等级
  3.  
  4. 在源服务器上运行, 同时保存执行的结果。
  5. 查询输出在目标服务器上执行
  6.  
  7. 设置@cmptlevel变量,不同的数据代表不同的版本
  8. 90 for SQL 2005, 100 for SQL 2008 and 2008 R2, 110 for SQL 2012 and 120 for SQL 2014.
  9.  
  10. Author : Dathuraj Pasarge
  11. Last Edited : 14th July 2014
  12. ==================================================================*/
  13.  
  14. declare @dbname varchar(250)
  15. declare @cmptlevel varchar(10)
  16. declare @Counter int
  17. declare @cmd varchar(250)
  18.  
  19. -- Set Counter to Zero
  20. Select @Counter = 0
  21.  
  22. SET @cmptlevel = 110 -- Change compatibility 90 for SQL 2005, 100 for SQL 2008 and 2008 R2, 110 for SQL 2012 and 120 for SQL 2014.
  23.  
  24. IF CURSOR_STATUS('global','dbcursor')>=-1
  25. BEGIN
  26. CLOSE dbcursor
  27. DEALLOCATE dbcursor
  28. END
  29.  
  30. declare dbcursor cursor for
  31. select sd.name from master..sysdatabases sd
  32. where sd.dbid>4 and sd.name not in('ReportServer','ReportServerTempDB',
  33. 'pubs','Northwind','AdventureWorks') -- Include databases with readonly,offline ones in this NOT IN clause, or make them online.
  34.  
  35. Open dbcursor
  36.  
  37. Fetch next from dbcursor into @dbname
  38.  
  39. WHILE @@FETCH_STATUS = 0
  40. BEGIN
  41.  
  42. Begin
  43.  
  44. set @cmd='alter database '+ @dbname+ ' set compatibility_level = '+ @cmptlevel
  45. Select @Counter = @Counter + 1
  46.  
  47. print @cmd
  48. End
  49.  
  50. Fetch next from dbcursor into @dbname
  51. END
  52.  
  53. close dbcursor
  54. deallocate dbcursor

output

  1. /*=============================================================
  2. Script 6 : 更新数据库usage。
  3.  
  4. 注意事项 –
  5. 源服务器上运行,保存查询输出
  6. 查询输出在目标服务器上执行
  7. 只有从SQL2000的数据库上升级才需要执行
  8.  
  9. Author : Dathuraj Pasarge
  10. Last Edited : 14th July 2014
  11. ===============================================================*/
  12.  
  13. DECLARE @SQL VARCHAR(1000)
  14. DECLARE @DB sysname
  15.  
  16. IF CURSOR_STATUS('global','dbcursor')>=-1
  17. BEGIN
  18. CLOSE dbcursor
  19. DEALLOCATE dbcursor
  20. END
  21.  
  22. DECLARE curDB CURSOR FORWARD_ONLY STATIC FOR
  23.  
  24. SELECT [name] FROM master..sysdatabases WHERE dbid>4 and [name] not in('ReportServer','ReportServerTempDB','pubs','Northwind','AdventureWorks') ORDER BY [name] -- Include the db's in NOT IN clause, which are suspect or inaccessible.
  25.  
  26. OPEN curDB
  27. FETCH NEXT FROM curDB INTO @DB
  28. WHILE @@FETCH_STATUS = 0
  29. BEGIN
  30.  
  31. SELECT @SQL = 'USE [' + @DB +']' + CHAR(13) + 'DBCC updateusage(0)' + CHAR(13)
  32.  
  33. PRINT @SQL
  34.  
  35. FETCH NEXT FROM curDB INTO @DB
  36.  
  37. END
  38.  
  39. CLOSE curDB
  40. DEALLOCATE curDB

output

  1. /*=============================================================
  2. Script 7 : 产生脚本 - 更新所有数据库的统计信息
  3.  
  4. 注意事项:
  5. 源服务器上执行,然后保存结果用于目标服务器上执行
  6.  
  7. Author : Dathuraj Pasarge
  8. Last Edited : 14th July 2014
  9. ===============================================================*/
  10.  
  11. DECLARE @SQL VARCHAR(1000)
  12. DECLARE @DB sysname
  13.  
  14. IF CURSOR_STATUS('global','dbcursor')>=-1
  15. BEGIN
  16. CLOSE dbcursor
  17. DEALLOCATE dbcursor
  18. END
  19.  
  20. DECLARE curDB CURSOR FORWARD_ONLY STATIC FOR
  21. SELECT [name] FROM master..sysdatabases WHERE dbid>4 and [name] NOT IN ('ReportServer','ReportServerTempDB','pubs','Northwind','AdventureWorks')
  22. ORDER BY [name] -- Include the db's in NOT IN clause, which are suspect or inaccessible.
  23.  
  24. OPEN curDB
  25. FETCH NEXT FROM curDB INTO @DB
  26. WHILE @@FETCH_STATUS = 0
  27. BEGIN
  28. SELECT @SQL = 'USE [' + @DB +']' + CHAR(13) + 'EXEC sp_updatestats' + CHAR(13)
  29. PRINT @SQL
  30. FETCH NEXT FROM curDB INTO @DB
  31.  
  32. END
  33.  
  34. CLOSE curDB
  35. DEALLOCATE curDB

output

 

  1. /*============================================================
  2. Script 8 : 产生脚本 - 更改数据库所属
  3.  
  4. Author : Dathuraj Pasarge
  5. ===============================================================*/
  6.  
  7. declare @dbname varchar(250)
  8. declare @login varchar(250)
  9. declare @cmd varchar(250)
  10.  
  11. IF CURSOR_STATUS('global','dbcursor')>=-1
  12. BEGIN
  13. CLOSE dbcursor
  14. DEALLOCATE dbcursor
  15. END
  16.  
  17. declare dbcursor cursor for
  18. select sd.name, suser_sname(sd.sid) from master..sysdatabases sd
  19. where sd.dbid>4 and sd.name NOT IN ('ReportServer','ReportServerTempDB','pubs','Northwind','AdventureWorks') -- Include the db's in NOT IN clause, which are suspect or inaccessible.
  20.  
  21. Open dbcursor
  22.  
  23. Fetch next from dbcursor into @dbname,@login
  24.  
  25. WHILE @@FETCH_STATUS = 0
  26. BEGIN
  27. Begin
  28.  
  29. print 'use ' + @dbname
  30. set @cmd='exec sp_changedbowner '+''''+@login+''''
  31. print @cmd
  32. End
  33.  
  34. Fetch next from dbcursor into @dbname,@login
  35. END
  36.  
  37. close dbcursor
  38. deallocate dbcursor

output

在正式升级的时候请按以下脚本和步骤执行。

  1. 备份所有系统和用户数据库
  2. 停止有关应用程序的服务。
  3. 删除所有源实例连接进程。
  1. /*=========================================================================
  2. Script 9 :
  3. 杀掉所有源服务器连接进程
  4.  
  5. 分离数据库前,请运行以下脚本杀掉现有连接进程
  6.  
  7. Author : Dathuraj Pasarge.
  8. Last Modified Date: 10th Nov 2014.
  9. =========================================================================*/
  10. DECLARE @kill varchar(4000)
  11. set @kill= '';
  12. SELECT @kill = @kill + 'kill ' + CONVERT(varchar(5), spid) + ';'
  13. FROM master..sysprocesses
  14. WHERE spid >50 and spid<>(select @@SPID)
  15. EXEC(@kill);
  16. go
  17. use master
  18. go
  19. sp_who2;
  20. go

  4. 分享所有源服务器的数据库

  执行 Script # 1 的查询结果

  5. 生成XCOPY命令复制源服务器的所有主数据文件,日志文件到目标服务器上,生成的命令在以管理员身份运行的命令提示符下运行。

  执行 Script # 3 的查询结果

  注意: 对比数据库文件的个数,如果存在多于一个ldf文件的数据库,记得手动添加相应的命令。

  6. 在目标服务器附加所有数据库

  执行 Script # 4 的查询结果

  7. 附加完毕后,需确保所有数据库在线且可以访问

  8.在附加过程中如果出错,请确保数据库所有文件均复制到目标数据库且确保与你脚本的路径一致

  9.执行创建登陆,作业,连接服务器,操作员脚本以创建相应的对象

  10. 修复孤立用户。

  1. /*===========================================================
  2. Script 10 - Fix Orphaned users.
  3. Notes:
  4. 1. 以下脚本修复所有数据库的孤立用户
  5. 2. 当你创建了所有登陆用户后,运行以下脚本去除孤立用户.
  6.  
  7. Author: Dathuraj Pasarge
  8. ==========================================================*/
  9.  
  10. SET NOCOUNT ON
  11. If exists (select * from sysobjects where name like '#databases%')
  12. DROP TABLE #databases
  13. if exists (select * from sysobjects where name like '#orphanusers%')
  14. DROP TABLE #orphanusers
  15. BEGIN
  16.  
  17. declare @username sysname,
  18. @DBName varchar(250),
  19. @NoOfUsers smallint,
  20. @Query1 varchar(2000),
  21. @Query2 varchar(2000)
  22.  
  23. CREATE TABLE #orphanusers
  24. (
  25. rowid smallint IDENTITY(1,1),
  26. UserName sysname,
  27. UserSID varbinary(100)
  28. )
  29.  
  30. CREATE TABLE #databases
  31. (
  32. dbname varchar(250)
  33. )
  34.  
  35. INSERT INTO #databases SELECT name from master.sys.databases where database_id > 4 and state_desc = 'ONLINE'
  36.  
  37. WHILE EXISTS(SELECT 1 FROM #databases)
  38.  
  39. BEGIN
  40.  
  41. SET @Query1 = ''
  42.  
  43. SELECT TOP 1 @DBName = dbname FROM #databases ORDER BY dbname
  44.  
  45. SET @Query1 = 'EXEC ' + @DBName + '.dbo.sp_change_users_login ''report'''
  46.  
  47. INSERT INTO #orphanusers EXEC(@Query1)
  48.  
  49. WHILE EXISTS(SELECT 1 FROM #orphanusers)
  50. BEGIN
  51. SELECT TOP 1 @username = UserName
  52. FROM #orphanusers ORDER BY rowid
  53.  
  54. BEGIN TRY
  55. SET @Query2 = 'EXEC ' + @DBName + '.dbo.sp_change_users_login ''Update_One'',' + @username+ ',' + @username
  56. EXEC(@Query2)
  57. Print 'Orphaned user ' + @username + ' fixed in ' +@DBName +' database'
  58. END TRY
  59.  
  60. BEGIN CATCH
  61.  
  62. PRINT 'Login '+ @username + ' has not found. If needed , create it and fix the orphaned issue. '
  63.  
  64. END CATCH
  65. DELETE FROM #orphanusers WHERE UserName = @username
  66. END
  67. DELETE FROM #databases WHERE dbname = @DBName
  68. END
  69.  
  70. DROP TABLE #orphanusers
  71. DROP TABLE #databases
  72.  
  73. END

  11. 更改数据库兼容级别

  执行 Script # 5 查询输出

  12. 更改所有用户数据库所属对象.

  执行 Script # 6 查询输出

  13. 更新数据库usage

  执行 Script # 7 查询输出

  14. 更新数据库统计信息

  执行 Script # 8 查询输出

迁移后须检查事项

如果你发现应用程序响应慢了,同时又有足够的停机时间,试着重建所有索引和维护计划或者那些你认为可行的办法.

1. 检查SQL Server错误日志

2. 如果你在附加数据库的时候出现以下错误,以管理员身份打开SSMS

操作系统错误5: "5(failed to retrieve text for this error. Reason: 15105)".

3. 如果不能解析主机名,试着刷新一下IP地址和DNS缓存

4. 如果有用到ODBC,确保ODBC连接可用。

5. 确保所有连接服务器可用.

其他参考:

Fulltext Seach catalog movement:

SQL Server 2000: http://support.microsoft.com/kb/240867

SQL Server 2005:

https://msdn.microsoft.com/en-us/library/ms345483%28v=sql.90%29.aspx

DTS Packages migration:

https://msdn.microsoft.com/en-us/library/ms143496%28v=sql.105%29.aspx

希望这结能帮助到您。

[译]SQL数据库迁移:从低版到高版本的更多相关文章

  1. centos 默认php 版本太低移到高版本的办法

    // centos 默认有php 版本太低转移到高版本的解决办法 php -v 版本低 ln -s /usr/local/php/bin/php /usr/bin/php

  2. sql server2008企业版和标准版

    SQL Server 的企业版和标准版的License价格差5倍之多,在企业应用中,DBA 经常会被这个问题问住,本帖将日常工作实践中遇到到版本问题给出第一手资料,陆续补充…… SQL 2008 镜像 ...

  3. 如何把SQLServer数据库从高版本降级到低版本?

    http://blog.csdn.net/dba_huangzj/article/details/7952403 由于目前还广泛使用着SQLServer2000,很多公司又想使用新的SQLServer ...

  4. 如何把SQLServer数据库从高版本降级到低版本

    如何把SQLServer数据库从高版本降级到低版本 编写人:CC阿爸 2015-4-7 近期在给一个客户推行ECM系统时,基本客户的硬件环境,我们为其安装的为SQL2008 64位的数据库系统.在安装 ...

  5. (4.16)sql server迁移DB文件(同一DB内)

    SQL Server 修改数据库物理文件存在位置 关键词:迁移文件,迁移temp库(这怎么迁移呢,用方法2即可,需要重启实例) 三种均需要离线: 一共分为(1)脱机迁移和(2)在线迁移. (1)迁移方 ...

  6. SQL与NoSQL区别--商业SQL数据库衰落--oracle面临困境

    转自:商用数据库之死:Oracle 面临困境 这二十年来,商业数据库市场仍然是 IT 行业最稳定.最具黏性的领域之一,Oracle.IBM 和微软三家厂商瓜分了 80% 的份额.然而,我们认为这个领域 ...

  7. SQL数据库从高版本到低版本的迁移,同时解决sql脚本文件太大无法打开的尴尬问题

    as we known,sql数据库高版本向低版本还原是不太可能但是又经常会碰到的事,今天实测了一种方法 步骤:任务—>生成脚本—> 下一步->高级,选择数据库版本和编写脚本数据类型 ...

  8. 价格更低、SLA 更强的全新 Azure SQL 数据库服务等级将于 9 月正式发布

    继上周公告之后,很高兴向大家宣布更多好消息,作为我们更广泛的数据平台的一部分, 我们将在 Azure 上提供丰富的在线数据服务.9 月,我们将针对 Azure SQL 数据库推出新的服务等级.Azur ...

  9. 高版本->低版本迁移,低版本客户端连接高版本数据库EXP导出报错EXP-00008,ORA-01455,EXP-00000

    生产环境: 源数据库:RHEL + Oracle 11.2.0.3 目标数据库:HP-UX + Oracle 10.2.0.4   需求:迁移部分表  11.2.0.3-->10.2.0.4,若 ...

随机推荐

  1. 【bzoj4518】征途

    懒得推式子了,总之是个斜率优化…… 先化一下题目要求的式子,再写一下dp方程,然后就是很自然的斜率优化了qwq #include<bits/stdc++.h> #define N 3005 ...

  2. Linq to SQL 小结

    前天开始看这方面的资料,虽然看了网上对比 sql和linq的速度,万条数据可能要慢1/4左右的数度,但是介于的方便,还是学了 首先看看linq的基本语法: FROM XX IN DATASOURCE ...

  3. dockerfile实例--安装nginx

    [root@localhost ~]# vi Dockerfile //ADD FROM centos_with_net MAINTAINER frankie onez0714@.com RUN yu ...

  4. C#多线程编程之:集合类中Synchronized方法与SyncRoot属性原理分析

    我们知道,在.net的一些集合类型中,譬如Hashtable和ArrayList,都有Synchronized静态方法和SyncRoot属性,他们之间有联系吗?我怎么才能用好他们呢? 以Hashtab ...

  5. SRM 638 Div.2

    250 给一个字符串 要求从一种形式换成另一形式 class NamingConvention{ private: int a, b, c; public: int d; string toCamel ...

  6. git+jenkins在windows机器上新建一个slave节点【转载】

    转至博客:上海-悠悠 前言 我们在跑自动化项目的时候,希望有单独的测试机能跑自动化项目,并且能集成到jenkins上构建任务.如果公司已经有jenkins环境了,那无需重新搭建. 只需在现有的平台基础 ...

  7. C#取出字符串中的数字或字母

    string str20 = "ABC123"; string strSplit1,strSplit2; //取出字符串中所有的英文字母 strSplit1 = Regex.Rep ...

  8. Majority Element——算法课上的一道题(经典)

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  9. 在k8s中安装flannel的故障解决: Failed to create SubnetManager: error retrieving pod spec for : the server does not allow access to the requested resource

    花了一个上午来追踪问题,k8s都反复新建了十多次,docker都重启了几次.(一次显示不有获取磁盘空间,重启docker,清空存储解决) 在用kubeadm安装容器化的几个组件时,flannel组件死 ...

  10. 前端读者 | 百度前端编码规范(HTML)

    本文来自:百度FEX 1 前言 HTML 作为描述网页结构的超文本标记语言,在百度一直有着广泛的应用.本文档的目标是使 HTML 代码风格保持一致,容易被理解和被维护. 2 代码风格 2.1 缩进与换 ...