我们有一个运行 SQL-Server 的生产服务器,它保存我们的后端数据,例如客户信息、销售发票等。这些数据的性质是“旧”数据可以改变,例如客户更新他们的地址。
目前,我们使用 Windows Server 2008 实例作为研究服务器,这样我们就可以在其上运行 MS-SQL 从属服务器,该服务器以事务方式从实时服务器复制数据。然后,我们每天从从属服务器将平面文件导出到我们的研究模式中,该模式恰好是 MySQL DB。我们通过将从属数据读入某些算法来实现这一点,这些算法会修改数据并将其写入 MySQL 研究数据库。我们删除研究数据库中的所有表,并每天进行干净导入,以处理生产数据库和从属数据库中可能已更改的“旧”数据。
因此,从本质上讲,从实时数据库转到我们的研究模式总是涉及每天进行完全转储并重新导入,这对我们来说很好,因为一切都在本地完成。
不幸的是,我们在 MS-SQL 复制和 Windows 服务器方面都遇到了很多问题;这些问题的根源实际上主要是人为的,而不是技术。然而,我们确实遇到了额外的问题,我们必须使用其他 Linux 应用程序服务器,因为在 Windows 上运行我们在其他领域需要的一些平台/堆栈很困难……
我想将我们的研究服务器移动到我更熟悉的Linux机器上,并且能够正确管理和配置,但我不知道从实时MS-SQL DB转移到我们的研究MySQL模式的最佳行动计划,因为我们现在没有选择将实时复制到从属服务器。
基本上:
- 大约有 5 个 SQL-Server 表,总计约 3GB
- 如果我们每天进行 3GB 的导出(目前我们将事务复制到从属服务器,然后从从属服务器进行 3GB 的导出),我们的 IT 人员担心生产服务器上的 IO 负载。
我们将 SQL-Server 数据导入研究模式的更新过程预计每天都会进行整个导入,但当然,无论是从平面文件/SQL 文件还是表导入都无关紧要。
因此,我们知道,不管怎样,我们都将对 SQL-Server 数据进行平面文件导入,但是,问题是 - 有没有一种聪明的方法可以每天从 MS-SQL 表导出,而不必进行整个转储?
我是不是谈论复制,因为接收端不会有 MS-SQL 实例,因为它是 Linux 服务器。但是,是否可以从 MS-SQL 服务器仅导出已修改字段的行?也就是说,当然无需修改 SQL-Server 表的架构来标记已编辑的行... :-)
SQL 服务器可以保存修改过的行或任何内容的日志吗?
如果以上这些都失败了,那么是否有人知道,每次进行 3GB 导出时,配置不足的 SQL-Server 实例是否会出现故障?我不太相信这一点... 我们讨论的是凌晨时分数据库上的最小负载(我们是一家小型 B2B 互联网零售商,因此不希望在那些时间发生太多事情)。
谢谢!
答案1
如果您想保留该“从属”SQL Server,我建议您忘记复制,只需将每日备份加载到服务器上,或摆弄恢复事务日志备份。DBA 应该有这些,您只需说服他们帮助您将生产数据自动恢复到“从属”框上。但是,在我看来,您宁愿从属框消失。
我将详细研究“更改跟踪”和“更改数据捕获”功能。据我所知,“更改跟踪”通过提供主键值列表来识别受监控表中已更改的行。“更改数据捕获”提供更多信息,包括捕获实际的前后值,以进行全面审计。手写简介是,您将从 SQL Server 表中读取描述更改的内容,然后更新 mysql 数据库。没有花哨的复制、代理或任何东西。这是 MS 的这些功能的登录页面。
在我看来,您可以只使用更改跟踪,并使用 SQL Server 中当前有效的值覆盖 mysql 中的所有内容。我预计更改数据捕获会比更改跟踪给系统带来更多负载。
至于每天 3GB 的提取量:我见过“过度配置”的服务器,其 SAN 存储性能不佳。拥有大量核心并不能解决所有问题。夜间通常还有其他事情要做,例如备份、碎片整理、其他提取、大量报告运行等。对我来说,“互联网零售商”意味着您随时都有流量。DBA 可能只是担心添加不必要的负载。
答案2
如果研究服务器仅包含基于生产数据库的数据,为什么不在 Linux 服务器上运行 SQL Server 而不是 MySQL?如果您的生产数据库小于 4GB(听起来是这样的),您可以免费运行 SQL Server Express 版本。
您不需要单独的导出步骤。IT 人员应该已经对生产数据库进行了完整和事务日志备份,因此他们已经支付了 I/O 成本。SQL Server Express 可以轻松读取这些备份并将其恢复到您的 Linux 服务器上。
我个人从未使用过 SQL Server DB 复制,但听起来您有。因此,您也可以选择从生产复制到研究数据库。
Linux 上的 SQL Server 2017
现在有了 SQL Server 2019,它必定会更好!
答案3
我知道您提到过您不想修改表,但是您是否考虑过在表上添加更新/插入触发器来编写一个删除文件,然后您的 Linux 机器可以获取该文件并用它来更新 MySQL 服务器?
就像是
USE [DatabaseName]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[trig_WriteDropfileOnChange] ON [dbo].[tableName]
FOR INSERT, UPDATE
AS
-- declare vars
DECLARE @RecordId bigint,
@RetCode int,
@FileSystem int,
@FileHandle int,
@MyDate varchar(255),
@FileName varchar(255)
-- build filename
SET @MyDate = getDate()
SET @MyDate = REPLACE(@MyDate, ':', '')
SET @MyDate = REPLACE(@MyDate, ' ', '')
SET @MyDate = REPLACE(@MyDate, '-', '')
SET @MyDate = REPLACE(@MyDate, '.', '')
SELECT @RecordID = myfield
FROM INSERTED
SET @FileName = '\\path\to\drop\directory\' + @MyDate + '.txt'
EXECUTE @RetCode = sp_OACreate 'Scripting.FileSystemObject', @FileSystem OUTPUT
IF (@@ERROR|@RetCode > 0 Or @FileSystem < 0)
RAISEERROR('could not create FileSystemObject', 16, 1)
EXECUTE @RetCode = sp_OAMethod @FileSystem, 'OpenTextFile', @FileHandle OUTPUT, @FileName, 2, 1
IF (@@ERROR|@RetCode > 0 Or @FileHandle < 0)
RAISEERROR('Could not open file.', 16, 1)
EXECUTE @RetCode = sp_OAMethod @FileHandle, 'WriteLine', NULL, CONVERT(varchar, @RecordId)
IF (@@ERROR|@RetCode > 0 Or @FileHandle < 0)
RAISEERROR('Could not write to file.', 16, 1)
EXECUTE @RetCode = sp_OAMethod @FileHandle, 'Close', NULL
IF (@@ERROR|@RetCode > 0)
RAISEERROR('Could not close file.', 16, 1)
EXEC sp_OADestroy @FileSystem