Description:-
In this article we are going to see Oracle Automation-Applying PSU patch in Oracle 12c Database Using Ansible Tool
Let’s start the Demo:-
Steps to apply oracle PSU patch using Ansible :-
Step 1:- Download the ansible-oracle-psu role from github site.Click Here
Step 2:-Copy the ZIP file to ansible server and unzip the file
[oracle@ansible Desktop]# unzip ansible-oracle-psu.zip Archive: ansible-oracle-master.zip 1bbb35d690c102e23488537754ff8d1e0a99dc15 creating: ansible-oracle-master/
[oracle@ansible Desktop]# ls -lrt
total 4272
drwxr-xr-x. 7 root root 4096 Jul 30 11:12 ansible-oracle-psu
-rwxrw-rw-. 1 ansible ansible 349507 Jul 30 22:33 ansible-oracle-psu.zip
Step 3:- Ansible playbook file for applying path in ORACLE_HOME
Sample file:-
- hosts: servers
roles:
- role: psu-apply
Role name: Ansible role psu-apply to apply Oracle patches (PSU) to single instance (SI) and RAC instances.
Step 4:- Copy the p6880880_121010_Linux-x86-64.zip(opatch utility upgrade) and PSU patch(p27338041_121020_Linux-x86-64.zip) file to the target server.
TARGET :-
[oracle@test OPatch]$ cd /u01/ [oracle@test u01]$ ls -lrt drwxr-xr-x. 4 oracle oinstall 38 Jul 26 15:36 app -rwxrwxrwx. 1 oracle oinstall 496419192 Aug 1 19:22 p27338041_121020_Linux-x86-64.zip -rwxrwxrwx. 1 oracle oinstall 99183505 Aug 2 12:14 p6880880_121010_Linux-x86-64.zip
Step 5:- Create a role folder under /etc/ansible & copy the ansible-oracle-psu folder and rename as psu-apply folder
[oracle@ansible ansible]$ mkdir roles [oracle@ansible ansible]$ mv ansible-oracle-psu psu-apply [oracle@ansible ~]$ cd /etc/ansible/roles/psu-apply/ [oracle@ansible psu-apply]$ ls -lrt total 16 -rwxrwxr-x. 1 oracle oinstall 1300 Sep 19 2017 README.md drwxrwxr-x. 2 oracle oinstall 51 Aug 10 23:58 files -rwxrwxr-x. 1 oracle oinstall 62 Aug 11 00:04 patch.yml drwxrwxr-x. 2 oracle oinstall 21 Aug 12 11:15 meta drwxrwxr-x. 2 oracle oinstall 4096 Aug 12 13:20 templates drwxrwxr-x. 2 oracle oinstall 21 Aug 12 13:51 defaults drwxrwxr-x. 2 oracle oinstall 4096 Aug 12 14:06 tasks drwxrwxr-x. 2 oracle oinstall 21 Aug 12 14:06 vars
Step 6:- Run the tree command and see the execution of .yml files to apply a patch for ORACLE_HOME.
[root@ansible roles]# tree psu-apply
psu-apply
├── defaults
│ └── main.yml
├── files
│ ├── check_patches.sql
│ └── getMOSPatch.sh
├── meta
│ └── main.yml
├── patch.retry
├── patch.yml
├── README.md
├── tasks
│ ├── conflict_check.yml
│ ├── dbbp_rac.yml
│ ├── dbbp_si.yml
│ ├── extract_files.yml
│ ├── main.yml
│ ├── oneoff_apply.yml
│ ├── oneoff_rollback.yml
│ ├── pre_checks.yml
│ ├── psu_rac.yml
│ ├── psu_si.yml
│ ├── rollback_patch.yml
│ ├── rollback_rac.yml
│ ├── rollback_si.yml
│ ├── run_catbundle.yml
│ └── ru_si.yml
├── templates
│ ├── getMOSPatch.sh.cfg.j2
│ ├── ocmrsp.expect.j2
│ ├── patch_list.j2
│ ├── quarterly_patch_list.j2
│ └── srvctl_state.j2
└── vars
└── main.yml
6 directories, 29 files
Role Variables :-
vars/main.yml
patch_type: psu dictionary variable for information for 12.1.0.2 and 11.2.0.4
defaults/main.yml
patch_name: APR2018 # Should match quarterly_patches dictionary variable defined in vars/main.yml
shutdown_listener: true # set to false if patching an empty oracle home (ie new 12c install)
rollback_psu: false # set to true if rolling back current PSU.
Required Inventory Variables
oracle_install_type: valid values are SI or RAC. Used to determine if host is a single instance database install or part of a RAC cluster.
oracle_stage_install: directory that contains all oracle install files
oracle_stage: directory to store logs and scripts used during playbook execution.
oracle_version: expects values of 11.2.0.4 or 12.1.0.2
Step 7:- In main.yml file,provide the below entries
[oracle@ansible defaults]$ cat main.yml
---
patch_name: APR2018 # Should match psu dictionary variable defined in vars/main.yml
shutdown_listener: true # set to false if patching an empty oracle home (ie new 12c install)
rollback_psu: false # set to true if rolling back current PSU.
oracle_home: "/u01/app/oracle/product/12.1.0/dbhome_1/"
oracle_base: /u01/app/oracle
tns_admin: "{{ oracle_home }}/network/admin"
oracle_stage_install: /u01
oracle_stage_base: /u01
oracle_install_type: si
oracle_version: 12.1.0.2
patch_type: psu
patch_directory: /u01
env:
ORACLE_HOME: "{{ oracle_home }}"
ORACLE_BASE: "{{ oracle_base }}"
TNS_ADMIN: "{{ tns_admin }}"
PATH: "{{ oracle_home }}/bin:{{ oracle_home }}/OPatch:$PATH:/bin:/usr/bin::/usr/ccs/bin"
oracle_user: oracle # User that will own the Oracle Installations.
oracle_group: oinstall # Primary group for oracle_user.
Step 8:- Provide the PSU patch details
[oracle@ansible psu-apply]$ cd vars/
[oracle@ansible vars]$ cat main.yml
---
env:
ORACLE_HOME: "{{ oracle_home }}"
ORACLE_BASE: "{{ oracle_base }}"
TNS_ADMIN: "{{ tns_admin }}"
PATH: "{{ oracle_home }}/bin:{{ oracle_home }}/OPatch:$PATH:/bin:/usr/bin::/usr/ccs/bin"
# Latest opatch versions and files.
# Files should exist in path defined by oracle_stage_install.
opatch:
12.1.0.2:
version: 12.2.0.1.14
filename: p6880880_121010_Linux-x86-64.zip
# Database Proactive Patch for 12.1
psu:
12.1.0.2:
APR2018:
patchversion: 12.1.0.2.180417
filename: p27338041_121020_Linux-x86-64.zip
patchid: 27338041
si_patchid: 27338041
Step 9:- The list of tasks has been executed for applying patch in target ORACLE_HOME.
tasks/main.yml --- role: psu-apply #file: main.yml - debug: var=patch_type - name: Run pre-check tasks include: pre_checks.yml tags: pre_checks - name: Extract PSU and One-off patches include: extract_files.yml when: not rollback_psu tags: extract_files - name: Stop EM Agent shell: "{{ agent_home }}/bin/emctl stop agent" become_user: "{{ oracle_user }}" when: agent_home is defined and shutdown_listener tags: stop_agent - name: Apply Quarterly Patch include: "{{ patch_type }}_{{ oracle_install_type }}.yml" become_user: "{{ oracle_user }}" when: not rollback_psu tags: apply - name: Rollback Quarterly Patch include: "rollback_{{ oracle_install_type }}.yml" become_user: "{{ oracle_user }}" when: rollback_psu tags: rollback - name: Start EM Agent shell: "{{ agent_home }}/bin/emctl start agent" become: yes become_user: "{{ oracle_user }}" when: agent_home is defined and shutdown_listener tags: start_agent - name: Opatch lsinventory shell: "{{ oracle_home }}/OPatch/opatch lsinventory -oh {{ oracle_home }}" become_user: "{{ oracle_user }}" with_items: - "{{ oracle_home }}" - "{{ grid_home|default(None) }}" when: item is defined register: lsinv_post tasks/pre_checks.yml --- - name: fail if required variables are not defined fail: msg="{{ item }} is not defined for {{ ansible_hostname }}" when: "{{ item }} is not defined" tags: always with_items: - oracle_install_type - oracle_version - patch_type - patch_name - name: Check for zip file stat: path: "{{ oracle_stage_install }}" get_checksum: false get_md5: false register: patch_st failed_when: "not {{ patch_st.stat.exists }}" - name: Check if OPatch zip file exists stat: path: "{{ oracle_stage_install }}" register: opatch_st failed_when: "not {{ opatch_st.stat.exists }}" # - name: fail if PSU-Specific one-off patches are missing # stat: # path: "{{ oracle_stage_install }}/{{ item.filename }}" # register: patch_st # with_items: oneoff_patches[ quarterly_patches[patch_type][oracle_version][patch_name].patchversion ]|default([]) # when: "{{ oneoff_patches[ quarterly_patches[patch_type][oracle_version][patch_name].patchversion ] }} is defined" # - name: Fail if missing PSU-Specific one-off patches # fail: msg="Oops! Missing one-off patch {{ item.item.filename }}" # with_items: patch_st.results # when: # - "{{ oneoff_patches[ quarterly_patches[patch_type][oracle_version][patch_name].patchversion ] }} is defined" # - "not {{ item.stat.exists }}"
Step 10 :- Check the opatch version and inventory in ORACLE_HOME
[oracle@fhpasadbdr01 OPatch]$ ./opatch version OPatch Version: 12.1.0.1.8 OPatch succeeded.
Step 11 :- Stop the database & listener services
Playbook file to apply patch :-
[oracle@ansible psu-apply]$ cat patch.yml
---
- hosts: database-servers
roles:
- role: psu-apply
Step 12:- Check ping status before applying a patch
[oracle@ansible psu-apply]$ ansible all -m ping test | SUCCESS => { "changed": false, "ping": "pong" }
Syntax check:-
[oracle@ansible psu-apply]$ ansible-playbook patch.yml --syntax-check playbook: patch.yml
Step 13:- Run the playbook file to apply a database patch in ORACLE_HOME.
patch.yml file will update the opatch utility and apply PSU patch in ORACLE_HOME which we copied to /u01 directory
[oracle@ansible psu-apply]$ ansible-playbook patch.yml
PLAY [database-servers] **********************************************************
TASK [Gathering Facts] ***************************************************************************************************
ok: [test]
TASK [psu-apply : debug] *************************************************************************************************
ok: [test] => {
"patch_type": "psu"
}
TASK [psu-apply : fail if required variables are not defined] ************************************************************
skipping: [test] => (item=oracle_install_type)
skipping: [test] => (item=oracle_version)
skipping: [test] => (item=patch_type)
skipping: [test] => (item=patch_name)
TASK [psu-apply : Check for zip file] ************************************************************************************
ok: [test]
TASK [psu-apply : Check if OPatch zip file exists] ***********************************************************************
ok: [test]
TASK [psu-apply : Create Patch directory] ********************************************************************************
ok: [test]
TASK [psu-apply : Unzip Quarterly Patch] *********************************************************************************
skipping: [test]
TASK [psu-apply : Unzip oneoff patches] **********************************************************************************
TASK [psu-apply : Stop EM Agent] *****************************************************************************************
skipping: [test]
TASK [psu-apply : Apply Quarterly Patch] *********************************************************************************
included: /etc/ansible/roles/psu-apply/tasks/psu_si.yml for test
TASK [psu-apply : PSU SI | update opatch] *******************************************************************************
changed: [test]
TASK [psu-apply : PSU SI | Get list of patches in PSU] *****************************************************************
ok: [test]
TASK [psu-apply : PSU SI | Template patch list] *************************************************************************
ok: [test]
TASK [psu-apply : PSU SI | check for conflicts] *************************************************************************
changed: [test] => (item=CheckConflictAgainstOHWithDetail)
changed: [test] => (item=CheckSystemSpace)
TASK [psu-apply : debug] *************************************************************************************************
ok: [test] => {
"opatch_conflicts": {
"changed": true,
"msg": "All items completed",
"results": [
{
"_ansible_ignore_errors": null,
"_ansible_item_label": "CheckConflictAgainstOHWithDetail",
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": true,
"cmd": "opatch prereq CheckConflictAgainstOHWithDetail -phBaseFile /u01/quarterly_patch_list_12.1.0.2_APR2018.txt",
"delta": "0:00:03.900157",
"end": "2018-08-10 23:13:51.674497",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": "opatch prereq CheckConflictAgainstOHWithDetail -phBaseFile /u01/quarterly_patch_list_12.1.0.2_APR2018.txt",
"_uses_shell": true,
"argv": null,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"warn": true
}
},
"item": "CheckConflictAgainstOHWithDetail",
"rc": 0,
"start": "2018-08-10 23:13:47.774340",
"stderr": "",
"stderr_lines": [],
"stdout": "Oracle Interim Patch Installer version 12.2.0.1.14\nCopyright (c) 2018, Oracle Corporation. All rights reserved.\n\nPREREQ session\n\nOracle Home : /u01/app/oracle/product/12.1.0/dbhome_1\nCentral Inventory : /u01/app/oraInventory\n from : /u01/app/oracle/product/12.1.0/dbhome_1//oraInst.loc\nOPatch version : 12.2.0.1.14\nOUI version : 12.1.0.2.0\nLog file location : /u01/app/oracle/product/12.1.0/dbhome_1/cfgtoollogs/opatch/opatch2018-08-10_23-13-48PM_1.log\n\nInvoking prereq \"checkconflictagainstohwithdetail\"\n\nPrereq \"checkConflictAgainstOHWithDetail\" passed.\n\nOPatch succeeded.",
"stdout_lines": [
"Oracle Interim Patch Installer version 12.2.0.1.14",
"Copyright (c) 2018, Oracle Corporation. All rights reserved.",
"",
"PREREQ session",
"",
"Oracle Home : /u01/app/oracle/product/12.1.0/dbhome_1",
"Central Inventory : /u01/app/oraInventory",
" from : /u01/app/oracle/product/12.1.0/dbhome_1//oraInst.loc",
"OPatch version : 12.2.0.1.14",
"OUI version : 12.1.0.2.0",
"Log file location : /u01/app/oracle/product/12.1.0/dbhome_1/cfgtoollogs/opatch/opatch2018-08-10_23-13-48PM_1.log",
"",
"Invoking prereq \"checkconflictagainstohwithdetail\"",
"",
"Prereq \"checkConflictAgainstOHWithDetail\" passed.",
"",
"OPatch succeeded."
]
},
{
"_ansible_ignore_errors": null,
"_ansible_item_label": "CheckSystemSpace",
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": true,
"cmd": "opatch prereq CheckSystemSpace -phBaseFile /u01/quarterly_patch_list_12.1.0.2_APR2018.txt",
"delta": "0:00:03.471081",
"end": "2018-08-10 23:13:55.508123",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": "opatch prereq CheckSystemSpace -phBaseFile /u01/quarterly_patch_list_12.1.0.2_APR2018.txt",
"_uses_shell": true,
"argv": null,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"warn": true
}
},
"item": "CheckSystemSpace",
"rc": 0,
"start": "2018-08-10 23:13:52.037042",
"stderr": "",
"stderr_lines": [],
"stdout": "Oracle Interim Patch Installer version 12.2.0.1.14\nCopyright (c) 2018, Oracle Corporation. All rights reserved.\n\nPREREQ session\n\nOracle Home : /u01/app/oracle/product/12.1.0/dbhome_1\nCentral Inventory : /u01/app/oraInventory\n from : /u01/app/oracle/product/12.1.0/dbhome_1//oraInst.loc\nOPatch version : 12.2.0.1.14\nOUI version : 12.1.0.2.0\nLog file location : /u01/app/oracle/product/12.1.0/dbhome_1/cfgtoollogs/opatch/opatch2018-08-10_23-13-52PM_1.log\n\nInvoking prereq \"checksystemspace\"\n\nPrereq \"checkSystemSpace\" passed.\n\nOPatch succeeded.",
"stdout_lines": [
"Oracle Interim Patch Installer version 12.2.0.1.14",
"Copyright (c) 2018, Oracle Corporation. All rights reserved.",
"",
"PREREQ session",
"",
"Oracle Home : /u01/app/oracle/product/12.1.0/dbhome_1",
"Central Inventory : /u01/app/oraInventory",
" from : /u01/app/oracle/product/12.1.0/dbhome_1//oraInst.loc",
"OPatch version : 12.2.0.1.14",
"OUI version : 12.1.0.2.0",
"Log file location : /u01/app/oracle/product/12.1.0/dbhome_1/cfgtoollogs/opatch/opatch2018-08-10_23-13-52PM_1.log",
"",
"Invoking prereq \"checksystemspace\"",
"",
"Prereq \"checkSystemSpace\" passed.",
"",
"OPatch succeeded."
]
}
]
}
}
TASK [psu-apply : PSU SI | get list of database names on host] **********************************************************
changed: [test]
TASK [psu-apply : dictionary variable with latest PSU information for 12.1.0.2 and 11.2.0.4SI | shutdown databases running in oracle_home] ***************************************************
TASK [psu-apply : PSU SI | shutdown listener in oracle_home] ************************************************************
changed: [test]
TASK [psu-apply : PSU SI | opatch apply] ********************************************************************************
changed: [test]
TASK [psu-apply : debug] *************************************************************************************************
ok: [test] => {
"opatch_apply.stdout_lines": [
"Oracle Interim Patch Installer version 12.2.0.1.14",
"Copyright (c) 2018, Oracle Corporation. All rights reserved.",
"",
"",
"Oracle Home : /u01/app/oracle/product/12.1.0/dbhome_1",
"Central Inventory : /u01/app/oraInventory",
" from : /u01/app/oracle/product/12.1.0/dbhome_1//oraInst.loc",
"OPatch version : 12.2.0.1.14",
"OUI version : 12.1.0.2.0",
"Log file location : /u01/app/oracle/product/12.1.0/dbhome_1/cfgtoollogs/opatch/opatch2018-08-10_23-13-57PM_1.log",
"",
"Verifying environment and performing prerequisite checks...",
"OPatch continues with these patches: 19769480 20299023 20831110 21359755 21948354 22291127 23054246 24006101 24732082 25171037 25755742 26609783 26713565 26925311 27338041 ",
"",
"Do you want to proceed? [y|n]",
"Y (auto-answered by -silent)",
"User Responded with: Y",
"All checks passed.",
"",
"Please shutdown Oracle instances running out of this ORACLE_HOME on the local system.",
"(Oracle Home = '/u01/app/oracle/product/12.1.0/dbhome_1')",
"",
"",
"Is the local system ready for patching? [y|n]",
"Y (auto-answered by -silent)",
"User Responded with: Y",
"Backing up files...",
"Applying sub-patch '19769480' to OH '/u01/app/oracle/product/12.1.0/dbhome_1'",
"",
"Composite patch 27338041 successfully applied.",
"Log file location: /u01/app/oracle/product/12.1.0/dbhome_1/cfgtoollogs/opatch/opatch2018-08-10_23-13-57PM_1.log",
"",
"OPatch succeeded."
]
}
TASK [psu-apply : PSU SI | apply oneoff patches] ************************************************************************
skipping: [test]
TASK [psu-apply : PSU SI | startup databases] ***************************************************************************
TASK [psu-apply : PSU SI | 12.1 - startup pluggable databases] **********************************************************
TASK [psu-apply : PSU SI | Load Modified SQL Files into the Database] ***************************************************
included: /etc/ansible/roles/psu-apply/tasks/run_catbundle.yml for test
TASK [psu-apply : 11.2 - Load Modified SQL Files into the Database] ******************************************************
TASK [psu-apply : 12.1 - Load Modified SQL Files into the Database] ******************************************************
TASK [psu-apply : PSU SI | startup listener in oracle_home] *************************************************************
changed: [test]
TASK [psu-apply : Rollback Quarterly Patch] ******************************************************************************
skipping: [test]
TASK [psu-apply : Start EM Agent] ****************************************************************************************
skipping: [test]
TASK [psu-apply : Opatch lsinventory] ************************************************************************************
changed: [test] => (item=/u01/app/oracle/product/12.1.0/dbhome_1/)
changed: [test] => (item=)
OPatch succeeded.",
"stdout_lines": [
"Oracle Interim Patch Installer version 12.2.0.1.14",
"Copyright (c) 2018, Oracle Corporation. All rights reserved.",
"",
"",
"Oracle Home : /u01/app/oracle/product/12.1.0/dbhome_1",
"Central Inventory : /u01/app/oraInventory",
" from : /u01/app/oracle/product/12.1.0/dbhome_1//oraInst.loc",
"OPatch version : 12.2.0.1.14",
"OUI version : 12.1.0.2.0",
"Log file location : /u01/app/oracle/product/12.1.0/dbhome_1/cfgtoollogs/opatch/opatch2018-08-10_23-24-05PM_1.log",
"",
"Lsinventory Output file location : /u01/app/oracle/product/12.1.0/dbhome_1/cfgtoollogs/opatch/lsinv/lsinventory2018-08-10_23-24-05PM.txt",
"",
"--------------------------------------------------------------------------------",
"Local Machine Information::",
"Hostname: test.localdomain.com",
"ARU platform id: 226",
"ARU platform description:: Linux x86-64",
"",
"Installed Top-level Products (1): ",
"",
"Oracle Database 12c 12.1.0.2.0",
"There are 1 products installed in this Oracle Home.",
"",
"",
"Interim patches (1) :",
"",
"Patch 27338041 : applied on Fri Aug 10 23:20:33 EDT 2018",
"Unique Patch ID: 22036385",
"Patch description: \"Database Patch Set Update : 12.1.0.2.180417 (27338041)\"",
" Created on 16 Mar 2018, 02:05:00 hrs PST8PDT",
"Sub-patch 26925311; \"Database Patch Set Update : 12.1.0.2.180116 (26925311)\"",
"Sub-patch 26713565; \"Database Patch Set Update : 12.1.0.2.171017 (26713565)\"",
"Sub-patch 26609783; \"Database Patch Set Update : 12.1.0.2.170814 (26609783)\"",
"Sub-patch 25755742; \"Database Patch Set Update : 12.1.0.2.170718 (25755742)\"",
"Sub-patch 25171037; \"Database Patch Set Update : 12.1.0.2.170418 (25171037)\"",
"Sub-patch 24732082; \"Database Patch Set Update : 12.1.0.2.170117 (24732082)\"",
"Sub-patch 24006101; \"Database Patch Set Update : 12.1.0.2.161018 (24006101)\"",
"Sub-patch 23054246; \"Database Patch Set Update : 12.1.0.2.160719 (23054246)\"",
"Sub-patch 22291127; \"Database Patch Set Update : 12.1.0.2.160419 (22291127)\"",
"Sub-patch 21948354; \"Database Patch Set Update : 12.1.0.2.160119 (21948354)\"",
"Sub-patch 21359755; \"Database Patch Set Update : 12.1.0.2.5 (21359755)\"",
"Sub-patch 20831110; \"Database Patch Set Update : 12.1.0.2.4 (20831110)\"",
"Sub-patch 20299023; \"Database Patch Set Update : 12.1.0.2.3 (20299023)\"",
"Sub-patch 19769480; \"Database Patch Set Update : 12.1.0.2.2 (19769480)\"",
"---------------------------------------------------------",
"OPatch succeeded."
]
}
]
}
PLAY RECAP **********************************************************
test : ok=19 changed=7 unreachable=0 failed=0
Step 14:- Start the database and listener
Step 15 :- Check the Opatch lsinventory of ORACLE_HOME
Catch Me On:- Hariprasath Rajaram
Telegram:https://t.me/joinchat/I_f4DhGF_Zifr9YZvvMkRg
LinkedIn:https://www.linkedin.com/in/hari-prasath-aa65bb19/
Facebook:https://www.facebook.com/HariPrasathdba
FB Group:https://www.facebook.com/groups/894402327369506/
FB Page: https://www.facebook.com/dbahariprasath/?
Twitter: https://twitter.com/hariprasathdba






