带有 PHP PDO 的只读副本上的 MySQL 存储过程

Posted

技术标签:

【中文标题】带有 PHP PDO 的只读副本上的 MySQL 存储过程【英文标题】:MySQL stored procedure on a read replica with PHP PDO 【发布时间】:2013-11-10 16:47:59 【问题描述】:

我打开了针对 mysql http://bugs.mysql.com/bug.php?id=70793&thanks=4 的错误报告。 这里有一个代码示例演示了这个错误。我还发现错误报告中包含了一种解决方法。此解决方法适用于 PHP 和控制台

我在存储过程和 PHP PDO 方面遇到了一个奇怪的问题。

我不允许发布存储过程的主体,但我可以提供以下信息。

当使用 PHP PDO 共享的同一用户从控制台访问只读副本时,它可以正常工作 -- 编辑:我在这里的初始报告部分不正确,如果临时表存在,存储过程将起作用,如果临时表在控制台和 pdo 环境中都不存在,则存储过程将失败。有关详细信息,请参阅链接到 MySQL 的错误报告。 我已验证我在两个地方使用的是同一个用户。 它执行的唯一写入活动是在临时表中 它确实使用了光标 主副本和副本都运行 MySQL 5.5.27 MySQL 服务器在 AWS RDS 上进行管理;我有一个带有标准配置的参数组。

我的问题是我无法从 PHP PDO 调用此存储过程,我收到此错误

SQLSTATE[HY000]: 一般错误: 1290 MySQL 服务器使用 --read-only 选项运行,因此无法执行此语句

这完全没有意义,因为我可以在只读副本上调用它,只要我不是从 PHP 中调用它。

谁能解释一下这里可能发生了什么?

编辑更多离奇信息

我可以让控制台会话失败,但我也可以让它成功。这取决于存储过程使用的临时表是否已经创建。所以让我解释一下我的工作和失败用例

失败

    在控制台登录服务器 尝试调用存储过程 失败The MySQL server is running with the --read-only option so it cannot execute this statement

通过

    在控制台登录服务器 创建临时表 尝试调用存储过程 成功

更奇怪的是,我肯定会在存储过程中删除该临时表并重新创建它(如果存在)。

我有理由确定此时我们正在查看 MySQL 错误

【问题讨论】:

可能在控制台上您正在使用 root@'' 连接,而在 php 中使用 root@'localhost' ...这似乎是一个用户问题 在 mysql cli 上使用 select current_user() @RobertRozas 我对控制台和 PHP PDO 使用完全相同的用户。也不是root。 你是否在 mysql cli 上检查了用户:select current_user() ?? @RobertRozas 是的,我已经通过select current_user() 确认用户是相同的 【参考方案1】:

--read-only 仅适用于非 root 或非副本用户。因此,来自控制台的 ROOT 仍然可以做任何事情,但 PHP 用户不能。

【讨论】:

【参考方案2】:

您是否尝试将 TEMPORARY 关键字添加到 DROP TABLE command?

TEMPORARY 关键字具有以下效果:

该语句仅删除 TEMPORARY 表。 该语句不会结束正在进行的事务。 没有检查访问权限。 (一个临时的 表只对创建它的会话可见,所以没有检查 必要。)

【讨论】:

很棒的收获!谢谢楼主

以上是关于带有 PHP PDO 的只读副本上的 MySQL 存储过程的主要内容,如果未能解决你的问题,请参考以下文章

PHP 7.0 上的 Laravel 5.4:PDO 异常 - 找不到驱动程序 (MySQL)

表上的 PHP PDO 查询错误具有 json 数据类型(MySQL 5.7.8-rc)

如何在 PHP 中使用带有 PDO 的 MySQL 用户函数?

带有 PDO::MYSQL_ATTR_MAX_BUFFER_SIZE 的 PHP 中的致命错误

使用带有 --ssl 的 PHP PDO 连接到 MySQL/MariaDB,无需证书

带有条件检查的 PHP MySQL PDO TextArea Where 子句