奇怪的MySQL“只读”错误

时间:2016-02-16 23:39:21

标签: mysql database debian

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

  

错误:500 - SQLSTATE [HY000]:一般错误:1290 MySQL服务器是   使用--read-only选项运行,因此无法执行此操作   声明

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

  • 在互联网上找到并阅读相关信息(一些指向MySQL的read-only标志);
  • 基于以上所述,试图在MySQL配置中找到read-only标志。文件(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
  • 最后,我决定在问题存在期间和临时修复(数据库重启)之后拍摄与MySQL相关的进程(ps ax | grep 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)

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

9 个答案:

答案 0 :(得分:9)

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

1)MySQL将自己设置为只读

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

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

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

container = deque(digits[:13], maxlen=13)
current_product = reduce(mul, map(int, container))
print cal_max_prod(container, current_product)
5576689664895

但要执行此操作,用户必须具有SET GLOBAL read_only = ON; 权限。使用MySQL的网站,应用程序等不需要此权限 - 仅保留用于管理数据库的管理员帐户。

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

答案 1 :(得分:3)

如果您使用的是AWS Aurora,请you might be accessing the replica instance which is read-only,因此您需要使用数据库集群终端节点。

答案 2 :(得分:1)

基于我的问题的评论(特别感谢@Eborbob)和我的更新,我发现系统中的某些进程会将read-only标记重置为ON (1),这似乎会引发问题,导致网站无法访问。为了解决问题以及在软件和服务器重新启动时修复 persistent ,我决定更新MySQL配置文件my.cnf并重新启动数据库服务器。

在对配置文件

进行相关更新(在我的情况下,添加)之后
read_only=0

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

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

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

service mysql stop
service mysql start

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

答案 3 :(得分:1)

我刚刚遇到了同样的错误并通过连接到mysql服务器的主机名而不是IP地址来修复它。我不确定为什么要修复它,但确实如此。仅供参考

答案 4 :(得分:0)

Eborbob说它可能是客户,

您是否检查了备份工具?

您是否使用某些SQL代理(例如proxySQL或maxscale)? 例如,Mascale可以通过监视https://jira.mariadb.org/browse/MXS-1859

来强制执行只读操作

Replication Manager也可以更改READ ONLY标志

答案 5 :(得分:0)

以下错误:- MySQL服务器正在使用--read-only选项运行,因此它无法执行该语句

当不具有sql数据库写权限的用户尝试向数据库中插入/更新某些数据时,就会发生这种情况。

这是一个非常有效的安全错误,因为它表明您当前仅具有-只读权限,因此无法执行与写操作有关的查询。

要解决此错误:- 从DBA获得写访问权限。

例如

GRANT ALL PRIVILEGES ON database.table TO 'user'@'localhost';

上面的查询将授予用户名'user'的用户所有特权。

答案 6 :(得分:0)

设置全局read_only =关闭; 稍后将其设为只读模式将可以正常工作。

答案 7 :(得分:0)

这对我有用,您可以尝试。

备份.sql文件(更改查询)

查找所有Engine=InnoDB 并将它们替换为Engine=MyISAM

然后尝试再次执行。

答案 8 :(得分:0)

与该问题无关,但与错误“ mysql只读”有关。

确保您不尝试向mysql的从属实例中写入内容。