Skip to content

Commit a70c6e0

Browse files
authored
Merge pull request #67 from jpmc-github/tts-backup-python-02232026
updated tts-backup.py, version.txt and ttsTemplate.txt
2 parents 1150a38 + ff93f41 commit a70c6e0

File tree

3 files changed

+50
-7
lines changed

3 files changed

+50
-7
lines changed

migration-tools/tts-backup-python/tts-backup.py

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#!/usr/bin/python3
2-
#
31
import os
42
import sys
53
import json
@@ -21,6 +19,7 @@
2119
import getpass
2220
import functools
2321
from datetime import datetime
22+
import re
2423

2524

2625
print = functools.partial(print, flush=True)
@@ -105,6 +104,14 @@ def split_into_lines(items, to_upper=True, chunk_size=10):
105104
item_list = ",\n".join(chunks)
106105
return item_list
107106

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+
108115
class ConsoleLogger:
109116
"""
110117
A class to send Python output simultaneously to the terminal and a log file.
@@ -281,6 +288,8 @@ def _load_env_variables(self):
281288
value = self._defaults.get(var, '').strip()
282289
if value and (var == 'TABLESPACES' or var == 'SCHEMAS'):
283290
value = value.replace(" ", "")
291+
if value and (var == 'EXCLUDE_TABLES'):
292+
value = escape_dollar(value)
284293
setattr(self, var, value)
285294

286295
if getattr(self, 'ZDM_BASED_TRANSPORT').strip():
@@ -642,10 +651,18 @@ def _get_schemas(self, template, user_type=None):
642651
sql_script = template.get('get_common_schemas')
643652
elif user_type == "required":
644653
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'"
645658
Configuration.substitutions = {
646659
'ts_list': ts_list.upper(),
660+
'l_user_list_clause': l_user_list_clause,
647661
}
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')
649666
else:
650667
if not self._env.SCHEMAS:
651668
print("No schemas provided. Returning a list of required users.")
@@ -1273,7 +1290,8 @@ def tts_src_export_tde_keys(self, template):
12731290
}
12741291

12751292
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')):
12771295
print("Export TDE Keys failed. \n")
12781296
raise RuntimeError("TDE key export command failed.")
12791297
print(f"TDE keys exported successfully to {tde_keys_path}.")
@@ -1458,9 +1476,13 @@ def tts_src_get_channel(self):
14581476
self.host_array = self._env.DB_PROPS_ARRAY[13].split(';')
14591477
self._env.CPU_COUNT = self.calculate_cpu_count()
14601478

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+
14611483
if not self.host_array or self._env.CPU_COUNT <= 0:
14621484
print("No instances or CPUs to construct channel string. Exiting...")
1463-
return False
1485+
sys.exit(1)
14641486

14651487
rman_parms = ""
14661488
if self._env.STORAGE_TYPE == "FSS":
@@ -1581,6 +1603,9 @@ def tts_src_backup_tablespaces(self, backup_type, template):
15811603
if self._env.DB_VERSION != '11g':
15821604
allow_inconsistent = "allow inconsistent"
15831605

1606+
# Remove DATAPUMP Clause from rman restore
1607+
tablespace_dump_clause = ""
1608+
15841609
# 11g -> for transport not supported, add section size clause
15851610
# 12c/19c :
15861611
# if src_platform = 13 : no need of for transport, add section size clause
@@ -2110,7 +2135,7 @@ def main(args):
21102135
exit(1)
21112136
log_end_time(start_time)
21122137

2113-
_env.platform_id = int(_env.DB_PROPS_ARRAY[4])
2138+
_env.platform_id = int(_env.DB_PROPS_ARRAY[3])
21142139
_env.version_full = _env.DB_PROPS_ARRAY[9]
21152140
_env.bigfile_tablespaces = _env.DB_PROPS_ARRAY[15].replace(';', ',')
21162141
_env.smallfile_tablespaces = _env.DB_PROPS_ARRAY[16].replace(';', ',')

migration-tools/tts-backup-python/ttsTemplate.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,18 @@ get_local_schemas:
274274
owners_in_tablespaces:
275275
select distinct owner from dba_tables where tablespace_name in (${ts_list});
276276

277+
owners_and_grantee_in_tablespaces:
278+
select distinct username from (
279+
select owner as username from dba_tables where tablespace_name in (${ts_list})
280+
union
281+
select grantee as username from dba_tab_privs
282+
where owner in (
283+
select owner from dba_tables where tablespace_name in (${ts_list})
284+
) and grantee in (
285+
select username from dba_users where ${l_user_list_clause}
286+
)
287+
);
288+
277289
object_validation:
278290
-- SEGMENTS : Physical Segments (tables, indexes, lobs, partitions etc.)
279291
SELECT 'SEGMENT,' || owner || '.' || segment_name

migration-tools/tts-backup-python/version.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
26.2.1.2 - 05 February 2005
1+
26.2.3.2 - 20 February 2026
2+
+ Escape '$' in table names (EXCLUDE_TABLES) e.g. TABLE$1 --> TABLE\$1
3+
+ Add users to schema list those have obj grants on tbs list if schema list not provided
4+
- remove tde keys file check to avoid platform dependency issues
5+
+ Improve error messages incase of invalid user input for DATABASE_NAME
6+
7+
26.2.1.2 - 05 February 2026
28
+ Added support to query the TTS Backup Utility version
39
+ Updated RMAN and Data Pump job names to include the project name
410
+ Added validation to ensure the tablespace list remains unaltered across backups

0 commit comments

Comments
 (0)