使用MySQL进行分片和事务

问题描述:

使用分片,您如何在多个数据库服务器之间维护可靠的事务?例如,如果我在一个数据库服务器(MySQL实例)上有一个名为AccountLedger的表,并且在另一个数据库服务器上有一个名为User的表,是否可以跨两个数据库实例运行事务,这两个数据库实例都可以可靠地提交,或者回滚失败?使用MySQL进行分片和事务

例事务:

AccountLedger数据库服务器:

START TRANSACTION; 
INSERT INTO AccountLedger SET 
    UserID = @UserID, 
    Date = @Date, 
    Debit = @Debit, 
    Balance = @Balance; 

用户数据库服务器:

START TRANSACTION; 
UPDATE User SET 
    Balance = @Balance 
WHERE UserID = @UserID; 

AccountLedger数据库服务器:

COMMIT; 

用户数据库服务器:

COMMIT; -- What happens if the COMMIT fails here (power goes out or whatever) 

我读过不少关于分片,但我似乎无法找到关于使用交易与分片的任何信息。有人能指引我朝着正确的方向吗?

有可能通过分布式交易做到这一点。它们受InnoDB存储引擎的支持。您将在MySQL文档中找到更多关于它们以及命令语法的信息:XA Transactions

我建议不要直接使用它们。如果一致性是ypur应用程序的最大要求,那么请使用可以处理它的事务监视器。 Java EE为你做到了这一点。

但是,如果可用性比一致性更重要,则应该避免分布式事务。 CAP定理解释了原因。

声明:我ScaleBase(http://www.scalebase.com),在ScaleBase为分片

我们一个完整的解决方案的供应商合作,给使用XA使用交易InnoDB的选择,尽管我们发现它们的性能可能会很高......并且恰好在您需要数据库成为最快的地方(大规模插入等)。所以我们也启用了“我们的两阶段提交版本”,它的速度更快,并且在一致性方面可能被认为与XA非常接近,并且可能足以进行权衡......这个“我们的版本”包括一个快速“是否可用”查询,如SELECT version()到所有参与的数据库,然后提交它们。这是对我们的“ScaleBase数据库流量控制器”中的其他机制的补充,对于我们的大多数客户(以及不是那些 - 仍然可以选择完整的XA)来说已经足够了。

如果每个分片支持每个键的线性化并进行比较和设置(这对于MySQL是正确的),则可以在客户端实现交叉分片可序列化事务。这种方法在Google's PercolatorCockroachDB中使用,但没有任何东西阻止你将它与MySQL一起使用。

我已创建此类交易的step-by-step visualization。我希望它能帮助你理解它们。

如果你对读取提交的隔离级别很好,那么看看Peter Bailis的RAMP transactions是有道理的。它们也可以在分散的MySQL环境中实现。