【问题标题】:MySQL Stored Procedure Read Replica Issue - Strange Stored Procedure/Function BehaviorMySQL 存储过程只读副本问题 - 奇怪的存储过程/函数行为
【发布时间】:2022-11-18 03:05:45
【问题描述】:

更新 11.15.2022

我进行了广泛的测试并在这里找到了问题的模式。再一次,奇怪的是,只有将函数作为参数传递给原始存储过程时才会发生这种情况;传递硬编码值或变量就可以了。

问题是当存储过程调用另一个存储过程时检查@@read_only 以查看它是否可以写入数据库。我确认删除任何写入数据的代码都解决了这个问题——所以最终它似乎将 STATIC 值传递给 SP 导致过程执行绕过任何写入(如预期的那样),因为 IF @@read_only = FALSE THEN ...write ...

似乎传递一个函数以某种方式导致 MySQL 编译调用和子调用的“树”以查看它们是否可以写入而不是是否写入。

解决这个问题的唯一方法似乎是将参数作为变量而不是函数调用传递。我们可以做到这一点,但它需要大量的重构。

我只是想知道为什么 MySQL 会这样做——为什么传递一个函数会导致系统向前看并查看它是否可以写入而不是是否可以写入。


我们有一个正常运行的只读副本。我们可以毫无问题地对其执行读取。

我们做得到:

CALL get_table_data(1, 1, "SELECT * from PERSON where ID=1;", @out_result, @out_result_value); 

它执行得很好。请注意,它带有 READS SQL DATA 标记。它没有写出任何东西。

我们也可以这样做:

SELECT get_value("OBJECT_BASE", "NAME");

这是只读的 SELECT 函数。

但是,如果我们尝试执行此操作:

CALL get_table_data(1, get_value("OBJECT_BASE", "NAME"), "SELECT * from PERSON where ID=1;", @out_result, @out_result_value); 

我们得到错误:

Error: ER_OPTION_PREVENTS_STATEMENT: The MySQL server is running with the --read-only option so it cannot execute this statement

我们对可能导致这种情况的原因感到困惑。 SP 和函数都是只读的,可以单独执行,但是当我们将函数结果嵌入到 SP 的调用中时,系统会阻塞。

有任何想法吗?

【问题讨论】:

  • 我在本地实例上测试了 MySQL 8.0.31,但没有收到错误。我想这是 AWS RDS 特有的东西。我建议您向 AWS 开一张支持票。
  • 谢谢@BillKarwin,我在 AWS 开了一张票。我会让你知道他们怎么说!
  • 嘿@BillKarwin。 AWS 无法弄清楚 LOL 上发生了什么。我开始怀疑这是否是 MySQL 错误。如前所述,它仅在我们在主调用中使用函数调用(仅读取数据库值)时发生,但是当我们对数字进行硬编码时它可以正常工作。让我想知道当函数用作存储过程的参数时是否有一些奇怪的设置写入日志?
  • 不,MySQL 不会那样做。首先它调用函数,获取结果,然后将该值用作过程的参数。就像您使用任何其他表达式作为函数的参数一样。正如我所说,我在我自己的本地 MySQL 实例上测试了您的代码,没有出现任何错误。 AWS support 没用我并不感到惊讶,这似乎是每个人的经验。
  • @BillKarwin AWS 仍在调查中。当我们使用任何函数调用 RR 上的任何存储过程时,就会发生此问题。我会让你知道他们想出了什么,但我的团队被难住了。

标签: mysql amazon-rds read-replication


【解决方案1】:

所以 AWS 无法解决这个问题。只有当一个函数作为参数传递给一个存储过程时,该存储过程调用另一个存储过程(甚至不传递函数的值),该存储过程在执行 INSERT 或 UPDATE 之前进行 @@read_only 检查时才会发生此问题。因此,出于某种原因,系统会在传递函数时对变量或硬编码值进行预扫描检查。

解决方法是将函数值作为变量传递。

我将向 Oracle 报告此问题,因为它可能是某种错误,特别是考虑到函数是确定性的。

【讨论】:

    猜你喜欢
    • 2015-09-03
    • 1970-01-01
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    • 2013-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多