Oracle 23ai 容器版默认不持久化,/opt/oracle/oradata 必须挂载为宿主机绝对路径目录并由 UID 54321 拥有,否则容器启动失败或数据丢失;挂载错误将导致初始化新库覆盖原有数据。

Oracle 23ai 容器版默认不持久化,/opt/oracle/oradata 必须挂载为宿主机目录
Oracle 23ai 官方提供的容器镜像(如 container-registry.oracle.com/database/free:23.0.0)在启动时若未显式挂载数据卷,所有数据库文件(包括控制文件、redo、undo、SYSTEM 表空间等)都会写入容器临时文件系统。容器重启或删除后,数据立即丢失。
关键点是:容器内数据库实例默认使用 /opt/oracle/oradata/FREE 作为数据文件根路径,这个路径必须映射到宿主机上一个**真实、可写、有足够空间且权限正确的目录**。
- 宿主机目录需由
oracle用户(UID 54321)拥有,否则容器启动失败并报错ORA-01078: failure in processing system parameters或permission denied - 推荐用
chown -R 54321:54321 /path/to/host/oradata设置属主,而非依赖--user参数绕过权限检查(后者可能导致监听器或后台进程异常) - 不要挂载为 NFS 或某些 FUSE 文件系统(如 sshfs),Oracle 23ai 对文件锁和 direct I/O 敏感,易触发
ORA-27091: unable to queue I/O
docker run 启动时必须指定 -v 并确保 ORACLE_SID=FREE
Oracle 23ai Free 镜像硬编码了数据库名为 FREE,其数据目录结构严格对应 /opt/oracle/oradata/FREE。若挂载路径不匹配或 SID 不一致,容器会初始化新库,覆盖已有数据。
正确命令示例:
docker run -d \ --name orcl23ai \ -p 1521:1521 \ -e ORACLE_PDB=FREEPDB1 \ -e ORACLE_PASSWORD=MyPass123 \ -v /mnt/oradata:/opt/oracle/oradata \ -v /mnt/diag:/opt/oracle/diag \ oracle/database:free
-
-v /mnt/oradata:/opt/oracle/oradata是核心,它让容器内/opt/oracle/oradata/FREE实际落在宿主机/mnt/oradata/FREE -
ORACLE_PDB只影响 PDB 名称,不影响 CDB 数据文件位置;但若省略,部分镜像版本可能跳过 PDB 创建,导致连接FREEPDB1失败 - 务必确认宿主机
/mnt/oradata已存在且权限正确,否则容器日志中会出现chown: cannot access '/opt/oracle/oradata': No such file or directory
使用 docker-compose.yml 时,volumes 路径不能用相对路径或 ./
Compose 文件里若写 ./oradata:/opt/oracle/oradata,Docker 会将其解析为相对于 docker-compose.yml 所在目录的路径,极易因执行位置不同而挂载错目录,造成“数据看似存在,实则写到别处”。
更隐蔽的问题是:Compose 默认以 root 运行 chown,但 Oracle 镜像启动脚本内部仍会尝试以 UID 54321 检查 /opt/oracle/oradata 权限,若宿主机目录属主不是 54321,容器反复重启。
- 始终使用绝对路径,例如
/data/oracle23ai/oradata:/opt/oracle/oradata - 在
docker-compose.yml中添加user: "54321:54321"无效——镜像启动逻辑不认该字段,它只认挂载目录本身的属主 - 启动前手动执行
mkdir -p /data/oracle23ai/oradata && chown -R 54321:54321 /data/oracle23ai/oradata是最稳妥做法
验证持久化是否生效:删容器后重建,检查 FREE 目录下文件时间戳和内容
仅看容器能启动、SQL*Plus 能连上,并不能证明数据已持久化。真正有效的验证方式是模拟故障场景。
- 先创建一张测试表并插入数据:
CREATE TABLE t_test AS SELECT * FROM dual; - 停并删容器:
docker stop orcl23ai && docker rm orcl23ai - 用完全相同的
docker run命令重新启动容器 - 进入容器执行:
sqlplus / as sysdba @/tmp/check.sql,其中check.sql包含SELECT COUNT(*) FROM t_test; - 若返回 1,则持久化成功;若报
ORA-00942: table or view does not exist,说明挂载路径没对上或目录为空
最容易被忽略的是:Oracle 23ai 容器首次启动时会检测 /opt/oracle/oradata/FREE 是否为空。非空即跳过初始化,直接加载现有库;但若你误将宿主机目录挂到了 /opt/oracle/oradata 的子目录(比如 /opt/oracle/oradata/mydb),容器看到的是空的 /opt/oracle/oradata/FREE,就会重建全新库,原有数据彻底不可见。


















