在容器化交付成为主流的云时代,oracle这种传统数据库巨无霸也开始适应潮流,将oracle软件也支持容器化部署。通过 https://container-registry.oracle.com/ 站点可以下载官方编译好的oracle镜像,不过前提是先要通过oracle的镜像仓库的授权。不过也可以不使用官方镜像仓库,可以通过官方提供的脚本文件,自已编译镜像。本篇就通过自编译镜像完成一个oracle的容器化部署。

一、编译镜像

  1. 安装最新版docker
1curl -fsSL get.docker.com -o get-docker.sh
2sh get-docker.sh
3systemctl restart docker
  1. oracle镜像编译
    这里选择了最简单的单机版部署,这里的脚本也支持RAC版镜像生成。
1git clone https://github.com/oracle/docker-images.git
2cd ~/docker-images/OracleDatabase/SingleInstance/19.3.0
3cp $HOME/Downloads/LINUX.X64_193000_db_home.zip .
4cd ~/docker-images/OracleDatabase/SingleInstance
5./buildDockerImage.sh -v 19.3.0 -e
6docker images
7//输出结果如下:
8REPOSITORY                                             TAG         IMAGE ID       CREATED        SIZE
9oracle/database                                        19.3.0-ee   3e3721d64bf0   34 hours ago   6.67GB

除了支持企业版,也支持标准版和express版,具体参数如下:

 1Usage: buildContainerImage.sh -v [version] -t [image_name:tag] [-e | -s | -x] [-i] [-o] [container build option]
 2Builds a container image for Oracle Database.
 3Parameters:
 4-v: version to build
 5Choose one of: 11.2.0.2 12.1.0.2 12.2.0.1 18.3.0 18.4.0 19.3.0 21.3.0
 6-t: image_name:tag for the generated docker image
 7-e: creates image based on 'Enterprise Edition'
 8-s: creates image based on 'Standard Edition 2'
 9-x: creates image based on 'Express Edition'
10-i: ignores the MD5 checksums
11-o: passes on container build option
12* select one edition only: -e, -s, or -x
13LICENSE UPL 1.0
14Copyright (c) 2014,2021 Oracle and/or its affiliates.

二、启动运行

制作的镜像支持传多个参数,这里通过传参的方式,将数据保存在外面的机器上,具体如下:

 1mkdir /opt/oracle19c
 2chown 54321:54321  /opt/oracle19c
 3sh start_oracle.sh
 4脚本文件内容如下:
 5[root@ecs-82f5 ~]# more start_oracle.sh
 6# default value ORCLCDB
 7ORACLE_SID=PSTGCDB
 8# default value ORCLPDB1
 9ORACLE_PDB=PSTGPDB1
10# default value random
11ORACLE_PWD=Docker#2020
12# enterprise or standard default enterprise
13ORACLE_EDITION=enterprise
14# default value AL32UTF8,also can choose ZHS16GBK
15ORACLE_CHARACTERSET=AL32UTF8
16#
17ORADATA=/opt/oracle19c/oradata
18ORASTARTUP=/opt/oracle19c/startup
19ORASETUP=/opt/oracle19c/setup
20#
21CON_NAME=my19c
22LISTENER=1521
23OEM=5500
24IMAGE=oracle/database:19.3.0-ee
25
26docker run -d --name ${CON_NAME} \
27-p ${LISTENER}:1521 -p ${OEM}:5500 \
28-e ORACLE_SID=${ORACLE_SID} \
29-e ORACLE_PDB=${ORACLE_PDB} \
30-e ORACLE_PWD=${ORACLE_PWD} \
31-e ORACLE_EDITION=${ORACLE_EDITION} \
32-v ${ORADATA}:/opt/oracle/oradata \
33-v ${ORASTARTUP}:/opt/oracle/scripts/startup \
34-v ${ORASETUP}:/opt/oracle/scripts/setup ${IMAGE}

命令执行后,等待10分钟左右,就完成了数据库的安装,可以通过docker logs -f 19c查看,当出现DATABASE IS READY TO USE!时,表示数据库已经安装启动成功。

这里有几个要点提下:

  1. 密码修改
    如果这里的密码没有设置,可以通过sqlplus / as sysdba登录后去修改,当然也可以通过直接运行docker镜像里的脚本去修改:
1方法1:容器脚本修改密码
2docker exec my19c ./setPassword.sh newpassword
3方法2:Sqlplus修改密码
4SQL> alter user system identified by newpassword;
  1. 查看端口监听
1$ docker port my19c
21521/tcp -> 0.0.0.0:1521
35500/tcp -> 0.0.0.0:5500
  1. 使用的字符集

在国内安装时经常会选择zhs16gbk字符集,在海外安装会见到很多会选择al32utf8这样的字符集,区别如下:

  • zhs16gbk是中文字符集,也就是适合在中国用,只能存储中文和英文字符,如果你存储韩文则显示为乱码(没有编码);
  • al32utf8是utf8字符集,u是unicode的意思,适合中文、韩语、日语等等不同的语言使用。
  • 那么为什么我们要在中国使用zhs16gbk存储中文呢?这是因为utf8存储中文的效率不如zhs16gbk,比如一个字“懂”,zhs16gbk采用2个字符存储,而al32utf8采用3-4个字符存储,这样效率就有了高低之分。

三、登录验证

  1. 图形管理界面登录
    由于我们将5500这个管理端口也映射了出去,可以通过https://主机IP:5500/em/shell链接登录查看对应的性能数据:
    oracle-em-shell
    oracle-em-shell

    注意,这里的容器名一定要使用CDB$ROOT,这里的容器名是oracle的,不是docker的容器名。
    登录后的界面类似如下:
    oracle-em-login
    oracle-em-login
  2. 命令行操作
    这里需要注意下,docker exec在这里使用的shell需要是bash,不能是/bin/sh,不然会导致环境变量不加载,连不上数据库。
 1[root@ecs-82f5 opt]# docker exec -it my19c /bin/bash
 2bash-4.2$ sqlplus / as sysdba
 3
 4SQL*Plus: Release 19.0.0.0.0 - Production on Tue Jun 7 15:30:48 2022
 5Version 19.3.0.0.0
 6
 7Copyright (c) 1982, 2019, Oracle.  All rights reserved.
 8
 9
10Connected to:
11Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
12Version 19.3.0.0.0
13
14SQL> SELECT NAME FROM v$database;
15
16NAME
17---------
18PSTGCDB
19
20SQL> SELECT TABLESPACE_NAME FROM USER_TABLESPACES;
21
22TABLESPACE_NAME
23------------------------------
24SYSTEM
25SYSAUX
26UNDOTBS1
27TEMP
28USERS
29
30SQL> select USERNAME, DEFAULT_TABLESPACE from DBA_USERS;