深入探究Oracle容器环境变量与存储挂载

1. 覆盖与创建变量

在使用 docker run 命令时,为容器分配变量会覆盖镜像中的默认值。例如,当我们尝试更改 ORACLE_HOME 时,可能会导致容器启动失败。

# 示例6 - 8:覆盖容器中的ORACLE_HOME会导致问题!
> docker run -d -e ORACLE_HOME=/home/oracle --name OOPS oracle/database:19.3.0-ee
1c32eb9d016e723256e47199e5801d3bcd4cc64c87099cc40057028cd0177eba
> docker logs -f OOPS
/opt/oracle/relinkOracleBinary.sh: line 13: /home/oracle/bin/oraversion: No such file or directory
/usr/bin/ar: /home/oracle/lib/libedtn.a: No such file or directory
# 更多错误信息...

docker run 中给定的变量/值不在镜像中,Docker会将其添加到容器环境及其元数据中。以下是为 ORACLE_SID ORACLE_PDB 分配非默认值的示例:

# 示例6 - 9:使用非默认值的ORACLE_SID和ORACLE_PDB时的容器环境
> docker run -d -e ORACLE_SID=ORA19C -e ORACLE_PDB=PDB1 --name ORA19C oracle/database:19.3.0-ee
aba0514d7fb36e70777c69ca4a6b619e3fbdca1f8a13a95935fed8e48c7722c3
> docker container inspect --format '{{range .Config.Env}}{{printf "%s\n" .}}{{end}}' ORA19C | grep ORACLE
ORACLE_BASE=/opt/oracle
ORACLE_HOME=/opt/oracle/product/19c/dbhome_1
ORACLE_PDB=PDB1
ORACLE_SID=ORA19C
> docker exec -it ORA19C bash
[oracle@aba0514d7fb3 ~]$ env | grep ORACLE
ORACLE_SID=ORA19C
ORACLE_BASE=/opt/oracle
ORACLE_PDB=PDB1
ORACLE_HOME=/opt/oracle/product/19c/dbhome_1
[oracle@aba0514d7fb3 ~]$ ps -ef | grep pmon
oracle      5072       1  0 21:21 ?        00:00:00 ora_pmon_ORA19C
2. Oracle镜像中的环境选项

Oracle容器镜像仓库提供了丰富的文档,其中包含用于自定义数据库启动和创建的环境选项。以下是一些常见的环境选项:
| 选项 | 描述 | 默认值 |
| — | — | — |
| ORACLE_SID | Oracle数据库的系统标识符 | ORCLCDB |
| ORACLE_PDB | Oracle数据库的可插拔数据库名称 | ORCLPDB1 |
| ORACLE_CHARACTERSET | 数据库字符集 | AL32UTF8 |
| ORACLE_PWD | Oracle数据库SYS、SYSTEM和PDB_ADMIN的密码 | 数据库创建时随机生成 |
| ENABLE_ARCHIVELOG | 启用归档日志 | False |

此外,还有一些可选的环境选项用于管理Oracle数据库容器的内存:
- INIT_SGA_SIZE :SGA组件的总内存(MB)。
- INIT_PGA_SIZE :目标PGA总大小(MB)。
- AUTO_MEM_CALCULATION :根据容器可用内存计算总内存分配。设置为 false 时,总内存分配为2GB。当设置了 INIT_SGA_SIZE INIT_PGA_SIZE 时,此选项将被忽略,默认值为 True

3. 数据持久化的重要性

过去,许多Oracle专家对在容器中运行Oracle持怀疑态度,主要担忧之一是数据持久性。由于容器是临时的,其文件系统与容器关联,删除容器会永久删除其数据。但通过使用挂载存储,Docker可以将数据保存在容器外部,从而实现数据的持久化。删除容器不会影响外部存储的数据。

4. 容器存储

容器使用联合文件系统,它可以将本地更改投影到父镜像提供的基础文件系统上。联合文件系统使容器快速高效,多个容器可以共享同一个镜像,只需为每个容器的私有层更改分配存储空间。

graph LR
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    A(父镜像文件系统):::process --> B(联合文件系统):::process
    C(容器私有层):::process --> B
    B --> D(容器文件系统视图):::process
5. Docker内部存储

查看 /var/lib/docker 目录信息和内容的实用方法是间接的,可通过Docker CLI命令报告元数据或连接到容器并检查其文件系统。在主机和容器之间共享信息时,使用 docker cp 命令可以复制文件,但其不支持通配符,操作限于整个目录或单个文件,使用起来不太方便。

# scp和docker cp命令结构对比
scp [source file] [destination]
docker cp [source file] [destination]

# 带远程组件的命令结构
scp [host or IP address]:[source file] [destination]
docker cp [container name]:[source file] [destination]
6. 联合文件系统的缺点

联合文件系统虽然是容器的关键技术,但对于数据库而言并非理想的存储机制:
- 随着容器私有层更改的增加,联合文件系统的效率会下降,因为主机系统需要进行更多的计算来生成容器的工作视图。
- /var/lib/docker 中的层默认限于单个文件系统(通常是启动卷),数据库的容量、性能和冗余性受到该磁盘的限制,无法将活动分散到多个设备上。

7. 挂载概念

挂载可以扩展容器的存储,使其超越联合文件系统。挂载类似于网络附加存储或共享文件系统,独立于容器及其生命周期。通过挂载,容器可以:
- 使用主机上的本地存储实现数据持久化、提高性能和增加容量。
- 与主机或其他容器共享文件。
- 避免联合文件系统对易变目录的开销。
- 访问不属于其父镜像的文件和目录。
- 将数据库文件分布在多个磁盘上,提高性能、增加容量并控制冗余性。

8. 挂载类型

在创建容器时,可使用 docker run 命令的选项来附加存储,主要有两种常见的挂载类型:
- 绑定挂载(Bind Mounts) :将容器中的文件和目录映射到主机上的文件和目录,方便管理和查看。例如,可将Oracle数据库容器的 /opt/oracle/oradata 目录映射到主机上的 ~/oradata 目录。

~/oradata> du -sh ./*
1.5G     ./ORA11G
2.0G     ./ORA12C
2.9G     ./ORA19C
4.8G     ./ORA21C
  • Docker卷(Docker Volumes) :是Docker对象,用于持久化容器数据。默认存储位置为 /var/lib/docker ,但可以在本地文件系统上创建卷,还可以引用云存储等外部存储。
# 示例7 - 1:创建、列出、查看和删除卷的Docker命令示例
> docker volume create oradata
oradata
> docker volume ls
DRIVER    VOLUME NAME
local     oradata
> docker volume inspect oradata
[
    {
        "CreatedAt": "2022-01-01T12:00:00Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/oradata/_data",
        "Name": "oradata",
        "Options": {},
        "Scope": "local"
    }
]
> docker volume rm oradata
oradata

综上所述,合理使用环境变量和挂载存储可以帮助我们更好地在容器中运行Oracle数据库,提高数据的持久性、性能和可管理性。

深入探究Oracle容器环境变量与存储挂载

9. 绑定挂载与Docker卷的对比

绑定挂载和Docker卷各有特点,以下是它们的详细对比:
| 挂载类型 | 优点 | 缺点 | 适用场景 |
| — | — | — | — |
| 绑定挂载 | 方便直观,可直接使用标准Linux命令管理主机上的挂载目录;对于熟悉传统文件系统操作的用户友好 | 依赖主机文件系统结构,不同主机上可能需要调整挂载路径;在某些系统(如Windows Subsystem for Linux 2)中,挂载的可见性受创建位置影响 | 需要频繁在主机和容器间共享文件,且对挂载目录管理要求直观的场景 |
| Docker卷 | 独立于主机文件系统结构,可方便地在不同主机间迁移;可以使用云存储等外部存储,扩展性强 | 管理相对复杂,需要使用Docker命令进行操作;默认存储位置可能受主机磁盘限制 | 需要数据持久化且对数据迁移和扩展性有要求的场景 |

10. 挂载操作示例

以下是使用绑定挂载和Docker卷创建Oracle数据库容器的具体操作示例:
- 绑定挂载示例

# 创建绑定挂载目录
mkdir -p ~/oradata/ORA19C
# 使用绑定挂载创建容器
docker run -d -v ~/oradata/ORA19C:/opt/oracle/oradata -e ORACLE_SID=ORA19C --name ORA19C oracle/database:19.3.0-ee
  • Docker卷示例
# 创建Docker卷
docker volume create oradata_ora19c
# 使用Docker卷创建容器
docker run -d -v oradata_ora19c:/opt/oracle/oradata -e ORACLE_SID=ORA19C --name ORA19C oracle/database:19.3.0-ee
11. 挂载对数据库管理的影响

挂载存储对Oracle数据库的管理有着重要影响,主要体现在以下几个方面:
- 数据备份与恢复 :通过挂载存储,数据库的数据文件和日志文件可以方便地备份到主机或外部存储中。在需要恢复数据时,只需将备份文件挂载到新的容器中即可。
- 数据库升级与补丁 :在进行数据库升级或打补丁时,可以创建一个新的容器,并将原有的数据卷挂载到新容器中,避免直接在容器中进行复杂的升级操作。
- 多实例管理 :可以通过挂载不同的存储目录或卷,在同一个主机上运行多个Oracle数据库实例,方便进行多实例的管理和测试。

12. 总结与最佳实践

在容器中运行Oracle数据库时,合理使用环境变量和挂载存储是关键。以下是一些总结和最佳实践:
- 环境变量使用
- 谨慎修改像 ORACLE_HOME 这样的关键环境变量,避免因路径错误导致容器启动失败。
- 对于常用的环境变量,如 ORACLE_SID ORACLE_PDB ,可以根据实际需求进行设置,以满足不同的数据库配置。
- 挂载存储使用
- 根据具体需求选择合适的挂载类型,绑定挂载适用于需要直观管理的场景,Docker卷适用于需要数据迁移和扩展性的场景。
- 对于数据库的数据文件和日志文件,建议使用挂载存储进行持久化,以确保数据的安全性和可恢复性。
- 在进行数据库管理操作(如备份、恢复、升级等)时,充分利用挂载存储的优势,简化操作流程。

graph LR
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    A(选择挂载类型):::process --> B{绑定挂载?}:::process
    B -->|是| C(创建主机目录):::process
    B -->|否| D(创建Docker卷):::process
    C --> E(使用绑定挂载创建容器):::process
    D --> F(使用Docker卷创建容器):::process
    E --> G(运行数据库):::process
    F --> G

通过以上的介绍和实践,我们可以更好地理解和掌握在容器中运行Oracle数据库时环境变量和挂载存储的使用方法,从而构建高效、可靠的数据库环境。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐