在传统企业级数据库部署中,Oracle安装往往意味着长达数十页的操作手册和数百条手工命令。从系统参数调优到依赖包安装,从目录权限设置到环境变量配置,每个环节都可能成为"坑点"。而当我们面对需要批量部署或频繁重建测试环境的场景时,这种手工操作模式更显得力不从心。
Ansible作为现代自动化运维工具的代表,通过声明式的Playbook语言,能够将复杂的部署流程转化为可版本控制、可重复执行的代码。本文将展示如何用Ansible Playbook全自动完成CentOS8系统上Oracle 19c(19.3.0)数据库的部署,涵盖从系统准备到数据库创建的完整生命周期。相比传统方式,这种方法具有三大优势:
自动化部署需要至少两台机器:
在控制机上安装Ansible:
bash复制# 对于RHEL/CentOS系
sudo yum install -y ansible
# 对于Debian/Ubuntu系
sudo apt-get install -y ansible
提示:建议使用Python虚拟环境安装特定版本的Ansible,避免与系统包冲突
Ansible通过SSH执行远程命令,需预先配置密钥认证:
bash复制# 生成密钥对(如果尚未存在)
ssh-keygen -t rsa -b 4096
# 将公钥复制到目标主机
ssh-copy-id root@target_host
验证连通性:
bash复制ansible all -i "target_host," -m ping
创建项目目录存放Playbook和相关文件:
code复制oracle19c-ansible/
├── inventory # 主机清单文件
├── group_vars/ # 组变量
│ └── all.yml # 全局变量
├── roles/ # 角色目录
│ └── oracle19c/ # Oracle部署角色
│ ├── tasks/
│ ├── templates/
│ └── files/
└── playbook.yml # 主Playbook
创建roles/oracle19c/tasks/sys_config.yml配置系统参数:
yaml复制- name: 配置sysctl参数
template:
src: sysctl.conf.j2
dest: /etc/sysctl.d/99-oracle.conf
owner: root
group: root
mode: 0644
register: sysctl_change
notify: apply sysctl
- name: 配置limits.conf
blockinfile:
path: /etc/security/limits.conf
block: |
oracle soft nproc 2048
oracle hard nproc 16384
oracle soft nofile 4096
oracle hard nofile 65536
marker: "# {mark} ANSIBLE MANAGED BLOCK - ORACLE"
- name: 配置pam.d/login
lineinfile:
path: /etc/pam.d/login
line: "session required pam_limits.so"
state: present
对应的Jinja2模板sysctl.conf.j2:
code复制# Oracle 19c recommended settings
fs.aio-max-nr = {{ aio_max_nr | default(1048576) }}
fs.file-max = {{ file_max | default(6815744) }}
kernel.shmall = {{ shmall | default(4194304) }}
kernel.shmmax = {{ shmmax | default(17179869183) }}
...
Oracle 19c需要特定系统包,通过yum模块批量安装:
yaml复制- name: 安装基础工具
yum:
name: ['net-tools', 'vim', 'wget', 'unzip', 'zip']
state: present
- name: 安装图形界面(可选)
yum:
name: ['@X Window System', '@GNOME Desktop']
state: present
when: install_gui | default(false)
- name: 安装Oracle依赖包
yum:
name: ['make', 'libnsl', 'compat-libcap1', 'libstdc++-devel',
'gcc-c++', 'ksh', 'glibc-devel', 'libaio-devel']
state: present
Oracle需要专用用户和特定目录结构:
yaml复制- name: 创建oinstall和dba组
group:
name: "{{ item }}"
state: present
loop:
- oinstall
- dba
- name: 创建oracle用户
user:
name: oracle
group: oinstall
groups: dba
password: "{{ oracle_password | password_hash('sha512') }}"
shell: /bin/bash
home: /home/oracle
- name: 创建Oracle目录结构
file:
path: "{{ item }}"
state: directory
owner: oracle
group: oinstall
mode: 0775
loop:
- /u01/app/oracle/product/19.3.0
- /home/OracleData
- /home/OracleArch/ArchiveLog
- /home/OracleBackup/rmanbak
通过Ansible处理Oracle安装包:
yaml复制- name: 下载Oracle 19c安装包
get_url:
url: "{{ oracle_download_url }}"
dest: "/tmp/LINUX.X64_193000_db_home.zip"
checksum: "sha256:{{ oracle_checksum }}"
timeout: 1800
when: oracle_download_url is defined
- name: 解压安装包
unarchive:
src: "/tmp/LINUX.X64_193000_db_home.zip"
dest: "/u01/app/oracle/product/19.3.0/"
remote_src: yes
owner: oracle
group: oinstall
创建db_install.rsp响应文件模板实现无人值守安装:
jinja2复制[GENERAL]
RESPONSEFILE_VERSION="19.0.0.0.0"
OPERATION_TYPE="INSTALL_DB_SWONLY"
[UNIX_GROUP_NAME]
UNIX_GROUP_NAME="oinstall"
[INVENTORY_LOCATION]
INVENTORY_LOCATION=/u01/app/oraInventory
[ORACLE_HOME]
ORACLE_HOME=/u01/app/oracle/product/19.3.0
[ORACLE_BASE]
ORACLE_BASE=/u01/app/oracle
[oracle.install.db.InstallEdition]
oracle.install.db.InstallEdition=EE
[oracle.install.db.OSDBA_GROUP]
oracle.install.db.OSDBA_GROUP=dba
[oracle.install.db.OSOPER_GROUP]
oracle.install.db.OSOPER_GROUP=dba
[oracle.install.db.OSBACKUPDBA_GROUP]
oracle.install.db.OSBACKUPDBA_GROUP=dba
[oracle.install.db.OSDGDBA_GROUP]
oracle.install.db.OSDGDBA_GROUP=dba
[oracle.install.db.OSKMDBA_GROUP]
oracle.install.db.OSKMDBA_GROUP=dba
[oracle.install.db.OSRACDBA_GROUP]
oracle.install.db.OSRACDBA_GROUP=dba
通过Playbook应用模板:
yaml复制- name: 配置响应文件
template:
src: db_install.rsp.j2
dest: /home/oracle/db_install.rsp
owner: oracle
group: oinstall
mode: 0644
- name: 执行静默安装
shell: |
export CV_ASSUME_DISTID=CentOS7
/u01/app/oracle/product/19.3.0/runInstaller -silent \
-responseFile /home/oracle/db_install.rsp \
-ignorePrereqFailure
args:
executable: /bin/bash
chdir: /home/oracle
environment:
ORACLE_HOME: /u01/app/oracle/product/19.3.0
PATH: "{{ ansible_env.PATH }}:/u01/app/oracle/product/19.3.0/bin"
become_user: oracle
register: install_result
changed_when: "'Successfully Setup Software' in install_result.stdout"
创建数据库响应文件模板dbca_create.rsp.j2:
jinja2复制[GENERAL]
responseFileVersion=/oracle/assistants/rspfmt_dbca_response_schema_v19.0.0
gdbName={{ oracle_sid }}
sid={{ oracle_sid }}
databaseConfigType=SI
policyManaged=false
createAsContainerDatabase=true
numberOfPDBs=1
pdbName={{ pdb_name }}
useLocalUndoForPDBs=true
templateName=General_Purpose.dbc
sysPassword={{ sys_password }}
systemPassword={{ system_password }}
emConfiguration=NONE
datafileDestination={{ oracle_data_dir }}
recoveryAreaDestination={{ oracle_arch_dir }}
storageType=FS
characterSet=AL32UTF8
nationalCharacterSet=AL16UTF16
registerWithDirService=false
listeners=LISTENER
variables=ORACLE_BASE=/u01/app/oracle,DB_UNIQUE_NAME={{ oracle_sid }},ORACLE_HOME=/u01/app/oracle/product/19.3.0,PDB_NAME={{ pdb_name }},SERVICE_NAME={{ oracle_sid }}
initParams=sga_target=4GB,sga_max_size=4GB,pga_aggregate_target=2GB,processes=500,open_cursors=300
sampleSchema=false
memoryPercentage=40
databaseType=MULTIPURPOSE
automaticMemoryManagement=false
totalMemory=6000
执行数据库创建的Playbook任务:
yaml复制- name: 生成dbca响应文件
template:
src: dbca_create.rsp.j2
dest: /home/oracle/dbca_create.rsp
owner: oracle
group: oinstall
- name: 执行静默建库
shell: |
export ORACLE_HOME=/u01/app/oracle/product/19.3.0
$ORACLE_HOME/bin/dbca -silent -createDatabase \
-responseFile /home/oracle/dbca_create.rsp
args:
executable: /bin/bash
chdir: /home/oracle
become_user: oracle
register: dbca_result
changed_when: "'Database creation complete' in dbca_result.stdout"
数据库创建后的常见优化操作:
yaml复制- name: 配置监听自启动
lineinfile:
path: /etc/oratab
line: "{{ oracle_sid }}:/u01/app/oracle/product/19.3.0:Y"
regexp: "^{{ oracle_sid }}:"
- name: 设置PDB自动打开
shell: |
sqlplus / as sysdba <<EOF
CREATE TRIGGER open_all_pdbs AFTER STARTUP ON DATABASE
BEGIN
EXECUTE IMMEDIATE 'alter pluggable database all open';
END open_all_pdbs;
/
EOF
args:
executable: /bin/bash
become_user: oracle
- name: 修改密码策略
shell: |
sqlplus / as sysdba <<EOF
alter profile "DEFAULT" limit PASSWORD_GRACE_TIME UNLIMITED;
alter profile "DEFAULT" limit PASSWORD_LIFE_TIME UNLIMITED;
alter profile "DEFAULT" limit PASSWORD_LOCK_TIME UNLIMITED;
alter profile "DEFAULT" limit FAILED_LOGIN_ATTEMPTS UNLIMITED;
EOF
args:
executable: /bin/bash
become_user: oracle
将所有角色整合到主Playbookplaybook.yml:
yaml复制---
- hosts: oracle_servers
gather_facts: yes
become: yes
vars_files:
- group_vars/all.yml
roles:
- role: oracle19c
tags: oracle19c
tasks:
- name: 显示安装结果
debug:
msg: "Oracle 19c安装完成,SID: {{ oracle_sid }}"
tags: always
执行完整部署:
bash复制ansible-playbook -i inventory playbook.yml
典型变量文件group_vars/all.yml配置示例:
yaml复制# 全局配置
oracle_sid: ORCLCDB
pdb_name: ORCLPDB
oracle_password: oracle123
sys_password: SysPassword123
system_password: SystemPassword123
# 目录配置
oracle_base: /u01/app/oracle
oracle_home: "{{ oracle_base }}/product/19.3.0"
oracle_data_dir: /home/OracleData
oracle_arch_dir: /home/OracleArch/ArchiveLog
# 内核参数
shmmax: 17179869183
shmall: 4194304
file_max: 6815744
通过Ansible的并行执行能力,可以轻松实现多服务器同时部署:
bash复制# 同时控制10台主机部署
ansible-playbook -i inventory playbook.yml -f 10
依赖包缺失问题:
yaml复制- name: 检查并修复libnsl缺失
block:
- name: 检查libnsl是否安装
stat:
path: /usr/lib64/libnsl.so.1
register: libnsl_stat
- name: 安装libnsl
yum:
name: libnsl
state: present
when: not libnsl_stat.stat.exists
空间不足问题:
yaml复制- name: 检查磁盘空间
shell: df -h /u01 | awk 'NR==2 {print $4}'
register: u01_space
changed_when: false
- name: 确保有足够空间
fail:
msg: "/u01 分区需要至少50GB可用空间"
when: u01_space.stdout | replace('G','') | int < 50
将通用功能抽象为独立角色:
code复制roles/
├── common/ # 基础系统配置
├── oracle-prepare/ # Oracle前置条件
└── oracle-install/ # Oracle安装与配置
通过requirements.yml管理角色依赖:
yaml复制- src: git+https://github.com/oracle-ansible-roles/common
version: main
name: common
安装依赖角色:
bash复制ansible-galaxy install -r requirements.yml
在实际项目中,我们通过这种自动化方式将Oracle部署时间从平均4小时缩短到30分钟,且实现了100%的配置一致性。特别是在开发测试环境中,重建一套完整数据库环境只需简单运行Playbook即可完成。