美文网首页工作我爱编程
在 Docker 中部署基于 Oracle 数据库的演示系统

在 Docker 中部署基于 Oracle 数据库的演示系统

作者: 骑着马编程 | 来源:发表于2018-03-17 23:58 被阅读0次

    · 前言

        为什么有这篇文章?工作很多年,一直都没有分享过工作中的积累和收获。前几年写过几篇博客,也早已辍笔。忽然发现工作中的很多东西,如果你不分享,自己也记不住,就拿这篇做个开始吧。

        为什么选择简书?互联网时代,分享是主题,博客已落后于这个时代。

    · 起因

        前几天,部门有个客户交流,需要搭建一个演示系统,问同事要了一堆代码和数据库,数据库是oracle,发现要搭建个演示环境还挺复杂。想到用 docker 搭建个环境,上传到仓库中,用的时候 pull 下来,岂不方便?说干就干,殊不知中间N多陷阱,踩了不少坑,记录下来,免得走冤枉路。

    · 准备环境

        1. docker 环境

            如果你不是在 Linux 中工作,那对不起,你需要一个虚拟机。无论是在Mac 还是在 Windows,你都可以用 Docker Toolbox 来搭建一个Docker环境,这不是本文的重点,请参考官方文档,docker 的参考手册在这里

        2. 阿里云镜像

            docker.io 的镜像对于国内的同学来说实在是太慢了,你需要一个镜像站点,可以用阿里云,有淘宝账号就可以申请,免费,速度很快,这也不是本文的重点,请到 这里 查看你的资源库。

    阿里云容器镜像服务

            在镜像加速器中,你可以找到如何设置你自己的镜像加速器,这里就不再赘述了。

        3. 下载基础镜像

            如果一切从零开始,比如说安装oracle,那就比较复杂了,好在这个世界总是有些 “好事之徒” 。从阿里云上下载一个基础镜像吧:

    下载 oracle11g镜像

            可以在镜像搜索中,找到适合自己的镜像。

    · 开始工作

        启动镜像:

    docker run -d --name oracle_11g --privileged=true -p 8080:8080 -p 1521:1521 registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g

        我这个项目用到jdk 1.7 和 tomcat7, 先将需要的资源复制到容器中:

    docker cp /Users/xxx/xxx.DMP oracle_11g:/tmp

    docker cp /Users/xxx/jdk-7u71-linux-x64.rpm oracle_11g:/tmp/

    docker cp /Users/xxx/apache-tomcat-7.0.85.tar.gz oracle_11g:/tmp/

    docker cp /Users/xxx/xxx.war oracle_11g:/tmp

    docker cp /Users/xxx/jta-1.1.jar oracle_11g:/tmp

        进入容器:

    docker exec -ti 容器ID /bin/bash

        初始化环境变量:

    source /home/oracle/.bash_profile

        安装一些必要工具:

    su  #输入密码helowin

    yum install tar

    yum install vim

        原有的jdk是1.6版本,升级为1.7:

    rpm -qa|grep jdk

    rpm -e --nodeps java-1.6.0-openjdk-1.6.0.0-6.1.13.4.el6_5.x86_64

    rpm -ivh /tmp/jdk-7u71-linux-x64.rpm

    java -version

        解压安装 tomcat,并复制jta包(项目需要,非必须):

    cp /tmp/apache-tomcat-7.0.85.tar.gz /usr/java/

    cd /usr/java/

    tar -zxvf apache-tomcat-7.0.85.tar.gz

    cp /tmp/jta-1.1.jar /usr/java/apache-tomcat-7.0.85/lib/

        修改虚拟机参数 $TOMCAT_HOME/bin/catalina.sh

    vim /usr/java/apache-tomcat-7.0.85/bin/catalina.sh

        在 cygwin=false 前增加,根据需要自行修改:

    JAVA_OPTS="-Xms1024M -Xmx1024M -Xss512K -XX:PermSize=128M -XX:MaxPermSize=256M"

        重点来了,这里曾经踩坑无数,翻来覆去做了几次,一直没有成功。oracle 的数据导入进去后,commit 镜像后重启,数据就丢了。。。经过反复研究才发现,在docker中,很多数据库都有这个问题。经过测试,在 oracle 安装目录下的 app/oracle/oradata 这个目录的数据,docker无法固化下来,因此要把这个目录的数据移动到其他目录才行。这个目录包含三类数据:控制文件、系统数据库文件和日志文件。下面分步骤讲解如何移动这三种文件。

        1. 新建外部目录(root用户),用于保存这几类文件,几个子目录分别用于保存控制文件(ctl)、数据库文件和日志文件(oradata)、备份文件(bak):

    mkdir /oracle

    chown -R oracle:oinstall /oracle

    exit //退出 root 用户

    mkdir /oracle/ctl  /oracle/oradata /oracle/bak

        2. 修改控制文件

    #dba登录, 设置输出格式,不然看不清, 查看当前数据文件位置和 spfile 的位置

    sqlplus / as sysdba 

    col member format a80; 

    select name from v$controlfile; 

    show parameter spfile; 

        控制文件

    NAME -------------------------------------------------------------------------------- home/oracle/app/oracle/oradata/helowin/control01.ctl

    /home/oracle/app/oracle/flash_recovery_area/helowin/control02.ctl

        spfile

    NAME     TYPE VALUE ------------------------------------ ----------- ------------------------------ spfile     string                                /home/oracle/app/oracle/produc t/11.2.0/dbhome_2/dbs/spfilehe lowin.ora

    # pfile 是个二进制文件,不能修改,要从spfile建立一个pfile,再进行修改

    create pfile from spfile;  // 建立 pfile

    shutdown immediate    // 停止数据库

    exit

    # 然后将 control01 和 control02 复制到 /oracle/ctl 目录

    mv /home/oracle/app/oracle/oradata/helowin/control01.ctl    /oracle/ctl/

    mv /home/oracle/app/oracle/flash_recovery_area/helowin/control02.ctl    /oracle/ctl/

    # 修改生成的 pfile

    vim $ORACLE_HOME/dbs/inithelowin.ora

    control_files 修改为新路径下的文件

    # 修改后使用 pfile 重启,并从pfile创建spfile,之后再重启,就ok了。

    sqlplus / as sysdba

    startup pfile=$ORACLE_HOME/dbs/inithelowin.ora

    select name from v$controlfile;

    create spfile from pfile;

    shutdown immediate

    startup

    select name from v$controlfile;

        控制文件修改完毕

    NAME -------------------------------------------------------------------------------- /oracle/ctl/control01.ctl

    /oracle/ctl/control02.ctl

        3. 修改数据文件位置

    #停机并重启

    shutdown immediate 

    exit

    #将所有数据文件复制到新目录下

    mv /home/oracle/app/oracle/oradata/helowin/sysaux01.dbf /oracle/oradata/

    mv /home/oracle/app/oracle/oradata/helowin/users01.dbf /oracle/oradata/

    mv /home/oracle/app/oracle/oradata/helowin/example01.dbf /oracle/oradata/

    mv /home/oracle/app/oracle/oradata/helowin/undotbs01.dbf /oracle/oradata/

    mv /home/oracle/app/oracle/oradata/helowin/system01.dbf /oracle/oradata/

    mv /home/oracle/app/oracle/oradata/helowin/temp01.dbf /oracle/oradata/

    # 进入 sqlplus, 用 mount 模式启动,并修改数据文件的位置,再打开数据库

    sqlplus / as sysdba

    startup mount

    alter database rename file '/home/oracle/app/oracle/oradata/helowin/sysaux01.dbf' to '/oracle/oradata/sysaux01.dbf';

    alter database rename file '/home/oracle/app/oracle/oradata/helowin/users01.dbf' to '/oracle/oradata/users01.dbf';

    alter database rename file '/home/oracle/app/oracle/oradata/helowin/example01.dbf' to '/oracle/oradata/example01.dbf';

    alter database rename file '/home/oracle/app/oracle/oradata/helowin/undotbs01.dbf' to '/oracle/oradata/undotbs01.dbf';

    alter database rename file '/home/oracle/app/oracle/oradata/helowin/system01.dbf' to '/oracle/oradata/system01.dbf';

    alter database rename file '/home/oracle/app/oracle/oradata/helowin/temp01.dbf' to '/oracle/oradata/temp01.dbf';

    alter database open;

    select name from v$datafile;

        数据文件已切换到新位置

    NAME -------------------------------------------------------------------------------- /oracle/oradata/system01.dbf

    /oracle/oradata/sysaux01.dbf

    /oracle/oradata/undotbs01.dbf

    /oracle/oradata/users01.dbf

    /oracle/oradata/example01.dbf

        4. 修改日志文件

            修改日志文件比较复杂,先要创建几个日志文件,然后把当前激活的日志文件改到新的日志文件上,删除原有的日志文件,在新位置建立新的日志文件,然后再激活回来,基本上是这个逻辑。

    select group#,members,bytes/1024/1024,status from v$log;

    # 你看到的结果可能是这个样子,其中 1,2,3 是日志文件序号

    GROUP#    MEMBERS BYTES/1024/1024 STATUS ---------- ---------- ---------------

    1     1   50 CURRENT

    2     1   50 UNUSED

    3     1   50 UNUSED

    #新增日志文件

    alter database add logfile group 4 ('/oracle/oradata/redo04.log') size 50M;

    alter database add logfile group 5 ('/oracle/oradata/redo05.log') size 50M;

    alter database add logfile group 6 ('/oracle/oradata/redo06.log') size 50M;

    #添加完后

    GROUP#    MEMBERS BYTES/1024/1024 STATUS ---------- ---------- ----------------

    1     1   50 CURRENT

    2     1   50 UNUSED

    3     1   50 UNUSED

    4     1   50 UNUSED

    5     1   50 UNUSED

    6     1   50 UNUSED

    #切换日志组,需要多次切换才可能将1,2,3设置为 inactive,inactive的可以删除

    alter system switch logfile;

    #调整成这个样子就可以切换了

    GROUP#    MEMBERS BYTES/1024/1024 STATUS ----------  ----------------

    1     1   50 ACTIVE

    2     1   50 ACTIVE

    3     1   50 ACTIVE

    4     1   50 ACTIVE

    5     1   50 CURRENT

    6     1   50 UNUSED

    #保存修改 , 删除原有位置上的日志组

    alter system checkpoint;

    alter database drop logfile group 1;

    alter database drop logfile group 2;

    alter database drop logfile group 3;

    exit

    rm -rf /home/oracle/app/oracle/oradata/helowin/redo01.log

    rm -rf /home/oracle/app/oracle/oradata/helowin/redo02.log

    rm -rf /home/oracle/app/oracle/oradata/helowin/redo03.log

    #增加新的日志组

    sqlplus / as sysdba

    alter database add logfile group 1 ('/oracle/oradata/redo01.log') size 50M;

    alter database add logfile group 2 ('/oracle/oradata/redo02.log') size 50M;

    alter database add logfile group 3 ('/oracle/oradata/redo03.log') size 50M;

    # 继续调整,直到1号日志组为当前为止

    alter system switch logfile;

    #结果可能是

    GROUP#    MEMBERS BYTES/1024/1024 STATUS ---------- - ----------------

    1     1   50 CURRENT

    2     1   50 ACTIVE

    3     1   50 ACTIVE

    4     1   50 ACTIVE

    5     1   50 ACTIVE

    6     1   50 ACTIVE

    #保存修改,大功告成

    alter system checkpoint;

        5. 修改字符集

            默认的字符集是 UTF-8, 不幸的是我们的数据库用的的 GBK,因此要调整。注意,一定要在上面几个步骤完成后再做,不然就白做了。

    #修改闪回设置,修改字符集

    select userenv('language') from dual;

    shutdown immediate;

    startup mount;

    alter system enable restricted session;

    alter system set job_queue_processes=0;

    alter system set aq_tm_processes=0;

    alter database flashback off;

    alter database open;

    show parameter recovery;

    alter system reset db_recovery_file_dest  scope=spfile sid='*';

    alter system reset db_recovery_file_dest_size scope=spfile sid='*';

    alter database character set internal_use ZHS16GBK;

    shutdown immediate

    startup

    exit

        至此,oracle 设置完毕,接下来你就可以放心大胆的去恢复你的数据库,部署应用。最后,退出容器后不要忘了commit

    docker commit -m "注释" 容器ID 你的镜像名:latest

        如果你要提交到阿里云的私有仓库保存起来,可以先在阿里云上建立一个仓库,然后为你的镜像打个tag,再push,就ok了。

    docker login --username=你的淘宝账号 registry.cn-hangzhou.aliyuncs.com

    #输入密码

    docker tag 你本机的镜像名:标签 registry.cn-hangzhou.aliyuncs.com/仓库名/镜像名:latest

    docker push registry.cn-hangzhou.aliyuncs.com/仓库名/镜像名:latest

        如果运行容器有乱码问题,可以这样启动

    docker run -e LANG=zh_CN.utf8 -d --name 名称 --privileged=true -p 8080:8080 镜像名

    · 总结

        1. 工作中积累很重要。

        2. 遇到困难不要轻易放弃。

    相关文章

      网友评论

        本文标题:在 Docker 中部署基于 Oracle 数据库的演示系统

        本文链接:https://www.haomeiwen.com/subject/ovlsqftx.html