0

我们有一个在 WildFly 8.2 和 MariaDB 10 上运行的 Java Web 应用程序。我们目前正在评估从单个 MariaDB 服务器迁移到使用 HAProxy 1.5 作为负载均衡器的三节点 Galera/MariaDB 集群。

当仅针对集群发出 DML 命令时,一切正常。但是在某些情况下,我们的 Java 应用程序会运行 DDL 命令,例如 CREATE TABLE 或 ALTER TABLE。例如,在 Web 界面中可以创建新客户。任何这样的客户都会获得 50 个新表来存储其数据。

假设我们添加 id 为 123 的客户,应用程序将运行以下 DDL 和 DML 查询组合:

-- start customer creation
create table Table1_123 (id int not null,.., primary key (id));
create table Table2_123 (id int not null, tid int not null,..., primary key (id));
....
alter table Table2_123 add constraint constraintName foreign key (tid) references Table1_123 (id);
...
insert into Table1_123 ...; -- insert one or more values
insert into Table2_123 ...; -- insert one or more values
...
-- define tables and insert data up to Table50_123

我们有 wsrep_osu_method=toi(默认值)。

创建这样的客户后,我检查了新创建的表,并且很多时候我发现节点之间存在不一致。表格本身已正确复制,但内容未正确复制。某些节点上的一些新表包含尚未复制到其他节点的数据。

我做了一些测试,只将 Java 应用程序直接连接到单个节点,避免了 HA 代理。我遇到了同样的不一致,但不同之处在于只有应用程序直接连接到的节点才保存未复制的数据。在之前的测试中,未复制的数据分散在所有节点上。

我不明白这种行为。我在日志中没有得到任何相关错误。

运行此类 DDL 查询是经常发生的事情。当然,我们希望自动而不是手动完成。当应用程序运行 DDL 和 DML 时,这种情况的最佳方法是什么?

我们的优先事项如下(按此顺序):

  1. 在 DDL 运行期间和之后保持一致性。

  2. 在应用程序代码中做最少的更改。

  3. 如果可能,自动而不是手动运行 DDL。

4

1 回答 1

1

要看的两个项目:

  1. 发生这种情况后,您是否已验证您的集群中的所有节点仍具有 SYNC 状态?缺少数据的节点可能已从集群中删除。
  2. 是否涉及任何交易?Galera 不能很好地处理非常大的交易。如果涉及交易,请谨慎使用,仅在必要时使用。

您肯定想在这里使用 TOI,但是一次做一个表而不是尝试用一个新的 SQL 来做它们可能是有益的。将每个表视为某种“批次”。

如果这些都没有成功,您始终可以单独连接到每个节点并将所有内容作为 RSU 运行。但我有点认为这是一种解决方法,而不是一种解决方案。

参考:GaleraCluster - 架构升级

编辑:答案在评论中。“那里清楚地解释了Galera不支持XA事务......我切换到非XA事务并且问题已经消失并且复制工作正常。”

于 2015-10-05T04:49:35.923 回答