ORA-16001: Database Already Open for Read-Only Access
ORA-16001 is an Oracle error that occurs when you attempt a write operation or try to change the open mode of a database that is already open in Read-Only mode. This error is most commonly encountered in Oracle Data Guard environments where a Physical Standby database is operating in Read-Only or Active Data Guard mode. Understanding the current database state before executing any commands is the key to resolving and preventing this error.
Top 3 Causes
1. Attempting Writes on a Data Guard Standby Database
The most frequent cause is trying to perform DML or DDL operations directly on a Physical Standby database that is open in Read-Only mode. Automation scripts that don't differentiate between Primary and Standby databases often trigger this error.
-- Check current database role and open mode first
SELECT NAME, OPEN_MODE, DATABASE_ROLE, DB_UNIQUE_NAME
FROM V$DATABASE;
-- Expected output on a Standby:
-- OPEN_MODE = READ ONLY
-- DATABASE_ROLE = PHYSICAL STANDBY
2. Attempting to Re-Open an Already Open Read-Only Database
Executing ALTER DATABASE OPEN or ALTER DATABASE OPEN READ WRITE on a database that is already open in Read-Only mode without first closing it will trigger ORA-16001. Oracle does not allow an in-place mode transition without a proper shutdown and restart cycle.
-- WRONG: This will cause ORA-16001 if DB is already READ ONLY
ALTER DATABASE OPEN READ WRITE; -- ERROR if already open
-- CORRECT: Shutdown first, then reopen
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE OPEN READ WRITE;
-- Verify the change
SELECT NAME, OPEN_MODE FROM V$DATABASE;
3. Incorrect Command Sequence in Active Data Guard (ADG) Environments
In Active Data Guard setups, the Standby database runs in READ ONLY WITH APPLY mode. Running commands out of sequence — such as trying to cancel recovery and open Read-Write without a proper switchover — causes ORA-16001.
-- Check MRP (Managed Recovery Process) status
SELECT PROCESS, STATUS, SEQUENCE#
FROM V$MANAGED_STANDBY
WHERE PROCESS = 'MRP0';
-- Correct sequence to restart Managed Recovery
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
ALTER DATABASE OPEN READ ONLY;
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE
USING CURRENT LOGFILE DISCONNECT;
-- Verify
SELECT OPEN_MODE, DATABASE_ROLE FROM V$DATABASE;
Quick Fix Solutions
Fix 1 — Perform a Switchover (Data Guard)
-- On PRIMARY: Verify switchover readiness
SELECT SWITCHOVER_STATUS FROM V$DATABASE;
-- Should show 'TO STANDBY'
-- On PRIMARY: Initiate switchover
ALTER DATABASE COMMIT TO SWITCHOVER TO PHYSICAL STANDBY
WITH SESSION SHUTDOWN;
-- On new PRIMARY (former Standby):
ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY
WITH SESSION SHUTDOWN;
ALTER DATABASE OPEN;
-- On new STANDBY: Resume Managed Recovery
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE
DISCONNECT FROM SESSION;
Fix 2 — Pre-check Script to Avoid the Error
DECLARE
v_open_mode VARCHAR2(20);
v_role VARCHAR2(30);
BEGIN
SELECT OPEN_MODE, DATABASE_ROLE
INTO v_open_mode, v_role
FROM V$DATABASE;
IF v_open_mode = 'READ ONLY' THEN
RAISE_APPLICATION_ERROR(-20001,
'ERROR: DB is READ ONLY. Role: ' || v_role ||
'. Writes are not allowed.');
END IF;
DBMS_OUTPUT.PUT_LINE('OK: ' || v_open_mode || ' | ' || v_role);
END;
/
Prevention Tips
Always validate database state before running any scripts. Add a state-check block at the beginning of every automation or deployment script to detect Read-Only mode early and halt execution gracefully.
Use Role-Based Services in Data Guard to ensure applications automatically connect to the correct database based on its current role (Primary vs. Standby), preventing accidental write attempts on a Read-Only Standby.
-- Create a Read-Write service for Primary only
EXECUTE DBMS_SERVICE.CREATE_SERVICE(
service_name => 'APP_RW',
network_name => 'APP_RW');
-- Verify active services
SELECT NAME, NETWORK_NAME FROM DBA_SERVICES;
Related Oracle Errors
| Error Code | Description |
|---|---|
| ORA-16000 | DB open for read-only access (informational) |
| ORA-01109 | Database not open |
| ORA-01507 | Database not mounted |
| ORA-10456 | Cannot open standby database; media recovery active |
| ORA-16014 | Log cannot be archived; no available destinations |
📖 Want a more detailed guide?
Check out the full in-depth version (Korean) on oraerror.com — includes detailed analysis, additional SQL examples, and prevention tips.
Top comments (0)