|
1 | | -#!/usr/bin/python3 |
2 | | -# |
3 | 1 | import os |
4 | 2 | import sys |
5 | 3 | import json |
|
21 | 19 | import getpass |
22 | 20 | import functools |
23 | 21 | from datetime import datetime |
| 22 | +import re |
24 | 23 |
|
25 | 24 |
|
26 | 25 | print = functools.partial(print, flush=True) |
@@ -105,6 +104,14 @@ def split_into_lines(items, to_upper=True, chunk_size=10): |
105 | 104 | item_list = ",\n".join(chunks) |
106 | 105 | return item_list |
107 | 106 |
|
| 107 | +# Escape '$' in table names for shell safety (TABLE$1 --> TABLE\$1) |
| 108 | +def escape_dollar(raw): |
| 109 | + tables = [] |
| 110 | + for tbl in raw.split(','): |
| 111 | + tbl = re.sub(r'(?<!\\)\$', r'\$', tbl.strip()) |
| 112 | + tables.append(tbl) |
| 113 | + return ",".join(tables) |
| 114 | + |
108 | 115 | class ConsoleLogger: |
109 | 116 | """ |
110 | 117 | A class to send Python output simultaneously to the terminal and a log file. |
@@ -281,6 +288,8 @@ def _load_env_variables(self): |
281 | 288 | value = self._defaults.get(var, '').strip() |
282 | 289 | if value and (var == 'TABLESPACES' or var == 'SCHEMAS'): |
283 | 290 | value = value.replace(" ", "") |
| 291 | + if value and (var == 'EXCLUDE_TABLES'): |
| 292 | + value = escape_dollar(value) |
284 | 293 | setattr(self, var, value) |
285 | 294 |
|
286 | 295 | if getattr(self, 'ZDM_BASED_TRANSPORT').strip(): |
@@ -642,10 +651,18 @@ def _get_schemas(self, template, user_type=None): |
642 | 651 | sql_script = template.get('get_common_schemas') |
643 | 652 | elif user_type == "required": |
644 | 653 | ts_list = split_into_lines(self._env.TABLESPACES) |
| 654 | + if self._env.DB_VERSION == '11g': |
| 655 | + l_user_list_clause = "username not in ('SYS','SYSTEM')" |
| 656 | + else: |
| 657 | + l_user_list_clause = "username not in ('SYS','SYSTEM') and common='NO'" |
645 | 658 | Configuration.substitutions = { |
646 | 659 | 'ts_list': ts_list.upper(), |
| 660 | + 'l_user_list_clause': l_user_list_clause, |
647 | 661 | } |
648 | | - sql_script = template.get('owners_in_tablespaces') |
| 662 | + if not self._env.SCHEMAS: |
| 663 | + sql_script = template.get('owners_and_grantee_in_tablespaces') |
| 664 | + else: |
| 665 | + sql_script = template.get('owners_in_tablespaces') |
649 | 666 | else: |
650 | 667 | if not self._env.SCHEMAS: |
651 | 668 | print("No schemas provided. Returning a list of required users.") |
@@ -1273,7 +1290,8 @@ def tts_src_export_tde_keys(self, template): |
1273 | 1290 | } |
1274 | 1291 |
|
1275 | 1292 | try: |
1276 | | - if not sqlplus.run_sql(template.get('tts_src_export_tde_keys')) or not os.path.exists(tde_keys_path): |
| 1293 | + # if not sqlplus.run_sql(template.get('tts_src_export_tde_keys')) or not os.path.exists(tde_keys_path): |
| 1294 | + if not sqlplus.run_sql(template.get('tts_src_export_tde_keys')): |
1277 | 1295 | print("Export TDE Keys failed. \n") |
1278 | 1296 | raise RuntimeError("TDE key export command failed.") |
1279 | 1297 | print(f"TDE keys exported successfully to {tde_keys_path}.") |
@@ -1458,9 +1476,13 @@ def tts_src_get_channel(self): |
1458 | 1476 | self.host_array = self._env.DB_PROPS_ARRAY[13].split(';') |
1459 | 1477 | self._env.CPU_COUNT = self.calculate_cpu_count() |
1460 | 1478 |
|
| 1479 | + if not self._env.DB_PROPS_ARRAY[13]: |
| 1480 | + print("Invalid DATABASE_NAME {0} or the PDB is not open in READ WRITE mode in any instance. Exiting...".format(self._env.DATABASE_NAME)) |
| 1481 | + sys.exit(1) |
| 1482 | + |
1461 | 1483 | if not self.host_array or self._env.CPU_COUNT <= 0: |
1462 | 1484 | print("No instances or CPUs to construct channel string. Exiting...") |
1463 | | - return False |
| 1485 | + sys.exit(1) |
1464 | 1486 |
|
1465 | 1487 | rman_parms = "" |
1466 | 1488 | if self._env.STORAGE_TYPE == "FSS": |
@@ -1581,6 +1603,9 @@ def tts_src_backup_tablespaces(self, backup_type, template): |
1581 | 1603 | if self._env.DB_VERSION != '11g': |
1582 | 1604 | allow_inconsistent = "allow inconsistent" |
1583 | 1605 |
|
| 1606 | + # Remove DATAPUMP Clause from rman restore |
| 1607 | + tablespace_dump_clause = "" |
| 1608 | + |
1584 | 1609 | # 11g -> for transport not supported, add section size clause |
1585 | 1610 | # 12c/19c : |
1586 | 1611 | # if src_platform = 13 : no need of for transport, add section size clause |
@@ -2110,7 +2135,7 @@ def main(args): |
2110 | 2135 | exit(1) |
2111 | 2136 | log_end_time(start_time) |
2112 | 2137 |
|
2113 | | - _env.platform_id = int(_env.DB_PROPS_ARRAY[4]) |
| 2138 | + _env.platform_id = int(_env.DB_PROPS_ARRAY[3]) |
2114 | 2139 | _env.version_full = _env.DB_PROPS_ARRAY[9] |
2115 | 2140 | _env.bigfile_tablespaces = _env.DB_PROPS_ARRAY[15].replace(';', ',') |
2116 | 2141 | _env.smallfile_tablespaces = _env.DB_PROPS_ARRAY[16].replace(';', ',') |
|
0 commit comments