SQL Server 迁移至MySQL 关键步骤的梳理总结

迁移主要是通过Navicat工具来实现的。迁移工具的选定在此不讨论。

迁移前准备

1.提前通知DBA\SA\BI等,并确认发布计划及数据库迁移方案。

2.梳理出SQL  Server DB 中影响业务的Job(迁移的过程中要关闭)、DB LinkServer、相关账号。

3.模拟数据迁移,评估出相关精确的时间。例如每张大表的耗时(我们定义的表准是,每张百万级别的表耗时都要测评出来),每2分钟一个进度标记。Navicat 工具不能指定SQL条件迁移 ,需全表迁移,因此 不支持增量迁移。SQL Server 和 MySQL 表结构需一致。表名、字段名一致。如果不一致,需要创建一个过渡库过渡表来进行迁移。

4.创建生产环境的MySQL数据库,将最终的Dev环境的表导入生产环境(只导表结构)。与SQL Server 相比,如果有表结构调整,最好要求开发提供数变化的list(包含新增表、新增索引等)。

5.对生产环境的MySQL进行账号设置(DBkey等相关配置一起设置)。

6.对生产环境的表进行检查(主要表结构的变化,例如主要字段、索引、默认值等)。Navicat工具导入的过程中,可以保留索引,但是默认值会丢失,并且默认字段不理想。此步骤可参照附录。

7.进行测试(全链路,从数据库的连接到插入更新等)。测试可以是全面的,DB对数据库进行测试,当然,针对应用程序,可以要求测试人员提供一份性能压测报告。

8.数据库备份作业的设置(完整备份和Binlog备份)。

9.验证迁移步骤及准备脚本

迁移中

1.请SA团队暂停相关的业务服务

2.禁用Server 上DB的相关账号。

3.停止备份Job 和影响业务的Job。

4.数据迁移。

5.验证数据,主要是比对迁移前后数据量。

6.通知全员数据迁移完毕。通知SA开启相关服务。

迁移后

1.删除链接服务器(DBLink,本地相关链接服务器 和异地有关此DB的连接服务器)。

2.通过活动监视器或SQL命令查询是否还有对此 SQL Server DB的请求。

3.MySQL数据库性能监控。

4.数据库做一个完整备份,Copy至异地服务器。Copy至异地,主要是考虑服务器资源的回收,此为,在异地最好要添加一个对备份文件的描述,例如此文件是什么时候产生的,用途是什么,是否可以删除,建议保留时间,操作人等。

5.关闭SQL Server 剩余的Job。

6.Detach (分离)数据库(一定是Detach 不要直接删除,虽然有备份文件,但恢复还是相对较慢的)。

7.如果此服务器上没有其它的用户数据库,停止SQL Server 服务。

8.历史数据库的迁移(如果有的话)。

9.归档数据Job的设置。

10.本次迁移的总结报告(主要是梳理出迁移过程注意的事项和提升的建议)

附录

附录A

SQL Server 与 MySQL 字段类型对照表

SQL Server MySQL
n/varchar(1-4000) varchar(1-4000)
varchar(4000-8000) text
n/varchar(max) longtext
char char
nchar varchar
timestamp timestamp
time datetime(3)
datetime datetime(3)
date datetime(3)
smalldatetime datetime(3)
numeric decimal
numeric17 decimal
ntext mediumtext
text mediumtext
bit tinyint
int int
tinyint tinyint
bigint bigint
smallint int
float double
decimal decimal
varbinary varchar
binary varchar
image longblob
uniqueidentifier varchar(40)
real double
money decimal(19,4)
longblob longblob

附录B

查询生成 需添加默认值和调整字段的SQL语句。

以下T-SQL在需要迁移的SQL Server DB上执行,生成的SQL 语句在MySQL直接执行(sql_text列)。

SELECT  'alter table ' + D.name + ' modify column ' + A.name+' '
+ CASE WHEN B.name = 'datetime' THEN ' datetime(3)'
WHEN B.name = 'bit' THEN ' tinyint(1)'
WHEN B.name = 'decimal'
THEN ' decimal('
+ CAST(COLUMNPROPERTY(A.id, A.name, 'PRECISION') AS VARCHAR(10))
+ ','
+ CAST(ISNULL(COLUMNPROPERTY(A.id, A.name, 'Scale'), 0) AS VARCHAR(10))
+ ')'
WHEN B.name like '%varchar' AND COLUMNPROPERTY(A.id, A.name, 'PRECISION')=-1 THEN ' varchar(4000)'
WHEN B.name like '%varchar' AND COLUMNPROPERTY(A.id, A.name, 'PRECISION')<>-1 THEN ' varchar('+CAST(COLUMNPROPERTY(A.id, A.name, 'PRECISION') AS VARCHAR(20))+')'
WHEN B.name like '%varbinary' AND COLUMNPROPERTY(A.id, A.name, 'PRECISION')=-1 THEN ' varbinary(4000)'
WHEN B.name like '%varbinary' AND COLUMNPROPERTY(A.id, A.name, 'PRECISION')<>-1 THEN ' varbinary('+CAST(COLUMNPROPERTY(A.id, A.name, 'PRECISION') AS VARCHAR(20))+')'
ELSE B.name
END + CASE WHEN A.isnullable = 1 THEN ' NULL'
ELSE ' NOT NULL '
END + ' default '
+ CAST (CASE WHEN E.text = '(getdate())' THEN 'CURRENT_TIMESTAMP(3)'
WHEN E.text LIKE '(%'
THEN REPLACE(REPLACE(E.text, '(', ''), ')', '')
ELSE E.text
END AS VARCHAR(30))
+ CASE WHEN ISNULL(G.[value], '') <> ''
THEN ' COMMENT '''
+ CAST(ISNULL(G.[value], '') AS VARCHAR(100)) + ''';'
ELSE ';'
END AS sql_text ,
表名 = D.name ,
字段名 = A.name ,
字段说明 = ISNULL(G.[value], '') ,
类型 = B.name ,
占用字节数 = A.length ,
长度 = COLUMNPROPERTY(A.id, A.name, 'PRECISION') ,
小数位数 = ISNULL(COLUMNPROPERTY(A.id, A.name, 'Scale'), 0) ,
允许空 = CASE WHEN A.isnullable = 1 THEN 'Y'
ELSE 'N'
END ,
默认值 = ISNULL(E.text, '')
FROM syscolumns A
INNER JOIN systypes B ON A.xusertype = B.xusertype
INNER JOIN sysobjects D ON A.id = D.id
AND D.xtype = 'U'
AND D.name <> 'dtproperties'
INNER JOIN syscomments E ON A.cdefault = E.id
LEFT JOIN sys.extended_properties G ON A.id = G.major_id
AND A.colid = G.minor_id
LEFT JOIN sys.extended_properties F ON D.id = F.major_id
AND F.minor_id = 0
WHERE B.name <> 'uniqueidentifier'
and D.name not in ('需排除的表')
ORDER BY D.name ,
A.id ,
A.colorder

本文版权归作者所有,未经作者同意不得转载,谢谢配合!!!

上一篇:深入ThreadLocal之三(ThreadLocal可能引起的内存泄露)


下一篇:URAL 1029