昨天在做变更时,遇到这样一个问题。
在同一个SQL Server实例上,要将一个库中的一个表的数据,全量导入到另一个数据库中,表结构完全一致的空表中。目的数据库的恢复模式是简单。
原定的实施计划是用导入导出向导做,但在向导执行时报错某一列的数据无效。
导入数据。
随时查看导入的进度。
当运行了10分钟,插入了2000W行时,监控系统告警磁盘空间不足。检查磁盘空间发现,数据库日志文件所在的盘,可用空间只剩几十MB了。
看着行数不断减少,估计回滚完成的时间。回滚完成后,赶紧收缩了日志文件。在这种情况下,insert into的方式肯定是不行了,不仅日志空间不够,而且执行时间会比较长。
考虑到临时加磁盘空间时间上来不及,而分批导数据的话,又没有简便高效分批方案,于是改用最小日志记录的方式导数据。
执行以下的语句,先把数据导入到一个临时表destination_table_temp,再修改临时表的名字为destination_table,并创建索引等对象,使其结构与原来的destination_table完全一致。
执行以上的语句,只用了几分钟,就导入了6000W条数据,而其日志文件只增长了不超过1GB。后续改表名,创建索引等就不再详述。
从这次导入数据的操作中,得到的经验如下:
https://technet.microsoft.com/en-us/library/ms191244(v=sql.105).aspx
https://technet.microsoft.com/en-us/library/ms188029(v=sql.105).aspx
在同一个SQL Server实例上,要将一个库中的一个表的数据,全量导入到另一个数据库中,表结构完全一致的空表中。目的数据库的恢复模式是简单。
原定的实施计划是用导入导出向导做,但在向导执行时报错某一列的数据无效。
需要导入的数据有6000W行,要找到哪一行的数据有问题会非常耗时,于是就打算用
insert into destination_table select * from source_table with(nolock)
导入数据。
导入的过程中,执行
select count(1) from destination_table with(nolock)
随时查看导入的进度。
当运行了10分钟,插入了2000W行时,监控系统告警磁盘空间不足。检查磁盘空间发现,数据库日志文件所在的盘,可用空间只剩几十MB了。
只插入了1/3的数据, 日志文件增长20多GB,导致磁盘空间耗尽。服务器上暂时没有别的磁盘空间可用,于是就取消了insert的操作,让事务回滚,时不时执行
select count(1) from destination_table with(nolock)
看着行数不断减少,估计回滚完成的时间。回滚完成后,赶紧收缩了日志文件。在这种情况下,insert into的方式肯定是不行了,不仅日志空间不够,而且执行时间会比较长。
考虑到临时加磁盘空间时间上来不及,而分批导数据的话,又没有简便高效分批方案,于是改用最小日志记录的方式导数据。
执行以下的语句,先把数据导入到一个临时表destination_table_temp,再修改临时表的名字为destination_table,并创建索引等对象,使其结构与原来的destination_table完全一致。
select * into destination_table_temp from source_table with(nolock)
执行以上的语句,只用了几分钟,就导入了6000W条数据,而其日志文件只增长了不超过1GB。后续改表名,创建索引等就不再详述。
从这次导入数据的操作中,得到的经验如下:
- 如果是简单的同构数据导入,尽量用SQL语句,简单明了,用导入导出向导会提高报错的概率,而且不好排查。
- 在insert into 导入数据或者回滚的过程中,都可以执行select count(1) from xxx with(nock),查看导入或者回滚的进度。
- 在select * into table_xxx from table_aaa的执行过程中,即便加了with(nolock),select count (*) from table_aaa 也会被阻塞,应该是架构锁的缘故。
- 使用最小日志记录模式导入数据,速度非常快,产生的日志量非常少。不过select into table要在数据库的恢复模式是简单或大容量日志时,才能使用最小日志记录模式。
- 正常日志记录模式导入数据时,大量的IO成本和等待时间其实都是消耗在写日志文件上,而写数据文件的成本相比之下少很多
- 即便数据库的恢复模式是简单,一个大的事务也会造成日志文件的持续增长,而且事务结束后,日志文件不会自动收缩(除非打开了自动收缩的选项)。
https://technet.microsoft.com/en-us/library/ms191244(v=sql.105).aspx
https://technet.microsoft.com/en-us/library/ms188029(v=sql.105).aspx