(5-2)迁移大型SQL表的方法

引言


大家好! 这是我的第一篇文章,我是代表C#的一名初级开发工程师编写的。 因此,将没有有关SQL的任何详细信息,只有关于解决与我本人相同的新手必须面对的相当不明显的问题的实用信息和思想。

首先,我以问题的描述为例,其中确实需要移动大桌子。

因此,假设您有一个Web服务和一个SQL(MS-SQL)数据库,其中包含服务发送给用户的html字母表。 信件已存储了很多年,并且不能删除,因为收集统计信息和分析需要它们。 但是,每年信件的数量在增加,数据库在增长,SQL Server上的空间也在变小(在我们的例子中,另一个因素是将数据库还原到测试站点,因为它的时间成比例地增加了),因此需要采取一些措施去做。 幸运的是,在我们的案例中,有一台具有一堆可用空间的免费服务器(实际上可能不是,当然这是一个临时解决方案,但这超出了本文的范围)。 因此出现了移动大桌子的问题(并说“大”,我的意思是一个非常大的桌子,寻找类似解决方案时看到的所有东西都在60-100 GB的范围内,在我们的例子中,桌子的重量超过300 GB)。

我们将考虑解决此问题的几种方法,但并非所有方法都与服务器-服务器类型的传输有关。 有时可能有必要在同一服务器内的数据库之间转移表。 另外,有些方法纯粹是理论上的,我没有在实践中对它们进行全部测试,但是它们可能应该起作用。

方法-1。 资料


不管听起来多么明显,但您都应该知道要传输的数据。 通常,数据不是以最佳方式存储的,多余的信息也可以存储。 在您的特定情况下,很可能无需传输所有数据就可以这样做。

首先,删除一列可能会为您提供帮助,但这是一项阻止操作,并非总是可以停止Web服务。 在哈布雷(Habré)上有一篇文章,告诉人们如何进行。

其次,不要忘记标准化。 也许可以将某些数据传输到字典中(对于字母来说,可以不存储字母正文,而是存储其中插入了数据的模板),并且只有这些元素的ID可以存储在一个大表中,这可以为您腾出很多空间。

方法0。选择进入


笑话=)因此,您只能以自己为基础。 但是,如果我们谈论的是表的小尺寸(那么您在这里做什么),则可以尝试使用此指令来传输数据库。 另外,如果您有测试依据,则可以使用“额头上”的方法进行实验,以评估总传输时间。

方法1。备份


最“规范”的方法就是通过它解决了我的问题。 我们对包含我们的表的数据库进行备份,然后将其还原到另一台服务器上,并清除所有不必要的数据。 此外,如果可以停止该Web服务,则可以通过在已传送的表中设置记录来重新部署它,并删除旧的* * (在这种情况下,很可能会出现需要通过连接向其写入查询的情况,为此Google如何链接sql-服务器)。 如果无法做到这一点,我们将固定最后一个字母的ID(以进行同步),那么我们将需要删除*所有传输的字母(我们将继续写在旧表中)。

*删除一个单独的话题进行对话,看来它比转移话题要快得多,但事实并非如此,在一般情况下,我建议分部分删除。

方法2:MS-SQL管理Studio


如果您有这个工作室,可以尝试使用内置工具来导出和导入数据。 就个人而言,我在堆栈溢出中读到,这东西挂在60演出桌上,没有任何机会。

方法3。分区


改进的额头方法。 这个想法是在迭代之间使用计时器以通常的方式传输数据。 您将所有行分成几部分(例如,每行100k),转移部分(可以立即将其删除,但不确定它的安全性),然后入睡,依此类推直至结束。 最好从末尾进行传输,这样就不必在末尾同步数据。 该方法显然非常慢,但是通过这种方式,您可以在不停止Web服务的情况下传输所有内容。 不使用SQL脚本,而是借助某些ORM来实现它,将更加方便。

总结


传输大量数据的过程始终需要一定的时间,因此您应该为此做好准备。 没有神奇的方法可以立即解决您的问题。 在每种情况下,您都需要构建自己的数量和限制。 如果没有一种方法适合您,请考虑是否可以使用它们的任何组合。

最后,我想补充两点。

任何在SQL中传输/删除行的过程都将记录在事务日志中,以便在发生错误的情况下回滚所有内容(我以前假设这仅在事务框架内进行)。 而且,日志的大小甚至比数据量还要大。 确保您有必要的空间量或禁用日志记录,但这是不安全的。

传输之前,您需要确保数据文件和日志文件的大小正确,因为 扩展操作会花费大量时间,并进行相应的配置,从而优化迁移。
感谢所有阅读者! 对于任何批评,评论和澄清,我都会感到高兴。 分享您处理大数据的方式和技术,例如 通常,这是非常重要且必不可少的信息。

Source: https://habr.com/ru/post/zh-CN434800/


All Articles