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

· 前言


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


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


· 起因

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

· 准备环境

    1. docker 环境

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

    2. 阿里云镜像

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


7875617-0547e4a3776e7132.png
阿里云容器镜像服务

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

    3. 下载基础镜像

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

7875617-4f026e0c2236d1e2.png
下载 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



7875617-a90060fced586ca5.png
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. 遇到困难不要轻易放弃。

猜你喜欢

转载自blog.csdn.net/weixin_34396103/article/details/87428688