【发布时间】:2010-10-12 07:44:48
【问题描述】:
我们在数据中心有一个 MySQL 数据库(大部分是只读的,因此是 MyISAM 表),它与现场的 SQL Server 数据库通信。 WAN 中有一些明显的延迟(超过 100 毫秒);大约 6 个月后,SQL Server DBMS 将向上移动到数据中心(例如同一个千兆位 LAN)。
在 MySQL 数据库中,我需要根据 SQL Server 数据库中的结果更新数千行。 MySQL DB 连接到在 Linux 上运行的 rails 应用程序,所以我想在 shell 脚本或 rake/ruby 任务中保留尽可能多地迁移数据的逻辑(我们不是Windows 应用程序开发人员,所以 Win32 应用程序和类似的应用程序完全!)。
这是一个相当简单的过程。在伪代码中:
SELECT id
, amount
FROM bank_account.on_SQL_Server
WHERE (some logic)
FOREACH ROW:
UPDATE bank_account.on_MySQL
SET amount = $some_amount
WHERE id = $some_id
让我们假设有几千行需要更新并且更新频率很高(每 5 分钟一次)。还假设我无法知道 SQL Server 中的哪些行发生了变化(不幸的是!)所以我不能将其限制为仅修改过的行——我必须将它们全部发送出去(糟糕,但是 SQL Server DB是无法修改的第 3 方应用程序编辑:我们确实可以控制 DBMS,因此我们可以进行一些轻微的修改,例如对表的触发器或新的存储过程——只是没有表模式更改以添加最后更新的列 - 但我想将此选项保存为最后的手段)。
如何最好地执行此更新过程以最小化运行时间?这个过程需要每隔几分钟运行一次(越快越好),并且从 Ruby 向 SQL Server 和 MySQL 发出双连接太慢了。这可能是由 MyISAM 引擎发出的一些写表锁,但转换为 Innodb 似乎并没有让它更快(系统正在测试中,因此不容易模拟生产将收到的相同类型的负载,导致我相信它与锁无关)。
我目前倾向于 BCP 将 VIEW(对应于上面的 SQL Server 语句)写入文件,通过 FTP 传输到 Linux 服务器,然后使用 Ruby foreach 文件(并执行大量序列化SQL 语句),但我不得不想象还有更好的方法。
【问题讨论】:
标签: mysql sql-server ruby performance migration