Oracle表空间突变READ ONLY大概率是人为误执行ALTER TABLESPACE ... READ ONLY或底层文件系统被内核强制remount为ro所致;需优先查审计日志、dmesg错误及数据文件状态,而非直接尝试切换。
oracle表空间突然变成 read only,大概率不是数据库自己“想通了”,而是被强制切过去的——要么是人手抖执行了 alter tablespace ... read only,要么是底层磁盘/文件系统出了问题,触发了保护性只读挂载。
检查是否有人为执行过 READ ONLY 操作
DBA 或脚本误执行 ALTER TABLESPACE ... READ ONLY 是最常见原因,尤其在批量维护或自动化脚本中漏掉条件判断时。关键点在于:这个操作不需要重启、不报错、立刻生效,但后续 DML 就会炸出 ORA-00372。
- 查最近 24 小时的审计日志(如果开启):
SELECT timestamp, sql_text FROM dba_audit_trail WHERE sql_text LIKE '%READ%ONLY%' AND timestamp > SYSDATE - 1; - 没开审计?直接查
v$transaction和v$session关联,看有没有长时间未提交的事务卡在表空间上——因为READ ONLY要求无活动事务,强行执行会等或报错,但日志里可能留痕 - 重点盯紧运维平台、CI/CD 流水线、备份脚本里是否硬编码了该语句;有些“一键归档脚本”会在迁移后顺手把旧表空间设为只读,但忘了加确认逻辑
确认底层文件系统是否被内核设为只读(ro)
Oracle 数据文件所在的文件系统如果因 I/O 错误被 Linux 内核自动 remount 成 ro,Oracle 会感知不到“挂载状态变化”,但打开数据文件时会失败,最终表现为表空间无法写入,甚至 ALTER TABLESPACE ... READ WRITE 报 ORA-01122 或 ORA-01110。
- 立刻执行
mount | grep $(df . | tail -1 | awk '{print $1}'),看目标挂载点是否含ro选项 - 跑
dmesg -T | tail -50 | grep -i "buffer\|error\|fail\|ext4\|xfs",找类似end_request: I/O error或journal has been aborted的线索 - 别急着
remount,rw—— 如果smartctl -a /dev/sdX显示 Reallocated_Sector_Ct > 0 或 Current_Pending_Sector 非零,说明磁盘已开始掉渣,强制重挂可能让 Oracle 写坏块
验证表空间是否真处于 READ ONLY 状态(而非假象)
有时候 dba_tablespaces.status 显示 READ ONLY,但其实是数据文件 offline 或损坏导致 Oracle 无法校验状态,不能直接信。
- 查真实状态:
SELECT tablespace_name, status, plugged_in FROM dba_tablespaces WHERE tablespace_name = 'YOUR_TS';—— 注意plugged_in = 'YES'才代表是正常导入/插拔的只读表空间 - 看数据文件是否 online:
SELECT file_name, status, enabled FROM dba_data_files WHERE tablespace_name = 'YOUR_TS';,如果status = 'OFFLINE'或enabled = 'DISABLED',那不是只读,是废了 - 运行
SELECT name, checkpoint_change# FROM v$datafile WHERE name LIKE '%your_ts%';,对比其他读写表空间的checkpoint_change#—— 如果长期不动,基本坐实只读;如果乱跳但 DML 失败,大概率是文件系统 ro 导致 checkpoint 写不进头块
备库 OPEN_MODE 是 READ ONLY 而非 READ ONLY WITH APPLY
这不是表空间问题,但现象高度相似:应用进程(MRP)没起来,看起来“只读”,实际是归档没跟上或 SRL 缺失。容易和主库只读表空间混淆。
- 先确认 MRP 是否在跑:
SELECT process, status, sequence# FROM v$managed_standby WHERE process = 'MRP0';,空结果或STATUS = 'WAIT_FOR_LOG'就是卡住了 - 查
v$archive_gap,有记录说明归档断了;查v$standby_log,STATUS全是UNASSIGNED或INVALID就是 SRL 没配好 - 最关键的一步:看
alert.log里有没有ORA-00313(找不到当前日志)、ORA-16038(归档失败)、ORA-19504(SRL 创建失败)—— 这些错误不会直接说“MRP 没启”,但它们是根因
真正麻烦的是那种“磁盘轻微故障 + 人为脚本叠加”的组合:比如某次巡检脚本发现 I/O 延迟高,自动执行了 ALTER TABLESPACE ... READ ONLY,然后磁盘又真坏了,再想切回去就死循环报错。这时候得先停脚本、查 dmesg、换磁盘,再谈恢复——状态本身只是症状,不是病灶。











