From 51a522898f0edbe7ef1acba5e97df6f40728ec88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandru=20Tic=C4=83?= Date: Tue, 1 Nov 2022 09:15:16 +0200 Subject: [PATCH] Added support to upgrade the timezone of the db --- .../fragments/db_timezone_upgrade_support.yml | 3 + roles/oradb_tzupgrade/README.md | 61 ++++++++++++++ roles/oradb_tzupgrade/defaults/main.yml | 2 + roles/oradb_tzupgrade/meta/main.yml | 21 +++++ roles/oradb_tzupgrade/tasks/cdb.yml | 84 +++++++++++++++++++ roles/oradb_tzupgrade/tasks/main.yml | 9 ++ roles/oradb_tzupgrade/tasks/non_cdb.yml | 36 ++++++++ roles/oradb_tzupgrade/tasks/tzpatch_db.yml | 10 +++ roles/oradb_tzupgrade/vars/main.yml | 10 +++ 9 files changed, 236 insertions(+) create mode 100644 changelogs/fragments/db_timezone_upgrade_support.yml create mode 100644 roles/oradb_tzupgrade/README.md create mode 100644 roles/oradb_tzupgrade/defaults/main.yml create mode 100644 roles/oradb_tzupgrade/meta/main.yml create mode 100644 roles/oradb_tzupgrade/tasks/cdb.yml create mode 100644 roles/oradb_tzupgrade/tasks/main.yml create mode 100644 roles/oradb_tzupgrade/tasks/non_cdb.yml create mode 100644 roles/oradb_tzupgrade/tasks/tzpatch_db.yml create mode 100644 roles/oradb_tzupgrade/vars/main.yml diff --git a/changelogs/fragments/db_timezone_upgrade_support.yml b/changelogs/fragments/db_timezone_upgrade_support.yml new file mode 100644 index 000000000..4639c4190 --- /dev/null +++ b/changelogs/fragments/db_timezone_upgrade_support.yml @@ -0,0 +1,3 @@ +--- +minor_changes: + - added support to upgrade the timezone in the database using the oradb_tzupgrade role diff --git a/roles/oradb_tzupgrade/README.md b/roles/oradb_tzupgrade/README.md new file mode 100644 index 000000000..a80b3d195 --- /dev/null +++ b/roles/oradb_tzupgrade/README.md @@ -0,0 +1,61 @@ +# oradb-tzupgrade + +This role can be used to apply the latest timezone upgrade for the +selected Oracle databases. This means that the Oracle home must be +first patched with a higher version of the timezone file. You may use +[oraswdb_manage_patches](/roles/oraswdb_manage_patches) role to +automate the timezone patching of the oracle home. Please note that as +part of the timezone upgrade the database is restarted, so you have to +consider this if high availability is important. Nevertheless, if the +database is already upgraded with the latest timezone file available +in the Oracle home then the upgrade is skipped and no instance restart +is initiated. + +## Role Variables + +You may customize this role by setting the following variables: + +* `oracle_user`: oracle +The OS user to be used when connecting to the Oracle instance and do the +timezone upgrade. + +## Playbook Examples + +The following playbook patches the Oracle home with version 39 of the +timezone file and then applies the corresponding upgrade into the +database: + +``` +- name: Upgrade Oracle timezone + hosts: all + become: true + vars: + apply_patches_db: true + oracle_sw_unpack: true + oracle_sw_patches: + - filename: p34533061_190000_Linux-x86-64.zip + patchid: 34533061 + version: 19.3.0.0 + description: DB Timezone V39 + creates: 34533061/README.html + tz_latest_patch: + 19c: + opatch: + - patchid: 34533061 + state: present + stop_processes: false + collections: + - opitzconsulting.ansible_oracle + tasks: + - set_fact: + db_homes_config: "{{ db_homes_config | combine(tz_latest_patch, recursive=true) }}" + + - ansible.builtin.include_role: + name: "oraswdb_manage_patches" + + - ansible.builtin.include_role: + name: "oradb_tzupgrade" +``` + + + diff --git a/roles/oradb_tzupgrade/defaults/main.yml b/roles/oradb_tzupgrade/defaults/main.yml new file mode 100644 index 000000000..a2f8423e8 --- /dev/null +++ b/roles/oradb_tzupgrade/defaults/main.yml @@ -0,0 +1,2 @@ +--- +oracle_user: oracle diff --git a/roles/oradb_tzupgrade/meta/main.yml b/roles/oradb_tzupgrade/meta/main.yml new file mode 100644 index 000000000..22efa4f0f --- /dev/null +++ b/roles/oradb_tzupgrade/meta/main.yml @@ -0,0 +1,21 @@ +--- +galaxy_info: + role_name: oradb_tzupgrade + namespace: opitzconsulting + author: Alexandru Tică + description: Manage timezone upgrades for an Oracle Database + + license: license (MIT) + + min_ansible_version: 2.9.0 + + platforms: + - name: EL + versions: + - "6" + - "7" + - "8" + + galaxy_tags: + - database + - oracle diff --git a/roles/oradb_tzupgrade/tasks/cdb.yml b/roles/oradb_tzupgrade/tasks/cdb.yml new file mode 100644 index 000000000..98382af27 --- /dev/null +++ b/roles/oradb_tzupgrade/tasks/cdb.yml @@ -0,0 +1,84 @@ +--- +- name: oradb_tzupgrade | Perform timezone checks for CDB$ROOT and PDB$SEED first + oracle_sqldba: + catcon_pl: "{{ oracle_db_home }}/rdbms/admin/utltz_upg_check.sql" + creates_sql: "{{ tz_check_query }}" + oracle_home: "{{ oracle_db_home }}" + oracle_db_name: "{{ oracle_db_name }}" + scope: pdbs + pdb_list: "CDB$ROOT PDB$SEED" + become_user: "{{ oracle_user }}" + +- name: oradb_tzupgrade | Upgrade timezone for CDB$ROOT and PDB$SEED + oracle_sqldba: + catcon_pl: "{{ oracle_db_home }}/rdbms/admin/utltz_upg_apply.sql" + creates_sql: "{{ tz_check_query }}" + oracle_home: "{{ oracle_db_home }}" + oracle_db_name: "{{ oracle_db_name }}" + scope: pdbs + pdb_list: "CDB$ROOT PDB$SEED" + become_user: "{{ oracle_user }}" + +- name: oradb_tzupgrade | Get all open PDBs + oracle_sqldba: + sqlselect: "select listagg(name, ' ') within group (order by name) pdb_list from v$pdbs where open_mode in ('READ WRITE', 'MIGRATE')" + oracle_home: "{{ oracle_db_home }}" + oracle_db_name: "{{ oracle_db_name }}" + become_user: "{{ oracle_user }}" + register: pdbs_info + +- ansible.builtin.set_fact: # noqa unnamed-task + candidate_pdbs: "{{ pdbs_info.state.ROW[0].PDB_LIST | default('') }}" + +- ansible.builtin.debug: # noqa unnamed-task + msg: "Candidate PDBs: {{ candidate_pdbs }}" + +- block: # noqa unnamed-task + + - name: oradb_tzupgrade | Perform timezone checks for the candidate PDBs + oracle_sqldba: + catcon_pl: "{{ oracle_db_home }}/rdbms/admin/utltz_upg_check.sql" + creates_sql: "{{ tz_check_query }}" + oracle_home: "{{ oracle_db_home }}" + scope: pdbs + pdb_list: "{{ candidate_pdbs }}" + oracle_db_name: "{{ oracle_db_name }}" + become_user: "{{ oracle_user }}" + + - name: oradb_tzupgrade | Upgrade timezone for the candidate PDBs + oracle_sqldba: + catcon_pl: "{{ oracle_db_home }}/rdbms/admin/utltz_upg_apply.sql" + creates_sql: "{{ tz_check_query }}" + oracle_home: "{{ oracle_db_home }}" + scope: pdbs + pdb_list: "{{ candidate_pdbs }}" + oracle_db_name: "{{ oracle_db_name }}" + become_user: "{{ oracle_user }}" + + when: candidate_pdbs != "" + +- name: oradb_tzupgrade | Get post upgrade timezone status info + oracle_sqldba: + sql: | + set tab off + set head on + set pages 99 + set lines 200 + column current_tz format a20 + column latest_tz format a20 + column container format a20 + column open_mode format a15 + alter session set "_exclude_seed_cdb_view"=false; + select (select name from v$containers where con_id=t.con_id) container, + (select open_mode from v$containers where con_id = t.con_id) open_mode, + value$ current_tz, + to_char(dbms_dst.get_latest_timezone_version) latest_tz + from containers(SYS.PROPS$) t where NAME='DST_PRIMARY_TT_VERSION' order by 1; + oracle_home: "{{ oracle_db_home }}" + oracle_db_name: "{{ oracle_db_name }}" + become_user: "{{ oracle_user }}" + changed_when: false + register: post_status_info + +- ansible.builtin.debug: # noqa unnamed-task + msg: "{{ post_status_info.msg | split('\n') }}" diff --git a/roles/oradb_tzupgrade/tasks/main.yml b/roles/oradb_tzupgrade/tasks/main.yml new file mode 100644 index 000000000..94628f244 --- /dev/null +++ b/roles/oradb_tzupgrade/tasks/main.yml @@ -0,0 +1,9 @@ +--- +- ansible.builtin.include_tasks: tzpatch_db.yml + # noqa unnamed-task + vars: + oradb_entry: "{{ item }}" + with_items: "{{ oracle_databases }}" + when: item.state | lower == 'present' + loop_control: + label: "home: {{ item.home }} db_name: {{ item.oracle_db_name }}" diff --git a/roles/oradb_tzupgrade/tasks/non_cdb.yml b/roles/oradb_tzupgrade/tasks/non_cdb.yml new file mode 100644 index 000000000..95bd528f7 --- /dev/null +++ b/roles/oradb_tzupgrade/tasks/non_cdb.yml @@ -0,0 +1,36 @@ +--- +- name: oradb_tzupgrade | Perform timezone checks for a non-CDB database + oracle_sqldba: + sql: "@?/rdbms/admin/utltz_upg_check.sql" + creates_sql: "{{ tz_check_query }}" + oracle_home: "{{ oracle_db_home }}" + oracle_db_name: "{{ oracle_db_name }}" + become_user: "{{ oracle_user }}" + +- name: oradb_tzupgrade | Apply the timezone upgrade for the non-CDB database + oracle_sqldba: + sql: "@?/rdbms/admin/utltz_upg_apply.sql" + creates_sql: "{{ tz_check_query }}" + oracle_home: "{{ oracle_db_home }}" + oracle_db_name: "{{ oracle_db_name }}" + become_user: "{{ oracle_user }}" + +- name: oradb_tzupgrade | Get post upgrade timezone status info + oracle_sqldba: + sql: | + set lines 200 + set head on + set pages 99 + set tab off + column current_tz format a20 + column latest_tz format a20 + SELECT property_value current_tz, to_char(dbms_dst.get_latest_timezone_version) latest_tz + FROM database_properties WHERE property_name LIKE 'DST_PRIMARY_TT_VERSION'; + oracle_home: "{{ oracle_db_home }}" + oracle_db_name: "{{ oracle_db_name }}" + become_user: "{{ oracle_user }}" + changed_when: false + register: post_status_info + +- ansible.builtin.debug: # noqa unnamed-task + msg: "{{ post_status_info.msg | split('\n') }}" diff --git a/roles/oradb_tzupgrade/tasks/tzpatch_db.yml b/roles/oradb_tzupgrade/tasks/tzpatch_db.yml new file mode 100644 index 000000000..744d1a02f --- /dev/null +++ b/roles/oradb_tzupgrade/tasks/tzpatch_db.yml @@ -0,0 +1,10 @@ +--- +- name: oradb_tzupgrade | Determine the database type + oracle_sqldba: + sqlselect: "select decode(cdb, 'YES', 'cdb', 'non_cdb') dbtype from v$database" + oracle_home: "{{ oracle_db_home }}" + oracle_db_name: "{{ oracle_db_name }}" + become_user: "{{ oracle_user }}" + register: dbtype + +- ansible.builtin.include_tasks: "{{ dbtype.state.ROW[0].DBTYPE }}.yml" # noqa unnamed-task diff --git a/roles/oradb_tzupgrade/vars/main.yml b/roles/oradb_tzupgrade/vars/main.yml new file mode 100644 index 000000000..5777c96c2 --- /dev/null +++ b/roles/oradb_tzupgrade/vars/main.yml @@ -0,0 +1,10 @@ +--- +oracle_db_name: "{{ oradb_entry.oracle_db_instance_name | default(oradb_entry.oracle_db_unique_name | default(oradb_entry.oracle_db_name)) }}" +oracle_db_home: "{%- if oradb_entry is defined -%}\ + {%- if db_homes_config[oradb_entry.home]['oracle_home'] is defined -%}\ + {{ db_homes_config[oradb_entry.home]['oracle_home'] }}\ + {%- else -%}\ + {{ oracle_base }}/{{ db_homes_config[oradb_entry.home]['version'] }}/{{ db_homes_config[oradb_entry.home]['home'] }}\ + {%- endif -%}\ + {%- endif -%}" +tz_check_query: "SELECT decode(property_value, dbms_dst.get_latest_timezone_version, 1, 0) status FROM database_properties WHERE property_name LIKE 'DST_PRIMARY_TT_VERSION'"