与 MariaDB Galera Cluster(read/write 用户)一起使用时,PHPUnit 测试随机失败
PHPUnit tests fails randomly when used with MariaDB Galera Cluster (read/write user)
我有一个 Laravel (Lumen 5.2) 项目 运行 针对 MariaDB Galera 集群。当 运行 连接应用程序时,它似乎工作正常。但是当我 运行 PHPUnit 测试时,它们随机失败。
问题是我填充了数据库,然后尝试获取数据 (id) 以使用外键填充其他表。但是当试图立即获取数据时,数据为空。
Laravel 数据库连接用于 READ 用户和 WRITE 用户。 (Laravel 插入或读取时自动使用正确的那个)。我认为这就是问题所在。当我只使用 WRITE 用户时,测试工作正常。
SET SESSION wsrep_sync_wait = 1;
在 SELECT
之前将保证写入已经赶上。
虽然 Galera 是 "synchronous",但也不完全是。保证将写入发送到所有其他节点,并且它们将在那里工作。但是,在 "critical" 读取的情况下,SELECT
到达接收节点的速度太快,无法看到写入。上面的设置解决了这个问题。
现在,让我们真正了解一下您应该如何实施,比如说,在幕后使用 Galera 的网站。
- 在可行的情况下,例如在事务中,对相同 节点执行所有命令。对此没有处罚。 But,检查
COMMIT
后的错误。
- 当不切实际时——例如从一个新的 HTTP 连接开始一个新的网页——使用
SET
。
虽然 SELECT
等待复制可能会有轻微延迟,但延迟通常 非常接近于零。我建议您的测试实际上是压力测试,会欺骗性地说等待时间很长。也就是说,基准测试通常旨在找到 "worst",而不是 "typical"。
写入和失败之间有多少延迟SELECT
?也许只有1ms。 'user' post 和 'blog' 可以多快到达下一页并找到它 "missing"?可能超过 100 毫秒。
您的压力测试发现需要SET
,而不是 Galera 'broken'。
我有一个 Laravel (Lumen 5.2) 项目 运行 针对 MariaDB Galera 集群。当 运行 连接应用程序时,它似乎工作正常。但是当我 运行 PHPUnit 测试时,它们随机失败。
问题是我填充了数据库,然后尝试获取数据 (id) 以使用外键填充其他表。但是当试图立即获取数据时,数据为空。
Laravel 数据库连接用于 READ 用户和 WRITE 用户。 (Laravel 插入或读取时自动使用正确的那个)。我认为这就是问题所在。当我只使用 WRITE 用户时,测试工作正常。
SET SESSION wsrep_sync_wait = 1;
在 SELECT
之前将保证写入已经赶上。
虽然 Galera 是 "synchronous",但也不完全是。保证将写入发送到所有其他节点,并且它们将在那里工作。但是,在 "critical" 读取的情况下,SELECT
到达接收节点的速度太快,无法看到写入。上面的设置解决了这个问题。
现在,让我们真正了解一下您应该如何实施,比如说,在幕后使用 Galera 的网站。
- 在可行的情况下,例如在事务中,对相同 节点执行所有命令。对此没有处罚。 But,检查
COMMIT
后的错误。 - 当不切实际时——例如从一个新的 HTTP 连接开始一个新的网页——使用
SET
。
虽然 SELECT
等待复制可能会有轻微延迟,但延迟通常 非常接近于零。我建议您的测试实际上是压力测试,会欺骗性地说等待时间很长。也就是说,基准测试通常旨在找到 "worst",而不是 "typical"。
写入和失败之间有多少延迟SELECT
?也许只有1ms。 'user' post 和 'blog' 可以多快到达下一页并找到它 "missing"?可能超过 100 毫秒。
您的压力测试发现需要SET
,而不是 Galera 'broken'。