MySQL报错“Table is read only”本质是实例级或系统级只读限制,非表本身只读;需依次检查global.read_only/super_read_only变量、磁盘是否只读或满、配置文件残留设置、InnoDB引擎只读状态及会话级只读参数。

phpEnv 环境下报 MySQL table is read only,大概率不是表本身只读,而是 MySQL 实例被设为全局只读模式,或底层存储层(如磁盘)已只读 —— 直接查 read_only 和 super_read_only 就能定位。
确认是否开启了全局只读模式
phpEnv 用的是本地 MySQL 实例,常见误操作是手动执行过 SET GLOBAL read_only = ON,或者配置文件里写了 read_only=1。这种设置会让所有普通账号的写操作失败,报错看起来像“表只读”,其实是实例级拦截。
- 用 root 连进 MySQL 执行:
SELECT @@global.read_only, @@global.super_read_only;,两个值都为OFF才安全 - 如果
read_only是ON,运行SET GLOBAL read_only = OFF;(需 SUPER 权限) - 如果
super_read_only是ON,必须先关它:SET GLOBAL super_read_only = OFF;,否则read_only设为OFF也会被拒绝 - 检查
my.ini(Windows)或my.cnf(Linux/macOS)里有没有残留的read_only=1或super_read_only=1,删掉并重启 MySQL 服务
检查磁盘或文件系统是否只读
phpEnv 装在本地,容易因磁盘满、异常断电或手动挂载错误导致数据目录所在分区变成只读。这时 MySQL 自动切为只读保护状态,read_only 变量可能仍是 OFF,但任何写操作都会触发 table is read only 类错误。
- 在命令行运行
df -h(Linux/macOS)或dir C:\(Windows)看 MySQL 数据目录所在盘是否已满(>95%) - 查 MySQL 错误日志,路径通常是
phpEnv\MySQL\data\*.err,搜索关键词read-only filesystem或no space left on device - Windows 下若看到
The system cannot open the device or file specified.,可能是 NTFS 权限丢失,右键数据目录 → 属性 → 安全 → 编辑 → 给 MySQL 服务账户(如SYSTEM或mysql用户)加“完全控制”
JDBC 或 PHP 连接串触发的会话只读
如果你在 phpEnv 里跑的是 Java 应用(比如用 MyCat 做读写分离),或 PHP 用了某些 ORM(如 Laravel 配置了 strict 模式),连接建立时可能自动发了 SET SESSION tx_read_only = 1,导致单个会话不可写。
立即学习“PHP免费学习笔记(深入)”;
- 检查 JDBC URL 是否带了
useLocalSessionState=true—— 这个参数不加的话,驱动每次执行前会查@@session.tx_read_only,而某些代理(如 MyCat)返回假只读状态,引发误判 - PHP 中用
mysqli或PDO连接后,可手动执行mysqli_query($conn, "SET SESSION tx_read_only = 0");强制解除 - 避免在应用代码里调用
mysqli::begin_transaction(MYSQLI_TRANS_START_READ_ONLY),这个会显式开启只读事务
别漏掉 InnoDB 存储引擎的只读开关
极少数情况下,InnoDB 引擎自身被设为只读,影响所有 InnoDB 表。这和权限、配置无关,是引擎级硬限制。
- 执行
SHOW VARIABLES LIKE 'innodb_read_only';,若返回ON,说明整个 InnoDB 子系统被锁死 - 恢复方式只有:停止 MySQL → 删除
ib_logfile*和ibdata1(⚠️危险!仅限测试环境且无重要数据)→ 启动 MySQL 重建 - 更稳妥的做法是检查 MySQL 启动参数,确保没传
--innodb-read-only;phpEnv 默认不会加这个,除非你改过启动脚本
真正麻烦的不是 read_only 开关本身,而是它常和磁盘只读、super_read_only、JDBC 会话状态三者嵌套出现。比如磁盘满了 → MySQL 自动开 read_only → 你关了 read_only 却没清磁盘 → 重启后立刻又变只读。顺序查、逐层排除,比反复试命令更省时间。



















