(5.3.3)数据库迁移——迁移一个实例到底需要注意哪些方面?
SQL Server 迁移
【1】核心数据
DIR
【1.0】与当前版本相同、或者更高的数据库版本,相同的实例名、实例排序规则
【1.1】登录名及对应实例权限
【1.2】用户数据库,其本身的数据及库上的触发器、存储过程、函数等数据库对象信息
【1.3】作业
Content
【1.0】与当前版本相同、或者更高的数据库版本,相同的实例名、实例排序规则
use master go SELECT SERVERPROPERTY('MachineName') AS ComputerName, SERVERPROPERTY('ServerName') AS InstanceName, -- 如果显示的和计算机名一样,那么实例为默认实例 SERVERPROPERTY('Edition') AS Edition, SERVERPROPERTY('ProductVersion') AS ProductVersion_number, SERVERPROPERTY('ProductLevel') AS ProductLevel, SERVERPROPERTY('Collation') as Collation; GO
【1.1】登录名及对应实例权限
USE master GO IF OBJECT_ID ('sp_hexadecimal') IS NOT NULL DROP PROCEDURE sp_hexadecimal GO CREATE PROCEDURE sp_hexadecimal @binvalue varbinary(256), @hexvalue varchar (514) OUTPUT AS DECLARE @charvalue varchar (514) DECLARE @i int DECLARE @length int DECLARE @hexstring char(16) SELECT @charvalue = '0x' SELECT @i = 1 SELECT @length = DATALENGTH (@binvalue) SELECT @hexstring = '0123456789ABCDEF' WHILE (@i <= @length) BEGIN DECLARE @tempint int DECLARE @firstint int DECLARE @secondint int SELECT @tempint = CONVERT(int, SUBSTRING(@binvalue,@i,1)) SELECT @firstint = FLOOR(@tempint/16) SELECT @secondint = @tempint - (@firstint*16) SELECT @charvalue = @charvalue + SUBSTRING(@hexstring, @firstint+1, 1) + SUBSTRING(@hexstring, @secondint+1, 1) SELECT @i = @i + 1 END SELECT @hexvalue = @charvalue GO IF OBJECT_ID ('sp_help_revlogin') IS NOT NULL DROP PROCEDURE sp_help_revlogin GO CREATE PROCEDURE sp_help_revlogin @login_name sysname = NULL AS DECLARE @name sysname DECLARE @type varchar (1) DECLARE @hasaccess int DECLARE @denylogin int DECLARE @is_disabled int DECLARE @PWD_varbinary varbinary (256) DECLARE @PWD_string varchar (514) DECLARE @SID_varbinary varbinary (85) DECLARE @SID_string varchar (514) DECLARE @tmpstr varchar (1024) DECLARE @is_policy_checked varchar (3) DECLARE @is_expiration_checked varchar (3) DECLARE @defaultdb sysname IF (@login_name IS NULL) DECLARE login_curs CURSOR FOR SELECT p.sid, p.name, p.type, p.is_disabled, p.default_database_name, l.hasaccess, l.denylogin FROM sys.server_principals p LEFT JOIN sys.syslogins l ON ( l.name = p.name ) WHERE p.type IN ( 'S', 'G', 'U' ) AND p.name <> 'sa' ELSE DECLARE login_curs CURSOR FOR SELECT p.sid, p.name, p.type, p.is_disabled, p.default_database_name, l.hasaccess, l.denylogin FROM sys.server_principals p LEFT JOIN sys.syslogins l ON ( l.name = p.name ) WHERE p.type IN ( 'S', 'G', 'U' ) AND p.name = @login_name OPEN login_curs FETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @hasaccess, @denylogin IF (@@fetch_status = -1) BEGIN PRINT 'No login(s) found.' CLOSE login_curs DEALLOCATE login_curs RETURN -1 END SET @tmpstr = '/* sp_help_revlogin script ' PRINT @tmpstr SET @tmpstr = '** Generated ' + CONVERT (varchar, GETDATE()) + ' on ' + @@SERVERNAME + ' */' PRINT @tmpstr PRINT '' WHILE (@@fetch_status <> -1) BEGIN IF (@@fetch_status <> -2) BEGIN PRINT '' SET @tmpstr = '-- Login: ' + @name PRINT @tmpstr IF (@type IN ( 'G', 'U')) BEGIN -- NT authenticated account/group SET @tmpstr = 'CREATE LOGIN ' + QUOTENAME( @name ) + ' FROM WINDOWS WITH DEFAULT_DATABASE = [' + @defaultdb + ']' END ELSE BEGIN -- SQL Server authentication -- obtain password and sid SET @PWD_varbinary = CAST( LOGINPROPERTY( @name, 'PasswordHash' ) AS varbinary (256) ) EXEC sp_hexadecimal @PWD_varbinary, @PWD_string OUT EXEC sp_hexadecimal @SID_varbinary,@SID_string OUT -- obtain password policy state SELECT @is_policy_checked = CASE is_policy_checked WHEN 1 THEN 'ON' WHEN 0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE name = @name SELECT @is_expiration_checked = CASE is_expiration_checked WHEN 1 THEN 'ON' WHEN 0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE name = @name SET @tmpstr = 'CREATE LOGIN ' + QUOTENAME( @name ) + ' WITH PASSWORD = ' + @PWD_string + ' HASHED, SID = ' + @SID_string + ', DEFAULT_DATABASE = [' + @defaultdb + ']' IF ( @is_policy_checked IS NOT NULL ) BEGIN SET @tmpstr = @tmpstr + ', CHECK_POLICY = ' + @is_policy_checked END IF ( @is_expiration_checked IS NOT NULL ) BEGIN SET @tmpstr = @tmpstr + ', CHECK_EXPIRATION = ' + @is_expiration_checked END END IF (@denylogin = 1) BEGIN -- login is denied access SET @tmpstr = @tmpstr + '; DENY CONNECT SQL TO ' + QUOTENAME( @name ) END ELSE IF (@hasaccess = 0) BEGIN -- login exists but does not have access SET @tmpstr = @tmpstr + '; REVOKE CONNECT SQL TO ' + QUOTENAME( @name ) END IF (@is_disabled = 1) BEGIN -- login is disabled SET @tmpstr = @tmpstr + '; ALTER LOGIN ' + QUOTENAME( @name ) + ' DISABLE' END PRINT @tmpstr END FETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @hasaccess, @denylogin END CLOSE login_curs DEALLOCATE login_curs RETURN 0 GO exec sp_help_revlogin
--查看登录名服务器角色 SELECT sp.name AS [login_name] ,CASE WHEN sp.[type]='S' THEN 'SQL 登录名' WHEN sp.[type]='U' THEN 'Windows 登录名' WHEN sp.[type]='G' THEN 'Windows 组' WHEN sp.[type]='R' THEN '服务器角色' WHEN sp.[type]='C' THEN '映射到证书的登录名' WHEN sp.[type]='K' THEN '映射到非对称密钥的登录名' END AS [principal_type] ,sp.is_disabled ,ISNULL(sp.default_database_name,'') as [default_database_name] ,ISNULL(rsp.name,'') AS [server_role] ,STUFF((SELECT ','+permission_name FROM sys.server_permissions spp where sp.principal_id=spp.grantee_principal_id for xml path('')),1,1,'') as [permissions] FROM sys.server_principals sp LEFT JOIN sys.server_role_members srm ON sp.principal_id=srm.member_principal_id LEFT JOIN sys.server_principals rsp ON srm.role_principal_id=rsp.principal_id where rsp.name is not null ORDER BY [principal_type],sp.principal_id --授权服务器角色 select N'EXEC sp_addsrvrolemember N''' +sp.name+ ''' ,N''' + rsp.name+''' ' FROM sys.server_principals sp LEFT JOIN sys.server_role_members srm ON sp.principal_id=srm.member_principal_id LEFT JOIN sys.server_principals rsp ON srm.role_principal_id=rsp.principal_id where rsp.name is not null -- 将登录名添加为某个服务器级角色的成员 EXEC sp_addsrvrolemember @loginame= 'kk' ,@rolename = 'sysadmin' master库中的用户名及权限可以用如下脚本进行迁移。 -- 授予【数据库角色成员身份】权限 SELECT 'exec sp_addrolemember N'''+g.name+''', N'''+u.name+'''' FROM sys.database_principals u inner join sys.database_role_members m on u.principal_id = m.member_principal_id inner join sys.database_principals g on g.principal_id = m.role_principal_id ORDER BY g.name,u.name -- 授予【安全对象】权限 SELECT N'grant '+B.permission_name collate chinese_prc_ci_ai_ws+N' on ['+A.name+N'] to ['+C.name+N']' FROM sys.sysobjects A(NOLOCK) INNER JOIN sys.database_permissions B(NOLOCK) ON A.id=B.major_id INNER JOIN sys.database_principals C(NOLOCK) ON B.grantee_principal_id=C.principal_id --WHERE C.name='kk' --A.name='objectName'
【1.2】用户数据库,其本身的数据及库上的触发器、存储过程、函数等数据库对象信息
【method-1】备份还原(利用用户数据库备份还原)
【method-2】生成脚本(利用对象资源管理器详细信息(快捷键F7),批量生成数据库对象的创建脚本)
【method-3】故障转移(利用复制、镜像、日志传送等技术,以最小停机时间为标准来解决)
【1.3】作业
【method-1】利用对象资源管理器详细信息(快捷键F7),批量生成作业的创建SQL脚本)
【method-2】自己根据msdb相关系统表、视图等数据,写脚本生产创建作业SQL
【2】步骤列表
一定要有一个准备好的计划,我下面列出了所有的迁移过程需要做的工作,如下列表:
序号 |
SQL Server迁移步骤 |
1 |
必要环境的准备(比如高版本的服务器操作系统) |
2 |
研究弃用和停用的功能、特性 |
3 |
运行数据迁移助手(DMA)了解哪些改变不被允许或者会影响迁移。 |
4 |
确认SQL Server 服务,数据引擎,SSIS,SSAS,SSRS等等可用 |
5 |
排序规则注意一致或者有变更的仔细核对 |
6 |
确保应用程序的连接需求 |
7 |
日志、聚集、数据库镜像、复制、全文索引、分布式服务等服务类的都需要有计划的去管理迁移。 |
8 |
管理有效的连接服务器,迁移 |
9 |
备份策略和计划的完整迁移,包含了完整、差别、事务日志备份。 |
10 |
规划需要的磁盘空间 |
11 |
管理迁移各个服务的账号 |
12 |
检查数据一致性 |
13 |
预升级--升级前后比较性能指标 |
14 |
评估宕机时间及影响 |
15 |
定稿升级流程 |
16 |
制定升级、迁移的验收标准 |
17 |
最终验收 |
18 |
回滚计划以及测试 |
19 |
务必通知所有涉及和影响的负责人 |
20 |
向所有负责人发送升级、迁移的步骤 |
21 |
准备新的、或者迁移旧的数据库维护计划 |