Last active
August 26, 2018 07:28
-
-
Save domgiles/23a9099240c046e7bdbe924a03f0e9c3 to your computer and use it in GitHub Desktop.
Simple "Oracle Database" hack in python to change the size of the redo logs files. It assumes that Oracle Managed Files are being used.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import argparse | |
import time | |
import cx_Oracle | |
from prettytable import PrettyTable | |
class RedoLogManager(): | |
def get_log_files_info(self, cursor): | |
cursor.execute('''SELECT group#, thread#, sequence#, bytes/(1024*1024), members, status FROM sys.v_$log''') | |
result = cursor.fetchall() | |
logs = [] | |
for row in result: | |
logs.append(row) | |
return logs | |
def get_standby_log_files_info(self, cursor): | |
cursor.execute('''SELECT group#, thread#, sequence#, bytes/(1024*1024), status FROM sys.v_$standby_log''') | |
result = cursor.fetchall() | |
logs = [] | |
for row in result: | |
logs.append(row) | |
return logs | |
def print_log_info(self, logs): | |
table = PrettyTable(["Group No.", "Thread No.", "Sequence No.", "Size (MB)", "No of Members", "Status"]) | |
for row in logs: | |
table.add_row(row) | |
print table | |
def print_standby_log_info(self, logs): | |
table = PrettyTable(["Group No.", "Thread No.", "Sequence No.", "Size (MB)", "Status"]) | |
for row in logs: | |
table.add_row(row) | |
print table | |
def display_log_info(self, username, password, connectstring): | |
with cx_Oracle.connect(username, password, connectstring, mode=cx_Oracle.SYSDBA) as connection: | |
cursor = connection.cursor() | |
print ("Current Redo Log configuration") | |
logs = self.get_log_files_info(cursor) | |
self.print_log_info(logs) | |
logs = self.get_standby_log_files_info(cursor) | |
if len(logs) != 0: | |
print('Standby Logs') | |
self.print_standby_log_info(logs) | |
def create_standby_logs(self, username, password, connectstring): | |
sb_log_statement = "alter database add standby logfile size {}M" | |
with cx_Oracle.connect(username, password, connectstring, mode=cx_Oracle.SYSDBA) as connection: | |
cursor = connection.cursor() | |
logs = self.get_log_files_info(cursor) | |
log_size = max((map(lambda x: x[3], logs))) | |
for i in range(0, len(logs) + 1): | |
cursor.execute(sb_log_statement.format(log_size)) | |
print("Created standby log files") | |
logs = self.get_standby_log_files_info(cursor) | |
self.print_standby_log_info(logs) | |
def change_redo_log_size(self, username, password, connectstring, size): | |
switch_statement = "alter system switch logfile" | |
drop_statement = "alter database drop logfile group {}" | |
create_statement = "alter database add logfile group {} size {}M" | |
# target_size = args.size*1024*1024 | |
target_size = size | |
with cx_Oracle.connect(username, password, connectstring, mode=cx_Oracle.SYSDBA) as connection: | |
cursor = connection.cursor() | |
print ("Current Redo Log configuration") | |
logs = self.get_log_files_info(cursor) | |
self.print_log_info(logs) | |
# number_of_log_groups = len(logs) | |
while True: | |
print(switch_statement) | |
cursor.execute(switch_statement) | |
logs = self.get_log_files_info(cursor) | |
incorrectly_sizes_logs = [row for row in logs if row[3] != target_size] | |
if len(incorrectly_sizes_logs) == 0: | |
print("All logs correctly sized. Finishing...") | |
break | |
inactive_rows = [row for row in logs if row[5] == 'INACTIVE' and row[3] != target_size] | |
if len(inactive_rows) > 0: | |
print(drop_statement.format(inactive_rows[0][0])) | |
cursor.execute(drop_statement.format(inactive_rows[0][0])) | |
print(create_statement.format(inactive_rows[0][0], target_size)) | |
cursor.execute(create_statement.format(inactive_rows[0][0], target_size)) | |
logs = self.get_log_files_info(cursor) | |
time.sleep(1) | |
print ("New Redo Log configuration") | |
logs = self.get_log_files_info(cursor) | |
self.print_log_info(logs) | |
if __name__ == '__main__': | |
parser = argparse.ArgumentParser(description='Adjust the size of all redo logs') | |
group = parser.add_mutually_exclusive_group(required=False) | |
parser.add_argument('-u', '--user', help='sys username', required=True) | |
parser.add_argument('-p', '--password', help='sys password', required=True) | |
parser.add_argument('-cs', r'--connect_string', help='connect string to database (container)', required=True) | |
group.add_argument('-s', '--size', help='new size of the redo logs (MB)', required=False, type=int) | |
group.add_argument('-d', '--display', help='just display the current size of the redo logs (MB)', dest='display_only', action='store_true', required=False) | |
group.add_argument('-sb', '--standby', help='create standby logs', dest='create_sb_logs', action='store_true', required=False) | |
args = parser.parse_args() | |
rlm = RedoLogManager() | |
if args.display_only: | |
rlm.display_log_info(args.user, args.password, args.connect_string) | |
elif args.create_sb_logs: | |
rlm.create_standby_logs(args.user, args.password, args.connect_string) | |
else: | |
rlm.change_redo_log_size(args.user, args.password, args.connect_string, args.size) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A simple python script to change the size of the redo logs for an Oracle Database. This isn't designed to work against a RAC cluster but could be changed to do so. It also depends on the use of Oracle Managed Files. Again this could be trivially changed as well...