Oracle双库部署
部署oracle-db1和oracle-db2双库,核心原因只有一个:Oracle XE版本存在单库12GB容量限制。
本文涉及的业务数据量较大(如单表数据量可达3600多万行),单库12GB容量无法满足所有数据的存储需求,会出现"超过最大允许数据库大小"的报错(如ORA-12954),导致数据无法完整导入。
因此,通过建立双库(oracle-db1、oracle-db2),将数据分流存储到两个独立数据库中,分别占用各自12GB的容量,从而规避单库容量限制,确保所有业务数据都能正常导入、存储和使用,保障业务正常运行。
一、建库步骤
step1. 镜像拉取
拉取Oracle镜像(部署用)
bash
sudo docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/gvenzl/oracle-xe:21-full
验证镜像拉取成功
bash
sudo docker images | grep oracle-xe
3. 容器创建(核心,数据永久化)
创建oracle-db1容器(1521端口,数据永久化)
bash
sudo docker run -d \
--name oracle-db1 \
--restart=always \
-p 1521:1521 \
-e ORACLE_PASSWORD=Oracle123 \
-v oracle-data-db1:/opt/oracle/oradata \
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/gvenzl/oracle-xe:21-full
创建oracle-db2容器(1522端口,数据永久化)
bash
sudo docker run -d \
--name oracle-db2 \
--restart=always \
-p 1522:1521 \
-e ORACLE_PASSWORD=Oracle123 \
-v oracle-data-db2:/opt/oracle/oradata \
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/gvenzl/oracle-xe:21-full
说明:通过 -v 挂载数据卷,实现数据永久化,重启容器、服务器数据不丢失,双库分别使用1521、1522端口,规避容量限制。
step2. 容器管理
查看所有容器(运行+停止)
bash
sudo docker ps -a
启动/停止db1/db2容器
bash
sudo docker start oracle-db1
sudo docker stop oracle-db1
sudo docker start oracle-db2
sudo docker stop oracle-db2
删除无用容器(如旧的oracle-new)
bash
sudo docker stop oracle-new
sudo docker rm oracle-new
step3. 数据库用户创建(db1/db2通用)
进入SQL命令行(以db1为例)
bash
sudo docker exec -it oracle-db1 sqlplus system/Oracle123@//localhost:1521/XEPDB1
执行以下SQL(仅需1次,数据永久保存)
sql
ALTER SESSION SET CONTAINER = XEPDB1;
-- 创建表空间(永久化存储)
CREATE TABLESPACE TBS_EHR
DATAFILE '/opt/oracle/oradata/XE/XEPDB1/TBS_EHR.dbf'
SIZE 100M
AUTOEXTEND ON NEXT 100M MAXSIZE UNLIMITED;
-- 创建业务用户(永久生效)
CREATE USER XZ_EHR
IDENTIFIED BY XZ_EHR123
DEFAULT TABLESPACE TBS_EHR
TEMPORARY TABLESPACE TEMP;
-- 授权(永久生效)
GRANT DBA TO XZ_EHR;
GRANT UNLIMITED TABLESPACE TO XZ_EHR;
ALTER USER XZ_EHR ACCOUNT UNLOCK;
退出SQL命令行
bash
exit
step4. DMP导入通用模板
导入到db1
bash
sudo docker cp 文件名.dmp oracle-db1:/opt/oracle/
sudo docker exec -it oracle-db1 bash
imp system/Oracle123@//localhost:1521/XEPDB1 file=/opt/oracle/文件名.dmp fromuser=XZ_EHR touser=XZ_EHR ignore=y
导入到db2
bash
sudo docker cp 文件名.dmp oracle-db2:/opt/oracle/
sudo docker exec -it oracle-db2 bash
imp system/Oracle123@//localhost:1521/XEPDB1 file=/opt/oracle/文件名.dmp fromuser=XZ_EHR touser=XZ_EHR ignore=y
====================================================================================================
二、容器名称冲突报错(创建oracle-db1时)
- 报错信息
docker: Error response from daemon: Conflict. The container name "oracle-db1" is already in use by container "xxxxxxx". You have to remove (or rename) that container to be able to reuse that name. - 报错原因
系统中已存在名为"oracle-db1"的容器,无法重复创建同名容器。 - 解决办法及完整命令
停止并删除旧容器,清理无用资源后,重新创建新容器(数据永久化):
1. 停止旧的oracle-db1容器
bash
sudo docker stop oracle-db1
2. 删除旧的oracle-db1容器(彻底清理)
bash
sudo docker rm oracle-db1
3. 清理Docker无用资源(容器、镜像等)
bash
sudo docker system prune -f
4. 重新创建oracle-db1(1521端口,数据永久化)
bash
sudo docker run -d \
--name oracle-db1 \
--restart=always \
-p 1521:1521 \
-e ORACLE_PASSWORD=Oracle123 \
-v oracle-data-db1:/opt/oracle/oradata \
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/gvenzl/oracle-xe:21-full
5. 重新创建oracle-db2(1522端口,数据永久化)
bash
sudo docker run -d \
--name oracle-db2 \
--restart=always \
-p 1522:1521 \
-e ORACLE_PASSWORD=Oracle123 \
-v oracle-data-db2:/opt/oracle/oradata \
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/gvenzl/oracle-xe:21-full
6. 检查容器是否正常运行
bash
sudo docker ps
说明:通过 -v oracle-data-db1:/opt/oracle/oradata 挂载数据卷,实现数据永久化,重启容器、服务器,数据均不丢失,无需重复建库。
三、SQL命令行连接报错(连接oracle-db2时)
- 报错信息
ERROR: ORA-12541: TNS:no listener - 报错原因
混淆容器内外端口:容器外部连接db2用1522端口,但容器内部Oracle服务默认监听1521端口,用1522端口连接容器内部会失败。 - 解决办法及完整命令
容器内部统一用1521端口连接,外部连接区分1521(db1)/1522(db2)端口:
进入oracle-db1 SQL命令行(1521端口)
bash
sudo docker exec -it oracle-db1 sqlplus system/Oracle123@//localhost:1521/XEPDB1
进入oracle-db2 SQL命令行(核心:用1521端口)
bash
sudo docker exec -it oracle-db2 sqlplus system/Oracle123@//localhost:1521/XEPDB1
补充:db1/db2通用SQL命令行进入方式
db1进入命令
bash
sudo docker exec -it oracle-db1 sqlplus system/Oracle123@//localhost:1521/XEPDB1
db2进入命令
sudo docker exec -it oracle-db2 sqlplus system/Oracle123@//localhost:1521/XEPDB1
四、DMP文件导入报错(超过12GB限制)
- 报错信息
IMP-00017: following statement failed with ORACLE error 12954:
ORA-12954: The request exceeds the maximum allowed database size of 12 GB. - 报错原因
Oracle XE版本单库有12GB容量限制,数据已塞满,导致索引无法创建(数据已导入成功)。 - 解决办法及说明
无需额外操作,数据已完整导入,可正常使用,仅索引未创建(不影响查询、不影响ShinyProxy连接),验证命令如下:
进入对应数据库SQL命令行(以db2为例)
bash
sudo docker exec -it oracle-db2 sqlplus XZ_EHR/XZ_EHR123@//localhost:1521/XEPDB1
验证数据是否导入成功
sql
SELECT COUNT(*) FROM 表名; -- 替换为具体表名(如V_TEST_RESULT_RECORD)
退出SQL命令行
exit
五、DMP文件导入报错(文件损坏/不完整)
- 报错信息
IMP-00009: abnormal end of export file
IMP-00028: partial import of previous table rolled back: 3213014 rows rolled back
- 报错原因
DMP文件未完整复制到容器,导致文件损坏、截断,导入时数据回滚,表格为空。
- 解决办法及完整命令
步骤1:删除空表(以db2为例)
bash
sudo docker exec -it oracle-db2 sqlplus XZ_EHR/XZ_EHR123@//localhost:1521/XEPDB1
DROP TABLE 表名 PURGE; -- 替换为报错的表名(如V_EMR_TEST_SAMPLING_RECORD)
exit
步骤2:重新完整复制DMP文件到容器
bash
sudo docker cp 文件名.dmp oracle-db2:/opt/oracle/ -- 替换为实际DMP文件名
步骤3:重新导入
bash
sudo docker exec -it oracle-db2 bash
imp system/Oracle123@//localhost:1521/XEPDB1 file=/opt/oracle/文件名.dmp fromuser=XZ_EHR touser=XZ_EHR ignore=y
步骤4:验证导入成功
bash
sudo docker exec -it oracle-db2 sqlplus XZ_EHR/XZ_EHR123@//localhost:1521/XEPDB1
SELECT COUNT(*) FROM 表名;
bash
exit
====================================================================================================
六、关键注意事项
- 两个Oracle容器(db1/db2)均通过数据卷挂载实现数据永久化,一次建库、终身使用,无需重复操作。
- 外部连接:db1用1521端口,db2用1522端口;容器内部连接均用1521端口,不可混淆。
- DMP导入超过12GB限制时,无需处理,数据已导入成功,仅索引未创建,不影响使用。
- ShinyProxy与Oracle容器完全隔离,重启ShinyProxy不影响数据库数据和配置。
- 所有命令可直接复制执行,无需修改,适配CSDN编辑器排版,粘贴后可直接发布。