奇怪的MySQL"只读"错误

Ale*_*ekh 16 mysql database debian

我遇到了一个奇怪的MySQL错误,似乎与数据库的read-only标志有关.使用MySQL的Web应用程序在Debian 7.9上运行.它运行良好数周,如果不是更多,而突然,尝试访问应用程序驱动的网站开始在空白网页上产生以下错误消息:

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

以下是我在调查过程中执行的步骤:

  • 在互联网上找到并阅读相关信息(一些指向MySQL的read-only标志);
  • 基于以上所述,试图read-only在MySQL配置中找到标志.file(my.cnf) - 找不到它,但是读到该标志的默认值仍为OFF;
  • 验证了文件系统以确保有足够的磁盘空间(df -h): Filesystem Size Used Avail Use% Mounted on udev 10M 0 10M 0% /dev tmpfs 3.2G 1.4M 3.2G 1% /run /dev/disk/by-uuid/xxxxxxxxxxxxxxxxx 113G 14G 94G 13% / tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 7.3G 72K 7.3G 1% /run/shm

  • mysqlcheck --all-databases:所有的桌子都没事;

  • 验证服务器上有足够的RAM可用(free): total used free shared buffers cached Mem: 32898332 2090268 30808064 0 425436 970348 -/+ buffers/cache: 694484 32203848 Swap: 5105660 0 5105660
  • 最后,我决定ps ax | grep mysql在问题存在期间和临时修复(数据库重启)之后拍摄与MySQL相关的进程()的"快照" ,希望它可以为人们提供额外的想法背景; 这是相应的结果:

    问题: 20307 ? S 0:00 /bin/sh /usr/bin/mysqld_safe 20635 ? Sl 0:37 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib/mysql/plugin --user=mysql --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/run/mysqld/mysqld.sock --port=3306 20636 ? S 0:00 logger -t mysqld -p daemon.error 36427 pts/0 S+ 0:00 grep mysql

    没问题: 36948 pts/0 S 0:00 /bin/sh /usr/bin/mysqld_safe 37275 pts/0 Sl 0:00 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib/mysql/plugin --user=mysql --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/run/mysqld/mysqld.sock --port=3306 37276 pts/0 S 0:00 logger -t mysqld -p daemon.error 38313 pts/0 S+ 0:00 grep mysql

更新:

我刚刚再次遇到这个问题,并决定检查全局只读标志是否设置为OFF,假设后者.我的假设已经证实:

mysql> SELECT @@global.read_only;
+--------------------+
| @@global.read_only |
+--------------------+
|                  1 |
+--------------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

我想,尽管默认的OFF值,由于它被系统中的某个进程覆盖,我将不得不通过MySQL配置文件显式和永久地将只读标志设置为OFF.将在稍后的答案中报告结果.

Ebo*_*bob 10

正如我所看到的,将数据库设置为只读的原因有两个:

1)MySQL将自己设置为只读

我不确定什么可能导致MySQL只读,可能是磁盘问题或数据库损坏?在任何情况下,我都希望在日志中出现一些内容,因此请检查MySQL(和系统)日志.

2)客户端将数据库设置为只读

连接到MySQL的客户端可以使用以下命令设置数据库只读:

SET GLOBAL read_only = ON;
Run Code Online (Sandbox Code Playgroud)

但要执行此操作,用户必须具有SUPER权限.对于使用MySQL的网站,应用程序等,不应该需要此权限 - 仅将其保留用于管理数据库的管理员帐户.

锁定每个用户拥有的权限,以便他们只有权在适用​​的数据库/表上执行所需的操作.如果您正在使用一些开箱即用的应用程序,则应附带详细说明所需权限的说明(例如SELECT, INSERT, DELETE, UPDATE).


sas*_*alm 6

如果您使用的是AWS Aurora,则可能正在访问只读的副本实例,因此您需要使用数据库集群终端节点。

  • 我遇到了这个问题,它确实是用于主机名的 RDS 集群的只读端点。更改为 Writer 端点为我解决了这个问题。 (2认同)
  • 我正在使用集群端点,但仍然遇到相同的错误。 (2认同)

Ale*_*ekh 4

根据我的问题的评论(特别感谢@Eborbob)和我的更新,我发现系统中的某些进程将标志重置read-onlyON (1),这似乎触发了问题并导致网站无法访问。为了解决该问题并使此修复在软件和服务器重新启动后持续存在,我决定更新 MySQL 配置文件my.cnf并重新启动数据库服务器。

对配置文件进行相关更新(在我的例子中是添加)后

read_only=0
Run Code Online (Sandbox Code Playgroud)

让我们验证该标志是否确实设置为OFF (0)

# mysql
mysql> SELECT @@global.read_only;
+--------------------+
| @@global.read_only |
+--------------------+
|                  0 |
+--------------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

最后,让我们重新启动 MySQL 服务器(由于某种原因,动态重新加载MySQL 配置(/etc/init.d/mysql reload)不起作用,所以我必须显式重新启动数据库服务器:

service mysql stop
service mysql start
Run Code Online (Sandbox Code Playgroud)

瞧!现在该网站已恢复访问。如果发生任何变化,将更新我的答案。