Linux公社论坛

 找回密码
 注册
查看: 249|回复: 1

[其他] SQL Server 迁移至MySQL 关键步骤的梳理总结

[复制链接]

3

主题

0

听众

6

积分

新手上路

Rank: 1

dellkefu 发表于 2018-12-7 16:03:33 |显示全部楼层
迁移主要是通过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.本次迁移的总结报告(主要是梳理出迁移过程注意的事项和提升的建议)

附录附录ASQL Server 与 MySQL 字段类型对照表
SQL ServerMySQL
n/varchar(1-4000)varchar(1-4000)
varchar(4000-8000)text
n/varchar(max)longtext
charchar
ncharvarchar
timestamptimestamp
timedatetime(3)
datetimedatetime(3)
datedatetime(3)
smalldatetimedatetime(3)
numericdecimal
numeric17decimal
ntextmediumtext
textmediumtext
bittinyint
intint
tinyinttinyint
bigintbigint
smallintint
floatdouble
decimaldecimal
varbinaryvarchar
binaryvarchar
imagelongblob
uniqueidentifiervarchar(40)
realdouble
moneydecimal(19,4)
longbloblongblob

附录B查询生成 需添加默认值和调整字段的SQL语句。
以下T-SQL在需要迁移的SQL Server DB上执行,生成的SQL 语句在MySQL直接执行(sql_text列)。
  1. SELECT  'alter table ' + D.name + ' modify column ' + A.name+' '
  2.         + CASE WHEN B.name = 'datetime' THEN ' datetime(3)'
  3.                WHEN B.name = 'bit' THEN ' tinyint(1)'
  4.                WHEN B.name = 'decimal'
  5.                THEN ' decimal('
  6.                     + CAST(COLUMNPROPERTY(A.id, A.name, 'PRECISION') AS VARCHAR(10))
  7.                     + ','
  8.                     + CAST(ISNULL(COLUMNPROPERTY(A.id, A.name, 'Scale'), 0) AS VARCHAR(10))
  9.                     + ')'
  10.                WHEN B.name like '%varchar' AND COLUMNPROPERTY(A.id, A.name, 'PRECISION')=-1 THEN ' varchar(4000)'
  11.                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))+')'
  12.                WHEN B.name like '%varbinary' AND COLUMNPROPERTY(A.id, A.name, 'PRECISION')=-1 THEN ' varbinary(4000)'
  13.                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))+')'
  14.                ELSE B.name
  15.                  END + CASE WHEN A.isnullable = 1 THEN ' NULL'
  16.                      ELSE ' NOT NULL '
  17.                 END + ' default '
  18.              + CAST (CASE WHEN E.text = '(getdate())' THEN 'CURRENT_TIMESTAMP(3)'
  19.                      WHEN E.text LIKE '(%'
  20.                      THEN REPLACE(REPLACE(E.text, '(', ''), ')', '')
  21.                      ELSE E.text
  22.                 END AS VARCHAR(30))
  23.            + CASE WHEN ISNULL(G.[value], '') <> ''
  24.                THEN ' COMMENT '''
  25.                     + CAST(ISNULL(G.[value], '') AS VARCHAR(100)) + ''';'
  26.                ELSE ';'
  27.           END AS sql_text ,
  28.         表名 = D.name ,
  29.         字段名 = A.name ,
  30.         字段说明 = ISNULL(G.[value], '') ,
  31.         类型 = B.name ,
  32.         占用字节数 = A.length ,
  33.         长度 = COLUMNPROPERTY(A.id, A.name, 'PRECISION') ,
  34.         小数位数 = ISNULL(COLUMNPROPERTY(A.id, A.name, 'Scale'), 0) ,
  35.         允许空 = CASE WHEN A.isnullable = 1 THEN 'Y'
  36.                    ELSE 'N'
  37.               END ,
  38.         默认值 = ISNULL(E.text, '')
  39. FROM    syscolumns A
  40.         INNER JOIN systypes B ON A.xusertype = B.xusertype
  41.         INNER JOIN sysobjects D ON A.id = D.id
  42.                                    AND D.xtype = 'U'
  43.                                    AND D.name <> 'dtproperties'
  44.         INNER JOIN syscomments E ON A.cdefault = E.id
  45.         LEFT JOIN sys.extended_properties G ON A.id = G.major_id
  46.                                                AND A.colid = G.minor_id
  47.         LEFT JOIN sys.extended_properties F ON D.id = F.major_id
  48.                                                AND F.minor_id = 0
  49. WHERE   B.name <> 'uniqueidentifier'
  50.         and D.name not in ('需排除的表')
  51. ORDER BY D.name ,
  52.         A.id ,
  53.         A.colorder
复制代码

3

主题

0

听众

18

积分

新手上路

Rank: 1

rot 发表于 2019-2-21 12:56:00 |显示全部楼层
有用,受教了,先mark着。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

关注Linux公社官方微信,免费领取邀请码。

手机版|Linux公社(LinuxIDC.com)旗下网站【www.linuxidc.net】

GMT+8, 2019-6-18 19:41 , Processed in 0.061004 second(s), 19 queries , Wincache On.

Powered by Discuz! X 3.2

© 2010-2016 Comsenz Inc.

回顶部