· 前言
? ? 為什么有這篇文章?工作很多年,一直都沒有分享過工作中的積累和收獲。前幾年寫過幾篇博客,也早已輟筆。忽然發(fā)現(xiàn)工作中的很多東西,如果你不分享,自己也記不住,就拿這篇做個(gè)開始吧。
? ? 為什么選擇簡書?互聯(lián)網(wǎng)時(shí)代,分享是主題,博客已落后于這個(gè)時(shí)代。
· 起因
? ? 前幾天,部門有個(gè)客戶交流,需要搭建一個(gè)演示系統(tǒng),問同事要了一堆代碼和數(shù)據(jù)庫,數(shù)據(jù)庫是oracle,發(fā)現(xiàn)要搭建個(gè)演示環(huán)境還挺復(fù)雜。想到用 docker 搭建個(gè)環(huán)境,上傳到倉庫中,用的時(shí)候 pull 下來,豈不方便?說干就干,殊不知中間N多陷阱,踩了不少坑,記錄下來,免得走冤枉路。
· 準(zhǔn)備環(huán)境
? ? 1. docker 環(huán)境
? ? ? ? 如果你不是在 Linux 中工作,那對(duì)不起,你需要一個(gè)虛擬機(jī)。無論是在Mac 還是在 Windows,你都可以用 Docker Toolbox 來搭建一個(gè)Docker環(huán)境,這不是本文的重點(diǎn),請(qǐng)參考官方文檔,docker 的參考手冊(cè)在這里。
? ? 2. 阿里云鏡像
? ? ? ? docker.io 的鏡像對(duì)于國內(nèi)的同學(xué)來說實(shí)在是太慢了,你需要一個(gè)鏡像站點(diǎn),可以用阿里云,有淘寶賬號(hào)就可以申請(qǐng),免費(fèi),速度很快,這也不是本文的重點(diǎn),請(qǐng)到 這里 查看你的資源庫。

? ? ? ? 在鏡像加速器中,你可以找到如何設(shè)置你自己的鏡像加速器,這里就不再贅述了。
? ? 3. 下載基礎(chǔ)鏡像
? ? ? ? 如果一切從零開始,比如說安裝oracle,那就比較復(fù)雜了,好在這個(gè)世界總是有些 “好事之徒” 。從阿里云上下載一個(gè)基礎(chǔ)鏡像吧:

? ? ? ? 可以在鏡像搜索中,找到適合自己的鏡像。
· 開始工作
? ? 啟動(dòng)鏡像:
docker run -d --name oracle_11g --privileged=true -p 8080:8080 -p 1521:1521 registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g
? ? 我這個(gè)項(xiàng)目用到j(luò)dk 1.7 和 tomcat7, 先將需要的資源復(fù)制到容器中:
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
? ? 進(jìn)入容器:
docker exec -ti 容器ID /bin/bash
? ? 初始化環(huán)境變量:
source /home/oracle/.bash_profile
? ? 安裝一些必要工具:
su? #輸入密碼helowin
yum install tar
yum install vim
? ? 原有的jdk是1.6版本,升級(jí)為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,并復(fù)制jta包(項(xiàng)目需要,非必須):
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/
? ? 修改虛擬機(jī)參數(shù) $TOMCAT_HOME/bin/catalina.sh
vim /usr/java/apache-tomcat-7.0.85/bin/catalina.sh
? ? 在 cygwin=false 前增加,根據(jù)需要自行修改:
JAVA_OPTS="-Xms1024M -Xmx1024M -Xss512K -XX:PermSize=128M -XX:MaxPermSize=256M"
? ? 重點(diǎn)來了,這里曾經(jīng)踩坑無數(shù),翻來覆去做了幾次,一直沒有成功。oracle 的數(shù)據(jù)導(dǎo)入進(jìn)去后,commit 鏡像后重啟,數(shù)據(jù)就丟了。。。經(jīng)過反復(fù)研究才發(fā)現(xiàn),在docker中,很多數(shù)據(jù)庫都有這個(gè)問題。經(jīng)過測試,在 oracle 安裝目錄下的 app/oracle/oradata 這個(gè)目錄的數(shù)據(jù),docker無法固化下來,因此要把這個(gè)目錄的數(shù)據(jù)移動(dòng)到其他目錄才行。這個(gè)目錄包含三類數(shù)據(jù):控制文件、系統(tǒng)數(shù)據(jù)庫文件和日志文件。下面分步驟講解如何移動(dòng)這三種文件。
? ? 1. 新建外部目錄(root用戶),用于保存這幾類文件,幾個(gè)子目錄分別用于保存控制文件(ctl)、數(shù)據(jù)庫文件和日志文件(oradata)、備份文件(bak):
mkdir /oracle
chown -R oracle:oinstall /oracle
exit //退出 root 用戶
mkdir /oracle/ctl? /oracle/oradata /oracle/bak
? ? 2. 修改控制文件
#dba登錄, 設(shè)置輸出格式,不然看不清, 查看當(dāng)前數(shù)據(jù)文件位置和 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 是個(gè)二進(jìn)制文件,不能修改,要從spfile建立一個(gè)pfile,再進(jìn)行修改
create pfile from spfile;? // 建立 pfile
shutdown immediate? ? // 停止數(shù)據(jù)庫
exit
# 然后將 control01 和 control02 復(fù)制到 /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

# 修改后使用 pfile 重啟,并從pfile創(chuàng)建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. 修改數(shù)據(jù)文件位置
#停機(jī)并重啟
shutdown immediate?
exit
#將所有數(shù)據(jù)文件復(fù)制到新目錄下
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/
# 進(jìn)入 sqlplus, 用 mount 模式啟動(dòng),并修改數(shù)據(jù)文件的位置,再打開數(shù)據(jù)庫
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;
? ? 數(shù)據(jù)文件已切換到新位置
NAME -------------------------------------------------------------------------------- /oracle/oradata/system01.dbf
/oracle/oradata/sysaux01.dbf
/oracle/oradata/undotbs01.dbf
/oracle/oradata/users01.dbf
/oracle/oradata/example01.dbf
? ? 4. 修改日志文件
? ? ? ? 修改日志文件比較復(fù)雜,先要?jiǎng)?chuàng)建幾個(gè)日志文件,然后把當(dāng)前激活的日志文件改到新的日志文件上,刪除原有的日志文件,在新位置建立新的日志文件,然后再激活回來,基本上是這個(gè)邏輯。
select group#,members,bytes/1024/1024,status from v$log;
# 你看到的結(jié)果可能是這個(gè)樣子,其中 1,2,3 是日志文件序號(hào)
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設(shè)置為 inactive,inactive的可以刪除
alter system switch logfile;
#調(diào)整成這個(gè)樣子就可以切換了
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;
# 繼續(xù)調(diào)整,直到1號(hào)日志組為當(dāng)前為止
alter system switch logfile;
#結(jié)果可能是
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. 修改字符集
? ? ? ? 默認(rèn)的字符集是 UTF-8, 不幸的是我們的數(shù)據(jù)庫用的的 GBK,因此要調(diào)整。注意,一定要在上面幾個(gè)步驟完成后再做,不然就白做了。
#修改閃回設(shè)置,修改字符集
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 設(shè)置完畢,接下來你就可以放心大膽的去恢復(fù)你的數(shù)據(jù)庫,部署應(yīng)用。最后,退出容器后不要忘了commit
docker commit -m "注釋" 容器ID 你的鏡像名:latest
? ? 如果你要提交到阿里云的私有倉庫保存起來,可以先在阿里云上建立一個(gè)倉庫,然后為你的鏡像打個(gè)tag,再push,就ok了。
docker login --username=你的淘寶賬號(hào) registry.cn-hangzhou.aliyuncs.com
#輸入密碼
docker tag 你本機(jī)的鏡像名:標(biāo)簽 registry.cn-hangzhou.aliyuncs.com/倉庫名/鏡像名:latest
docker push registry.cn-hangzhou.aliyuncs.com/倉庫名/鏡像名:latest
? ? 如果運(yùn)行容器有亂碼問題,可以這樣啟動(dòng)
docker run -e LANG=zh_CN.utf8 -d --name 名稱 --privileged=true -p 8080:8080 鏡像名
· 總結(jié)
? ? 1. 工作中積累很重要。
? ? 2. 遇到困難不要輕易放棄。