home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 11 Util
/
11-Util.zip
/
tarv314.zip
/
RESETLOG.CMD
< prev
next >
Wrap
OS/2 REXX Batch file
|
1992-12-04
|
111KB
|
2,347 lines
/******************************************************************
* MODULE NAME: RESETLOG *
* *
* DESCRIPTIVE NAME: Reset the Log Control File *
* *
* LPP NAME: Standalone Tool *
* *
* DESCRIPTION: This routine provides a mechanism for resetting *
* or initializing the Log Control File to a state *
* in which it appears that the database no longer *
* needs recovery. *
* *
* Caution should be exercised in using this tool *
* because it will prevent any committed changes *
* which did not make it to media from being *
* recovered in the database. As a result, there *
* could be index and table mismatches and *
* referential integrity violations. *
* *
* DEPENDENCIES: *
* SYSTEM CONFIRUATION: *
* - OS/2 EE 1.2+ *
* *
* LANGUAGE INTERPRETER: *
* - OS/2 Rexx Interpreter *
* *
* PREREQUISTIES: None *
* *
* *
* RESTRICTIONS: None *
* *
* INPUT: Database name *
* *
* *
* OUTPUT: Log Control File reset. *
* Usable database. *
* *
* *
* HOST LANGUAGE: OS/2 Rexx *
* *
* LAST CHANGE DATE: Version 1.4 09/29/91 *
* *
* *
******************************************************************/
parse upper arg dbname rptname
'@echo off'
TRACE OFF
numeric digits 15 /* Set precision for arithmetic operations */
dbpath = '' /* Initialize database path specification */
logpath = '' /* Initialize log path specification */
cr_lf = d2c(13) || d2c(10) /* Line End characters */
report_open = 'NO' /* Initialize Report Open Indicator */
/*********************************************
Check the Program Input Arguments
*********************************************/
if dbname = '?' then
do
call general_help
signal xit
end
else /* No Help requested, so check the input parameters */
call chkargs
'cls'
say ' '
say ,
" ╔══════════════════════════════════════════════════════════════════════╗ "
say ,
" ║ ** NOTICE ** NOTICE ** NOTICE ** NOTICE ** NOTICE ** ║ "
say ,
" ║ ║ "
say ,
" ║ THE LOG CONTROL FILE IS ABOUT TO BE RESET !! ║ "
say ,
" ║ ║ "
say ,
" ║ Caution: This should only be done as a very last resort. ║ "
say ,
" ║ It will prevent all committed changes in the ║ "
say ,
" ║ Write-Ahead Log from being applied to the database. ║ "
say ,
" ║ ║ "
say ,
" ║ ┌─────────────────────────────────────────────────┐ ║ "
say ,
" ║ │ WARNING: Data Integrity may be lost. │ ║ "
say ,
" ║ └─────────────────────────────────────────────────┘ ║ "
say ,
" ║ ║ "
say ,
" ║ Would you like to Reset the Log Control File now? (y/n) ║ "
say ,
" ║ If so, type 'y' and press ENTER; ║ "
say ,
" ║ Otherwise, type 'n' and press ENTER. ║ "
say ,
" ╚══════════════════════════════════════════════════════════════════════╝ "
say " "
say " "
pull reset_decision
if reset_decision = 'Y' then
do
/*********************************************
Determine the Database Subdirectory
*********************************************/
say '....Scanning the Database Directory'
call getddir
if dbpath = '' then
call errxit 'The database was not found on the file system.'
/*********************************************
Construct the Database Configuration File
*********************************************/
dbcon_name = dbpath || 'SQLDBCON'
/*********************************************
Check Existence of Configuration File
*********************************************/
rc = stream(dbcon_name, 'c', 'query exist')
if rc = '' then
do
call errxit 'The Database Configuration File could not be found.'
end
/*********************************************
Open the Report File if specified
*********************************************/
if rptname \= '' then
do
rc = stream(rptname, 'c', 'open')
if (rc \= 'READY:') & (rc \= 'READY') then
do
call errxit 'The Report File could not be opened.'
end
report_open = 'YES' /* Report is now Open Indicator */
/*********************************************
Set the Write Cursor to Append to the Report File
*********************************************/
/* Locate the last byte in the file */
eofpos = stream(rptname, 'c', 'query size')
/* Make sure the file is not empty before reading
the last byte */
if eofpos > 0 then
do
/* Position the Write Cursor on the last byte
of the file if it is an EOF control;
otherwise leave the Write Cursor positioned
after the last byte */
if charin(rptname, eofpos, 1) = x2c('1A') then
r = stream(rptname, 'c', 'seek -1')
end
/*********************************************
Write the Report File Header
*********************************************/
call rpthdr
end
/*********************************************
Open the Database Configuration File
*********************************************/
rc = stream(dbcon_name, 'c', 'open')
if (rc \= 'READY:') & (rc \= 'READY') then
do
call errxit 'The Database Configuration File could not be opened.'
end
/*********************************************
Find the Path to the Log Files
*********************************************/
say '....Examining the Database Configuration'
call findlog
/*********************************************
Close the Database Configuration File
*********************************************/
rc = stream(dbcon_name, 'c', 'close')
/*********************************************
Construct Log Control File Name
Note: The Log Control File should exist in
the database subdirectory.
*********************************************/
if stream(dbpath || 'SQLOGCTL.LFH', 'c', 'query exist') = '' then
call errxit 'The Log Control File could not be found.'
else
/* Construct the Log Control File Name */
logctl_name = dbpath || 'SQLOGCTL.LFH'
/*********************************************
Open the Log Control File
*********************************************/
rc = stream(logctl_name, 'c', 'open')
if (rc \= 'READY:') & (rc \= 'READY') then
do
call errxit 'The Log Control File could not be opened.'
end
/*********************************************
Reset the Log Control File
*********************************************/
call reset
/*********************************************
Close the Log Control File
*********************************************/
rc = stream(logctl_name, 'c', 'close')
/*********************************************
Successful Program Completion
*********************************************/
say ' '
say 'The Reset Log Tool completed.'
signal finish
end
else /* User chose not to reset the Log Control File */
say 'Program terminated by user -- Log Control File not reset.'
/*********************************************
PROGRAM EXITS
*********************************************/
/*********************************************
Final Program Clean-Up
*********************************************/
finish:
/*********************************************
Close the Report File if specified
*********************************************/
if report_open = 'YES' then
rc = stream(rptname, 'c', 'close')
xit:
/* Exit the program */
exit
/*********************************************
RESETLOG Error Exit
*********************************************/
errxit:
parse arg msg_text
/* Display the Error Message */
say ' '
say msg_text
/* Complete the Tool Cleanup */
signal finish
return
/*********************************************
SQL (Database Manager) Error Exit
*********************************************/
sqlxit:
/* Get the formatted SQL message */
call SQLDBS 'GET MESSAGE INTO :sql_msg LINEWIDTH 70'
if result = 0 then
do
/* Formatting successful - Display formatted message */
say ' '
say sql_msg
end
else
do
/* Formatting unsuccessful - Display unformatted message */
say ' '
say SQLMSG
end
/* Complete the Tool Cleanup */
signal finish
return
/*********************************************
SUBROUTINES
*********************************************/
/******************************************************************
* SUBROUTINE: CHKARGS *
* *
* DESCRIPTIVE NAME: Check the Program Input Arguments *
* *
* DESCRIPTION: This routine checks the validity of the input *
* arguments for the program. If any arguments *
* are not specified, then the user is prompted to *
* type the required argument. *
* *
* INPUT: none *
* *
* *
* OUTPUT: none *
* *
******************************************************************/
chkargs:
if dbname = '' then /* Prompt for the Database name if not input */
do
'cls'
say " "
say ,
" ╔══════════════════════════════════════════════════════════════════════╗ "
say ,
" ║ ║ "
say ,
" ║ Please type the input Database Name and press ENTER: ║ "
say ,
" ║ ║ "
say ,
" ╚══════════════════════════════════════════════════════════════════════╝ "
say " "
say " "
pull dbname
end
return
/******************************************************************
* SUBROUTINE: GETDDIR *
* *
* DESCRIPTIVE NAME: Get the Database Directory *
* *
* DESCRIPTION: This routine scans the System Database Directory *
* to determine the Drive containing the specified *
* database. If it finds the database on a local *
* volume, then it calls another routine to *
* scan the Volume Database Directory to determine *
* the subdirectory containing the database. *
* *
* *
* INPUT: none *
* *
* *
* OUTPUT: none *
* *
******************************************************************/
getddir:
/*********************************************
Register SQLDBS with REXX
*********************************************/
/* Check if SQLDBS function is currently registered */
if Rxfuncquery('SQLDBS') \= 0 then
do
/* Register SQLDBS function */
rcy = Rxfuncadd('SQLDBS','SQLAR','SQLDBS')
if rcy \= 0 then
call errxit 'Database Manager registration error'
end /* end if */
/*********************************************
Register SQLEXEC with REXX
*********************************************/
/* Check if SQLEXEC function is currently registered */
if Rxfuncquery('SQLEXEC') \= 0 then
do
/* Register SQLEXEC function */
rcy = Rxfuncadd('SQLEXEC','SQLAR','SQLEXEC')
if rcy \= 0 then
call errxit 'Database Manager registration error'
end /* end if */
/*********************************************
Scan System Directory for Database Name
*********************************************/
call SQLDBS 'open database directory on 0 using :dhandle'
if sqlca.sqlcode < 0 then
signal sqlxit
do while sqlca.sqlcode = 0
call SQLDBS 'get database directory entry :dhandle.1'
if sqlca.sqlcode = 0 then
do
if SQLDINFO.1 = dbname then
do
db_drive = SQLDINFO.3
dbname = strip(dbname)
call scanvol
leave
end
end
end
call SQLDBS 'close database directory :dhandle.1'
return
/******************************************************************
* SUBROUTINE: SCANVOL *
* *
* DESCRIPTIVE NAME: Scan the Volume Database Directory *
* *
* DESCRIPTION: This routine scans the Volume Database Directory *
* to determine the Subdirectory containing the *
* specified database. *
* *
* *
* INPUT: none *
* *
* *
* OUTPUT: none *
* *
******************************************************************/
scanvol:
/* Scan volume directory for name */
dbpath = ''
call SQLDBS 'open database directory on 'left(db_drive,1)' using :vhandle'
if sqlca.sqlcode = 0 then
do
do forever
call SQLDBS 'get database directory entry :vhandle.1'
if SQLCA.SQLCODE = 1014 then
do
say 'No entry found in volume directory for drive 'db_drive'...'
leave
end
if SQLDINFO.1 = dbname then
do
dbdir = SQLDINFO.4
leave
end
end
call SQLDBS 'close database directory :vhandle.1'
dbpath = db_drive'\'dbdir'\'
end
return
/******************************************************************
* SUBROUTINE: RPTHDR *
* *
* DESCRIPTIVE NAME: Write the Report File Header *
* *
* DESCRIPTION: This routine writes the information that appears *
* at the beginning of the Report for a given *
* execution of RESETLOG. *
* *
* Note: The Report File must already be opened. *
* *
* INPUT: none *
* *
* *
* OUTPUT: none *
* *
******************************************************************/
rpthdr:
/* Define Various text lines for the Report */
eqlines = '==================================================' || ,
'============================'
ttline = ' RESETLOG (V 3.1) Report - ' || date('N') || ' ' || ,
time('C')
dbline = ' Database: ' || dbname
dbpline = ' Database Path: ' || dbpath
seplines = '--------------------------------------------------' || ,
'----------------------------'
/* Construct the Report Header text */
rpthdr_text = ' ' || cr_lf || ,
' ' || cr_lf || ,
eqlines || cr_lf || ,
eqlines || cr_lf || ,
eqlines || cr_lf || ,
eqlines || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
ttline || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
dbline || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
seplines || cr_lf || ,
seplines || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf
/* Write the Report Header to the Report File */
call wrt2rpt rpthdr_text
return
/******************************************************************
* SUBROUTINE: WRT2RPT *
* *
* DESCRIPTIVE NAME: Write to the Report File *
* *
* DESCRIPTION: This routine provides a common routine for *
* writing information to the Report File. This *
* routine checks to verify that the Report File *
* was specified as input to the tool and was *
* subsequently opened before writing the data. *
* *
* INPUT: Text to be written to the Report File *
* *
* *
* OUTPUT: none *
* *
******************************************************************/
wrt2rpt:
parse arg report_text
if report_open = 'YES' then
do
rc = lineout(rptname, report_text)
end
return
/******************************************************************
* SUBROUTINE: FINDLOG *
* *
* DESCRIPTIVE NAME: Find the Path to the Log Files *
* *
* DESCRIPTION: This routine determines the path containing the *
* Log files for the database. *
* *
* *
* INPUT: none *
* *
* *
* OUTPUT: none *
* *
******************************************************************/
findlog:
/*********************************************
Define Offsets to Fields in the Database
Configuration File
*********************************************/
call defoff_dbcon
/*********************************************
Get Data in the Database Configuration File
*********************************************/
call getdata_dbcon
/*********************************************
Determine the Path to the Log Files
*********************************************/
say '....Determining Log File Location'
call getlogpath
return
/******************************************************************
* SUBROUTINE: DEFOFF_DBCON *
* *
* DESCRIPTIVE NAME: Define Offsets to Fields in Database Config *
* *
* DESCRIPTION: This routine defines the offsets for the fields *
* in the Database Configuration File. *
* *
* INPUT: none *
* *
* *
* OUTPUT: none *
* *
******************************************************************/
defoff_dbcon:
/*********************************************
Define Page Offset Constants
(Note: These offsets are 1-origin from the Start of the Page)
(Note: The length values are in terms of character bytes.)
*********************************************/
dbcon = 1 /* Offset to the Database Configuration */
/*********************************************
Define Offsets within the Database Configuration Description
(Note: These offsets are 0-origin from the Start of the
Database Configuration File.)
*********************************************/
dbc_chksumo = 0 /* Checksum field offset */
dbc_chksuml = 4 /* length */
dbc_titleo = 4 /* Title field offset */
dbc_titlel = 12 /* length */
dbc_relo = 16 /* Release field offset */
dbc_rell = 2 /* length */
dbc_pad1o = 18 /* Pad for Long Boundary field offset */
dbc_pad1l = 2 /* length */
dbc_logsizo = 20 /* Log File Size (4K Pages) field offset */
dbc_logsizl = 4 /* length */
dbc_logexto = 24 /* Log File Extent Size field offset */
dbc_logextl = 4 /* length */
dbc_maxexto = 28 /* Max Extents field offset */
dbc_maxextl = 4 /* length */
dbc_dlchko = 32 /* Deadlock Check Interval field offset */
dbc_dlchkl = 4 /* length */
dbc_mseedo = 36 /* Database Seed (masked) field offset */
dbc_mseedl = 4 /* length */
dbc_pad2o = 40 /* Pad field offset */
dbc_pad2l = 4 /* length */
dbc_unseedo = 44 /* Unmasked Database Seed field offset */
dbc_unseedl = 4 /* length */
dbc_stmpo = 48 /* Timestamp field offset */
dbc_stmpl = 10 /* length */
dbc_lcklsto = 58 /* Maximum Storage for LockList offset */
dbc_lcklstl = 2 /* length */
dbc_buffo = 60 /* Size of buffer pool offset */
dbc_buffl = 2 /* length */
dbc_maxfilo = 62 /* Max Db Files Open per appl offset */
dbc_maxfill = 2 /* length */
dbc_softo = 64 /* No. records before Soft Chkpt offset */
dbc_softl = 2 /* length */
dbc_maxappo = 66 /* Max active applications offset */
dbc_maxappl = 2 /* length */
dbc_apheapo = 68 /* Application Heap Size offset */
dbc_apheapl = 2 /* length */
dbc_dbheapo = 70 /* Database Heap Size offset */
dbc_dbheapl = 2 /* length */
dbc_cntryo = 72 /* Country Code of Application offset */
dbc_cntryl = 2 /* length */
dbc_cpago = 74 /* Code Page of Application offset */
dbc_cpagl = 2 /* length */
dbc_agheapo = 76 /* Application Agent Heap Size offset */
dbc_agheapl = 2 /* length */
dbc_maxtoto = 78 /* Max Total Files Open offset */
dbc_maxtotl = 2 /* length */
dbc_slheapo = 80 /* Sort List Heap Size offset */
dbc_slheapl = 2 /* length */
dbc_rdso = 82 /* RDS Version Indicator offset */
dbc_rdsl = 2 /* length */
dbc_pctlckso = 84 /* % of Total LockList per appl offset */
dbc_pctlcksl = 2 /* length */
dbc_stheapo = 86 /* Statement Heap Size offset */
dbc_stheapl = 2 /* length */
dbc_plogo = 88 /* Number of Primary Log Files offset */
dbc_plogl = 2 /* length */
dbc_slogo = 90 /* Number of Secondary Log Files offset */
dbc_slogl = 2 /* length */
dbc_lfsizo = 92 /* Log File Size offset */
dbc_lfsizl = 2 /* length */
dbc_logpatho = 94 /* Log File Path offset */
dbc_logpathl = 248 /* length */
dbc_newpatho = 342 /* Path to the Log File offset */
dbc_newpathl = 248 /* length */
dbc_inflgo = 590 /* Internal Indicator/Status Flag offset */
dbc_inflgl = 2 /* length */
dbc_exflgo = 592 /* External Indicator/Status Flag offset */
dbc_exflgl = 2 /* length */
dbc_collseqo = 594 /* User-defined collating sequence offset */
dbc_collseql = 260 /* length */
dbc_pad3o = 854 /* Pad for Spare Bytes offset */
dbc_pad3l = 8 /* length */
return
/******************************************************************
* SUBROUTINE: GETDATA_DBCON *
* *
* DESCRIPTIVE NAME: Get Data from the Db Config File *
* *
* DESCRIPTION: This routine retrieves the data from the *
* Database Configuration File and stores the *
* Database Configuration fields in variables. *
* *
* INPUT: none *
* *
* *
* OUTPUT: none *
* *
******************************************************************/
getdata_dbcon:
/*********************************************
Read the Database Configuration File
*********************************************/
/* Checksum */
dbc_chksum = c2d(reverse(charin(dbcon_name, dbcon+dbc_chksumo+2, 2)) || ,
reverse(charin(dbcon_name, dbcon+dbc_chksumo, 2)), 5)
/* Title */
dbc_title = charin(dbcon_name, dbcon+dbc_titleo, dbc_titlel)
/* Release */
dbc_rel = c2x(reverse(charin(dbcon_name, dbcon+dbc_relo, dbc_rell)))
/* Log File Size */
dbc_logsiz = c2d(reverse(charin(dbcon_name, dbcon+dbc_logsizo+2, 2)) || ,
reverse(charin(dbcon_name, dbcon+dbc_logsizo, 2)), 5)
/* Log File Extent Size */
dbc_logext = c2d(reverse(charin(dbcon_name, dbcon+dbc_logexto+2, 2)) || ,
reverse(charin(dbcon_name, dbcon+dbc_logexto, 2)), 5)
/* Max No. of Extents */
dbc_maxext = c2d(reverse(charin(dbcon_name, dbcon+dbc_maxexto+2, 2)) || ,
reverse(charin(dbcon_name, dbcon+dbc_maxexto, 2)), 5)
/* Deadlock Check Interval */
dbc_dlchk = c2d(reverse(charin(dbcon_name, dbcon+dbc_dlchko+2, 2)) || ,
reverse(charin(dbcon_name, dbcon+dbc_dlchko, 2)), 5)
/* Masked Database Seed */
dbc_mseed = c2d(reverse(charin(dbcon_name, dbcon+dbc_mseedo+2, 2)) || ,
reverse(charin(dbcon_name, dbcon+dbc_mseedo, 2)), 5)
/* UnMasked Database Seed */
dbc_unseed = c2d(reverse(charin(dbcon_name, dbcon+dbc_unseedo+2, 2)) || ,
reverse(charin(dbcon_name, dbcon+dbc_unseedo, 2)), 5)
/* Timestamp */
dbc_stmp = c2x(charin(dbcon_name, dbcon+dbc_stmpo, dbc_stmpl))
/* Maximum Storage for Lock List */
dbc_lcklst = c2d(reverse(charin(dbcon_name, dbcon+dbc_lcklsto, dbc_lcklstl)))
/* Size of Buffer Pool */
dbc_buff = c2d(reverse(charin(dbcon_name, dbcon+dbc_buffo, dbc_buffl)))
/* Max Db Files Open per Appl */
dbc_maxfil = c2d(reverse(charin(dbcon_name, dbcon+dbc_maxfilo, dbc_maxfill)))
/* No. Records before Soft Chkpt */
dbc_soft = c2d(reverse(charin(dbcon_name, dbcon+dbc_softo, dbc_softl)))
/* Max Active Applications */
dbc_maxapp = c2d(reverse(charin(dbcon_name, dbcon+dbc_maxappo, dbc_maxappl)))
/* Application Heap Size */
dbc_apheap = c2d(reverse(charin(dbcon_name, dbcon+dbc_apheapo, dbc_apheapl)))
/* Database Heap Size */
dbc_dbheap = c2d(reverse(charin(dbcon_name, dbcon+dbc_dbheapo, dbc_dbheapl)))
/* Country Code */
dbc_cntry = c2d(reverse(charin(dbcon_name, dbcon+dbc_cntryo, dbc_cntryl)))
/* Code Page */
dbc_cpag = c2d(reverse(charin(dbcon_name, dbcon+dbc_cpago, dbc_cpagl)))
/* Application Agent Heap Size */
dbc_agheap = c2d(reverse(charin(dbcon_name, dbcon+dbc_agheapo, dbc_agheapl)))
/* Max Total Files Open */
dbc_maxtot = c2d(reverse(charin(dbcon_name, dbcon+dbc_maxtoto, dbc_maxtotl)))
/* Sort List Heap Size */
dbc_slheap = c2d(reverse(charin(dbcon_name, dbcon+dbc_slheapo, dbc_slheapl)))
/* RDS Version Indicator */
dbc_rds = c2d(reverse(charin(dbcon_name, dbcon+dbc_rdso, dbc_rdsl)))
/* % of Total LockList per Appl */
dbc_pctlcks = c2d(reverse(charin(dbcon_name, dbcon+dbc_pctlckso, dbc_pctlcksl)))
/* Statement Heap Size */
dbc_stheap = c2d(reverse(charin(dbcon_name, dbcon+dbc_stheapo, dbc_stheapl)))
/* Number of Primary Log Files */
dbc_plog = c2d(reverse(charin(dbcon_name, dbcon+dbc_plogo, dbc_plogl)))
/* Number of Secondary Log Files */
dbc_slog = c2d(reverse(charin(dbcon_name, dbcon+dbc_slogo, dbc_slogl)))
/* Log File Size */
dbc_lfsiz = c2d(reverse(charin(dbcon_name, dbcon+dbc_lfsizo, dbc_lfsizl)))
/* Log File Path */
dbc_logpath = charin(dbcon_name, dbcon+dbc_logpatho, dbc_logpathl)
/* New Log File Path */
dbc_newpath = charin(dbcon_name, dbcon+dbc_newpatho, dbc_newpathl)
/* Internal Indicator/Status Flag */
dbc_inflg = c2x(reverse(charin(dbcon_name, dbcon+dbc_inflgo, dbc_inflgl)))
/* External Indicator/Status Flag */
dbc_exflg = c2x(reverse(charin(dbcon_name, dbcon+dbc_exflgo, dbc_exflgl)))
/*********************************************
Report the Contents of the Database
Configuration File
*********************************************/
/* Get Binary representations of the Internal Indicators */
dbc_inflg_mo = x2b(c2x(bitand(x2c(dbc_inflg), '0001'x))) /* Log File Move */
dbc_inflg_lc = x2b(c2x(bitand(x2c(dbc_inflg), '0002'x))) /* L -> C Xlate */
dbc_inflg_cl = x2b(c2x(bitand(x2c(dbc_inflg), '0004'x))) /* C -> L Xlate */
dbc_inflg_sv = x2b(c2x(bitand(x2c(dbc_inflg), '0008'x))) /* Svr Def Install*/
/* Get Binary representations of the External Indicators */
dbc_exflg_cp = x2b(c2x(bitand(x2c(dbc_exflg), '0001'x))) /* Copy Protect */
dbc_exflg_lr = x2b(c2x(bitand(x2c(dbc_exflg), '0002'x))) /* Log Retain */
dbc_exflg_le = x2b(c2x(bitand(x2c(dbc_exflg), '0004'x))) /* Log Exit */
dbc_exflg_ar = x2b(c2x(bitand(x2c(dbc_exflg), '0008'x))) /* Auto Restart */
dbcon_text = ,
' ' || cr_lf || ,
' Database Configuration File ' || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' Checksum: ' || dbc_chksum || cr_lf || ,
' Title: ' || dbc_title || cr_lf || ,
' Release: ' || dbc_rel || cr_lf || ,
' RDS Version Indicator: ' || dbc_rds || cr_lf || ,
' Masked Database Seed: ' || dbc_mseed || cr_lf || ,
' UnMasked Database Seed: ' || dbc_unseed || cr_lf || ,
' Database Creation Timestamp: ' || substr(dbc_stmp,1,4) || '-' || ,
substr(dbc_stmp,5,2) || '-' || ,
substr(dbc_stmp,7,2) || '-' || ,
substr(dbc_stmp,9,2) || '.' || ,
substr(dbc_stmp,11,2) || '.' || ,
substr(dbc_stmp,13,2) || '.' || ,
substr(dbc_stmp,15,6) || ,
cr_lf || ,
' ' || cr_lf || ,
' Log File Size (Linear Log): ' || dbc_logsiz || cr_lf || ,
' Extent Size (Linear Log): ' || dbc_logext || cr_lf || ,
' Max No. of Extents (Linear Log): ' || dbc_maxext || cr_lf || ,
' Number of Primary Log Files: ' || dbc_plog || cr_lf || ,
' Number of Secondary Log Files: ' || dbc_slog || cr_lf || ,
' Size of Each Log File: ' || dbc_lfsiz || cr_lf || ,
' Log File Path: ' || ,
strip(translate(dbc_logpath, ' ', '00'x )) || ,
cr_lf || ,
' New Log File Path: ' || ,
strip(translate(dbc_newpath, ' ', '00'x )) || ,
cr_lf || ,
' ' || cr_lf || ,
' Interval for DeadLock Detection: ' || dbc_dlchk || cr_lf || ,
' Maximum Storage for Lock List: ' || dbc_lcklst || cr_lf || ,
' % of Total Lock List per Appl: ' || dbc_pctlcks || cr_lf || ,
' Maximum Active Applications: ' || dbc_maxapp || cr_lf || ,
' Maximum Db Files Open per Appl: ' || dbc_maxfil || cr_lf || ,
' Max Tot Files Open per Appl: ' || dbc_maxtot || cr_lf || ,
'Records Written before SoftChkpt: ' || dbc_soft || cr_lf || ,
' Size of Buffer Pool: ' || dbc_buff || cr_lf || ,
' ' || cr_lf || ,
' Application Heap Size: ' || dbc_apheap || cr_lf || ,
' Application Agent Heap Size: ' || dbc_agheap || cr_lf || ,
' Database Heap Size: ' || dbc_dbheap || cr_lf || ,
' Statement Heap Size: ' || dbc_stheap || cr_lf || ,
' Sort List Heap Size: ' || dbc_slheap || cr_lf || ,
' ' || cr_lf || ,
' Country Code: ' || dbc_cntry || cr_lf || ,
' Code Page: ' || dbc_cpag || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' -----Internal Indicators----- ' || cr_lf || ,
' ' || cr_lf || ,
' Log File Move Indicator: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 3) || ,
substr(dbc_inflg_mo,16, 1) || ,
copies('x', 0) || ,
cr_lf || ,
' Linear to Circular Log Xlate: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 2) || ,
substr(dbc_inflg_lc,15, 1) || ,
copies('x', 1) || ,
cr_lf || ,
' Circular to Linear Log Xlate: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 1) || ,
substr(dbc_inflg_cl,14, 1) || ,
copies('x', 2) || ,
cr_lf || ,
' Server Defaults Installed: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 0) || ,
substr(dbc_inflg_cl,13, 1) || ,
copies('x', 3) || ,
cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' -----External Indicators----- ' || cr_lf || ,
' ' || cr_lf || ,
' Copy Protect Indicator: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 3) || ,
substr(dbc_exflg_cp,16, 1) || ,
copies('x', 0) || ,
cr_lf || ,
' Enable Log Retain: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 2) || ,
substr(dbc_exflg_lr,15, 1) || ,
copies('x', 1) || ,
cr_lf || ,
' Enable Log Exit: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 1) || ,
substr(dbc_exflg_le,14, 1) || ,
copies('x', 2) || ,
cr_lf || ,
' Automatic Restart: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 0) || ,
substr(dbc_exflg_ar,13, 1) || ,
copies('x', 3) || ,
cr_lf
call wrt2rpt dbcon_text
return
/******************************************************************
* SUBROUTINE: GETLOGPATH *
* *
* DESCRIPTIVE NAME: Get the Path Containing Log Files *
* *
* DESCRIPTION: This routine determines the SubDirectory that *
* contains the Log Files from the LOGPATH and *
* NEWPATH fields in the Db Config file. If both *
* fields are NULL, then the Log Files are *
* supposed to be in the Database Subdirectory. *
* The Log Control File exists in the Database *
* Subdirectory regardless of the location of the *
* other Log Files. This routine checks to see if *
* the Log Files really exist in the location *
* that is described by the LOGPATH or the NEWPATH *
* fields. Upon exit from this routine, the *
* shared variable LOGPATH should contain the log *
* file subdirectory. If no subdirectory is found *
* to contain the Log Files, then LOGPATH remains *
* a NULL value. *
* *
* INPUT: LOGPATH = NULL *
* *
* *
* OUTPUT: LOGPATH = Log File Subdirectory *
* or *
* LOGPATH = NULL *
* *
******************************************************************/
getlogpath:
/* Construct normalized LogPath character string */
norm_logpath = strip(translate(dbc_logpath, ' ', '00'x ))
/* Construct normalized NewLogPath character string */
norm_newpath = strip(translate(dbc_newpath, ' ', '00'x ))
if norm_logpath = '' & norm_newpath = '' then
do
/* Log Files are supposedly in the database subdirectory */
if stream(dbpath || 'S0000000.LOG', 'c', 'query exist') \= '' then
logpath = dbpath /* Log File in database subdirectory */
end
else /* Log Path is specified in the Db Configuration */
do
/* Check if Log Control File is specified and found in LOGPATH */
if norm_logpath \= '' & ,
stream(norm_logpath || 'S0000000.LOG', 'c', 'query exist') \= '' then
/* Log Control File found in LOGPATH */
logpath = norm_logpath
else
do
if norm_newpath \= '' & ,
stream(norm_newpath || 'S0000000.LOG', 'c', 'query exist') \= '' then
/* Log Control File found in NEWPATH */
logpath = norm_newpath
end
end
return
/******************************************************************
* SUBROUTINE: RESET *
* *
* DESCRIPTIVE NAME: Reset the Log Control File *
* *
* DESCRIPTION: This routine controls the resetting of the Log *
* Control File. It calls a routine to set up the *
* offsets to fields in the Log Control File and *
* then it calls the routine to update the Base *
* LSN in the file. *
* *
* *
* INPUT: none *
* *
* *
* OUTPUT: none *
* *
******************************************************************/
reset:
say '....Examining the Log Control File'
/*********************************************
Define Offsets to Fields in the Log Control File
*********************************************/
call defoff_log
/*********************************************
Write Report File Separator Lines
*********************************************/
rptsep_text = ' ' || cr_lf || ,
' ' || cr_lf || ,
seplines || cr_lf || ,
seplines || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf
call wrt2rpt rptsep_text
/*********************************************
Get Data in the Log Control File
*********************************************/
call getdata_logctl
/*********************************************
Write Report File Separator Lines
*********************************************/
call wrt2rpt rptsep_text
/*********************************************
Update the Base LSN
*********************************************/
say '....Comparing LSN Values'
call updlsn
/*********************************************
Write the Report File Tail
*********************************************/
rptail_text = ' ' || cr_lf || ,
' ' || cr_lf || ,
eqlines || cr_lf || ,
eqlines || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf
call wrt2rpt rptail_text
return
/******************************************************************
* SUBROUTINE: DEFOFF_LOG *
* *
* DESCRIPTIVE NAME: Define Offsets to Fields in Log Control File *
* *
* DESCRIPTION: This routine defines the offsets for the fields *
* in the Log Control File. *
* *
* INPUT: none *
* *
* *
* OUTPUT: none *
* *
******************************************************************/
defoff_log:
/*********************************************
Define Page Offset Constants
(Note: These offsets are 1-origin from the Start of the Page)
(Note: The length values are in terms of character bytes.)
*********************************************/
lfhdr1 = 1 /* Offset to the Primary Log File Header */
lfhdr2 = 2049 /* Offset to the Secondary Log File Header */
/*********************************************
Define Offsets for Log File Header in Log Control File
(Note: These offsets are 0-origin from the Start of LFH)
*********************************************/
lfh_cnt1o = 0 /* Consistency Counter 1 field offset */
lfh_cnt1l = 2 /* field length */
lfh_fmtvo = 2 /* Format Version field offset */
lfh_fmtvl = 2 /* field length */
lfh_logtypo = 4 /* Log File Type field offset */
lfh_logtypl = 2 /* field length */
lfh_logacto = 6 /* Number of Primary Log Files field offset */
lfh_logactl = 2 /* field length */
lfh_loginao = 8 /* Number of Secondary Log Files field offset */
lfh_loginal = 2 /* field length */
lfh_logsizo = 10 /* Number of Pages in each Log File field offset*/
lfh_logsizl = 2 /* field length*/
lfh_ttblsizo = 12 /* Current Size of Trans Table field offset */
lfh_ttblsizl = 2 /* field length */
lfh_softmaxo = 14 /* Log Records written before Soft Chkpt off */
lfh_softmaxl = 2 /* field len */
lfh_baselsno = 16 /* First LSN after final Stop Using field off */
lfh_baselsnl = 6 /* field len */
lfh_nextlsno = 22 /* Next LSN prior to final Stop Using field off */
lfh_nextlsnl = 6 /* field len */
lfh_lowlsno = 28 /* First LSN of Oldest In-Flight Trans field off*/
lfh_lowlsnl = 6 /* field len*/
lfh_minblsno = 34 /* First LSN of Oldest Pg in Buff Pool field off*/
lfh_minblsnl = 6 /* field len*/
lfh_basetido = 40 /* First Transaction ID field offset */
lfh_basetidl = 6 /* field length */
lfh_headlsno = 46 /* LSN at Head of Log File field offset */
lfh_headlsnl = 6 /* field length */
lfh_taillsno = 52 /* Last LSN of Log File field offset */
lfh_taillsnl = 6 /* field length */
lfh_logpatho = 58 /* Log File Path field offset */
lfh_logpathl = 260 /* field length */
lfh_hflago = 318 /* HFLAG field offset */
lfh_hflagl = 2 /* field length */
lfh_headexto = 320 /* Head Extent ID field offset */
lfh_headextl = 4 /* field length */
lfh_lastexto = 324 /* Last Extent ID field offset */
lfh_lastextl = 4 /* field length */
lfh_dbexto = 328 /* Db Creation Extent ID field offset */
lfh_dbextl = 4 /* field length */
lfh_cmitexto = 332 /* Last Commit Extent ID field offset */
lfh_cmitextl = 4 /* field length */
lfh_frstarco = 336 /* First Archived Extent ID field offset */
lfh_frstarcl = 4 /* field length */
lfh_lastarco = 340 /* Last Archived Extent ID field offset */
lfh_lastarcl = 4 /* field length */
lfh_nextreco = 344 /* Next Media Recovery Extent ID field offset */
lfh_nextrecl = 4 /* field length */
lfh_frstreco = 348 /* First Media Recovery Extent ID field offset */
lfh_frstrecl = 4 /* field length */
lfh_frstdelo = 352 /* First M-Rcvry Deleted Extent ID field offset */
lfh_frstdell = 4 /* field length */
lfh_lastdelo = 356 /* Last M-Rcvry Deleted Extent ID field offset */
lfh_lastdell = 4 /* field length */
lfh_headreco = 360 /* Head Media Recovery Extent ID field offset */
lfh_headrecl = 4 /* field length */
lfh_filecnto = 364 /* Count of Files in Array field offset */
lfh_filecntl = 2 /* field length */
lfh_filarryo = 366 /* File Handle Array field offset */
lfh_filarryl = 512 /* field length */
lfh_trnclsno = 878 /* Truncation LSN field offset */
lfh_trnclsnl = 6 /* field length */
lfh_trncexto = 884 /* Truncation Extent ID field offset */
lfh_trncextl = 4 /* field length */
lfh_resrvo = 888 /* Unused */
lfh_resrvl = 2 /* */
lfh_lastcido = 890 /* Last CId field offset */
lfh_lastcidl = 4 /* field length */
lfh_lrdlsno = 894 /* Last Record Read LSN during RFR field offset */
lfh_lrdlsnl = 6 /* field length */
lfh_resrv2o = 900 /* Unused */
lfh_resrv2l = 18 /* */
lfh_cnt2o = 918 /* Consistency counter 2 offset */
lfh_cnt2l = 2 /* length */
return
/******************************************************************
* SUBROUTINE: GETDATA_LOGCTL *
* *
* DESCRIPTIVE NAME: Get Data from the Log Control File *
* *
* DESCRIPTION: This routine determines the most recent Log File *
* Header (either the Primary or the Secondary) and *
* retrieves the data from the Log Control File *
* and stores the Log File Header fields in *
* variables. *
* *
* INPUT: none *
* *
* *
* OUTPUT: none *
* *
******************************************************************/
getdata_logctl:
/*********************************************
Read the Log Control File (Primary LFH)
*********************************************/
lfhdr = lfhdr1 /* Set offset for reading Primary Log File Header */
lfh_i = 1 /* Set Primary LFH indicator */
call getlfh_fields /* Get the LFH fields from the Primary LFH */
/*********************************************
Read the Log Control File (Secondary LFH)
*********************************************/
lfhdr = lfhdr2 /* Set offset for reading Secondary Log File Header */
lfh_i = 2 /* Set Secondary LFH indicator */
call getlfh_fields /* Get the LFH fields from the Secondary LFH */
/*********************************************
Report the Contents of the Primary Log File
Header in the Log Control File
*********************************************/
/* Get Binary representations of the HFLAG */
lfh_hflg_b00.1 = x2b(c2x(bitand(x2c(lfh_hflag.1), '0001'x))) /* Db Consistent*/
lfh_hflg_b01.1 = x2b(c2x(bitand(x2c(lfh_hflag.1), '0002'x))) /* */
lfh_hflg_b02.1 = x2b(c2x(bitand(x2c(lfh_hflag.1), '0004'x))) /* Bckup Pending*/
lfh_hflg_b03.1 = x2b(c2x(bitand(x2c(lfh_hflag.1), '0008'x))) /* RFR Pending */
lfh_hflg_b04.1 = x2b(c2x(bitand(x2c(lfh_hflag.1), '0010'x))) /* Rec w/ Retain*/
lfh_hflg_b05.1 = x2b(c2x(bitand(x2c(lfh_hflag.1), '0020'x))) /* Rec w/ U Xit */
lfh_hflg_b06.1 = x2b(c2x(bitand(x2c(lfh_hflag.1), '0040'x))) /* Tst Consistnt*/
lfh_hflg_b07.1 = x2b(c2x(bitand(x2c(lfh_hflag.1), '0080'x))) /* RFR,not Crash*/
lfh_hflg_b08.1 = x2b(c2x(bitand(x2c(lfh_hflag.1), '0100'x))) /* Alloc Logs */
lfh_hflg_b09.1 = x2b(c2x(bitand(x2c(lfh_hflag.1), '0200'x))) /* Rec Complete */
lfh_hflg_b10.1 = x2b(c2x(bitand(x2c(lfh_hflag.1), '0400'x))) /* RFR in Prog */
lfh_hflg_b11.1 = x2b(c2x(bitand(x2c(lfh_hflag.1), '0800'x))) /* Trunc in Prog*/
lfh_hflg_b12.1 = x2b(c2x(bitand(x2c(lfh_hflag.1), '1000'x))) /* No Retry */
lfh_hflg_b13.1 = x2b(c2x(bitand(x2c(lfh_hflag.1), '2000'x))) /* */
lfh_hflg_b14.1 = x2b(c2x(bitand(x2c(lfh_hflag.1), '4000'x))) /* */
lfh_hflg_b15.1 = x2b(c2x(bitand(x2c(lfh_hflag.1), '8000'x))) /* Create Logs */
hflag_text = ,
' -----HFLAG Indicators----- ' || cr_lf || ,
' ' || cr_lf || ,
' Database is Consistent: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 3) || ,
substr(lfh_hflg_b00.1,16, 1) || ,
copies('x', 0) || ,
cr_lf || ,
' (Unused): ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 2) || ,
substr(lfh_hflg_b01.1,15, 1) || ,
copies('x', 1) || ,
cr_lf || ,
' Backup is Pending: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 1) || ,
substr(lfh_hflg_b02.1,14, 1) || ,
copies('x', 2) || ,
cr_lf || ,
' Roll-Forward Recovery is Pending: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 0) || ,
substr(lfh_hflg_b03.1,13, 1) || ,
copies('x', 3) || ,
cr_lf || ,
' Db is recoverable - Retain Logs: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 3) || ,
substr(lfh_hflg_b04.1,12, 1) || ,
copies('x', 0) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
' Db rcvrble - Retain & User Exit: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 2) || ,
substr(lfh_hflg_b05.1,11, 1) || ,
copies('x', 1) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
' Test is Consistent: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 1) || ,
substr(lfh_hflg_b06.1,10, 1) || ,
copies('x', 2) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
' RFR vs Crash Rcvry (1 => RFR): ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 0) || ,
substr(lfh_hflg_b07.1, 9, 1) || ,
copies('x', 3) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
'ReAllocate Logs for Crash Recovery: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 3) || ,
substr(lfh_hflg_b08.1, 8, 1) || ,
copies('x', 0) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
'Restore Force or Recovery Complete: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 2) || ,
substr(lfh_hflg_b09.1, 7, 1) || ,
copies('x', 1) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
'RFR Utility started & not Complete: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 1) || ,
substr(lfh_hflg_b10.1, 6, 1) || ,
copies('x', 2) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
' RFR Trunc started & not Complete: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 0) || ,
substr(lfh_hflg_b11.1, 5, 1) || ,
copies('x', 3) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
' Do not Invoke SQLUEXIT: ' || ,
copies('x', 3) || ,
substr(lfh_hflg_b12.1, 4, 1) || ,
copies('x', 0) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
' (unused): ' || ,
copies('x', 2) || ,
substr(lfh_hflg_b13.1, 3, 1) || ,
copies('x', 1) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
' (unused): ' || ,
copies('x', 1) || ,
substr(lfh_hflg_b14.1, 2, 1) || ,
copies('x', 2) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
' Database Logs are being Built: ' || ,
copies('x', 0) || ,
substr(lfh_hflg_b15.1, 1, 1) || ,
copies('x', 3) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ,
cr_lf
lfh_text = ,
' ' || cr_lf || ,
' Log Control File ' || cr_lf || ,
' Primary Log File Header:' || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' Consistency Counter 1: ' || lfh_cnt1.1 || cr_lf || ,
' Consistency Counter 2: ' || lfh_cnt2.1 || cr_lf || ,
' Format Version: ' || lfh_fmtv.1 || cr_lf || ,
' Log Type: ' || lfh_logtyp.1 || cr_lf || ,
' ' || cr_lf || ,
' Log File Path: ' || ,
strip(translate(lfh_logpath.1, ' ', '00'x )) || ,
cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' Number of Primary Log Files: ' || lfh_logact.1 || cr_lf || ,
' Number of Secondary Log Files: ' || lfh_logina.1 || cr_lf || ,
'Number of Pages in each Log File: ' || lfh_logsiz.1 || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
hflag_text || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' Base LSN: ' || lfh_baselsn.1 || cr_lf || ,
' Next LSN: ' || lfh_nextlsn.1 || cr_lf || ,
' Low Transaction LSN: ' || lfh_lowlsn.1 || cr_lf || ,
' Minimum Buffer LSN: ' || lfh_minblsn.1 || cr_lf || ,
' Head LSN: ' || lfh_headlsn.1 || cr_lf || ,
' Tail LSN: ' || lfh_taillsn.1 || cr_lf || ,
' Truncation LSN: ' || lfh_trnclsn.1 || cr_lf || ,
' Last Record Read LSN: ' || lfh_lrdlsn.1 || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' First Transaction ID: ' || lfh_basetid.1 || cr_lf || ,
' Size of Transaction Table: ' || lfh_ttblsiz.1 || cr_lf || ,
' Log Recs prior to Soft Chkpt: ' || lfh_softmax.1 || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' Head Extent ID: ' || lfh_headext.1 || cr_lf || ,
' Last Extent ID: ' || lfh_lastext.1 || cr_lf || ,
' Database Creation Extent ID: ' || lfh_dbext.1 || cr_lf || ,
' Last Commit Extent ID: ' || lfh_cmitext.1 || cr_lf || ,
' First Archived Extent ID: ' || lfh_frstarc.1 || cr_lf || ,
' Last Archived Extent ID: ' || lfh_lastarc.1 || cr_lf || ,
' First Media Recovery Extent ID: ' || lfh_frstrec.1 || cr_lf || ,
' Next Media Recovery Extent ID: ' || lfh_nextrec.1 || cr_lf || ,
' First M-Rcvry Deleted Extent ID: ' || lfh_frstdel.1 || cr_lf || ,
' Last M-Rcvry Deleted Extent ID: ' || lfh_lastdel.1 || cr_lf || ,
' Head Media Recovery Extent ID: ' || lfh_headrec.1 || cr_lf || ,
' Truncation Extent ID: ' || lfh_trncext.1 || cr_lf || ,
' Last CID: ' || lfh_lastcid.1 || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf
call wrt2rpt lfh_text
/* Write the report separator lines */
call wrt2rpt rptsep_text
/*********************************************
Report the Contents of the Secondary Log File
Header in the Log Control File
*********************************************/
/* Get Binary representations of the HFLAG */
lfh_hflg_b00.2 = x2b(c2x(bitand(x2c(lfh_hflag.2), '0001'x))) /* Db Consistent*/
lfh_hflg_b01.2 = x2b(c2x(bitand(x2c(lfh_hflag.2), '0002'x))) /* */
lfh_hflg_b02.2 = x2b(c2x(bitand(x2c(lfh_hflag.2), '0004'x))) /* Bckup Pending*/
lfh_hflg_b03.2 = x2b(c2x(bitand(x2c(lfh_hflag.2), '0008'x))) /* RFR Pending */
lfh_hflg_b04.2 = x2b(c2x(bitand(x2c(lfh_hflag.2), '0010'x))) /* Rec w/ Retain*/
lfh_hflg_b05.2 = x2b(c2x(bitand(x2c(lfh_hflag.2), '0020'x))) /* Rec w/ U Xit */
lfh_hflg_b06.2 = x2b(c2x(bitand(x2c(lfh_hflag.2), '0040'x))) /* Tst Consistnt*/
lfh_hflg_b07.2 = x2b(c2x(bitand(x2c(lfh_hflag.2), '0080'x))) /* RFR,not Crash*/
lfh_hflg_b08.2 = x2b(c2x(bitand(x2c(lfh_hflag.2), '0100'x))) /* Alloc Logs */
lfh_hflg_b09.2 = x2b(c2x(bitand(x2c(lfh_hflag.2), '0200'x))) /* Rec Complete */
lfh_hflg_b10.2 = x2b(c2x(bitand(x2c(lfh_hflag.2), '0400'x))) /* RFR in Prog */
lfh_hflg_b11.2 = x2b(c2x(bitand(x2c(lfh_hflag.2), '0800'x))) /* Trunc in Prog*/
lfh_hflg_b12.2 = x2b(c2x(bitand(x2c(lfh_hflag.2), '1000'x))) /* No Retry */
lfh_hflg_b13.2 = x2b(c2x(bitand(x2c(lfh_hflag.2), '2000'x))) /* */
lfh_hflg_b14.2 = x2b(c2x(bitand(x2c(lfh_hflag.2), '4000'x))) /* */
lfh_hflg_b15.2 = x2b(c2x(bitand(x2c(lfh_hflag.2), '8000'x))) /* Create Logs */
hflag_text = ,
' -----HFLAG Indicators----- ' || cr_lf || ,
' ' || cr_lf || ,
' Database is Consistent: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 3) || ,
substr(lfh_hflg_b00.2,16, 1) || ,
copies('x', 0) || ,
cr_lf || ,
' (Unused): ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 2) || ,
substr(lfh_hflg_b01.2,15, 1) || ,
copies('x', 1) || ,
cr_lf || ,
' Backup is Pending: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 1) || ,
substr(lfh_hflg_b02.2,14, 1) || ,
copies('x', 2) || ,
cr_lf || ,
' Roll-Forward Recovery is Pending: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 0) || ,
substr(lfh_hflg_b03.2,13, 1) || ,
copies('x', 3) || ,
cr_lf || ,
' Db is recoverable - Retain Logs: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 3) || ,
substr(lfh_hflg_b04.2,12, 1) || ,
copies('x', 0) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
' Db rcvrble - Retain & User Exit: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 2) || ,
substr(lfh_hflg_b05.2,11, 1) || ,
copies('x', 1) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
' Test is Consistent: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 1) || ,
substr(lfh_hflg_b06.2,10, 1) || ,
copies('x', 2) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
' RFR vs Crash Rcvry (1 => RFR): ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 0) || ,
substr(lfh_hflg_b07.2, 9, 1) || ,
copies('x', 3) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
'ReAllocate Logs for Crash Recovery: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 3) || ,
substr(lfh_hflg_b08.2, 8, 1) || ,
copies('x', 0) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
'Restore Force or Recovery Complete: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 2) || ,
substr(lfh_hflg_b09.2, 7, 1) || ,
copies('x', 1) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
'RFR Utility started & not Complete: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 1) || ,
substr(lfh_hflg_b10.2, 6, 1) || ,
copies('x', 2) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
' RFR Trunc started & not Complete: ' || ,
copies('x', 4) || ' ' || ,
copies('x', 0) || ,
substr(lfh_hflg_b11.2, 5, 1) || ,
copies('x', 3) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
' Do not Invoke SQLUEXIT: ' || ,
copies('x', 3) || ,
substr(lfh_hflg_b12.2, 4, 1) || ,
copies('x', 0) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
' (unused): ' || ,
copies('x', 2) || ,
substr(lfh_hflg_b13.2, 3, 1) || ,
copies('x', 1) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
' (unused): ' || ,
copies('x', 1) || ,
substr(lfh_hflg_b14.2, 2, 1) || ,
copies('x', 2) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ,
cr_lf || ,
' Database Logs are being Built: ' || ,
copies('x', 0) || ,
substr(lfh_hflg_b15.2, 1, 1) || ,
copies('x', 3) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ' ' || ,
copies('x', 4) || ,
cr_lf
lfh_text = ,
' ' || cr_lf || ,
' Log Control File ' || cr_lf || ,
' Secondary Log File Header:' || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' Consistency Counter 1: ' || lfh_cnt1.2 || cr_lf || ,
' Consistency Counter 2: ' || lfh_cnt2.2 || cr_lf || ,
' Format Version: ' || lfh_fmtv.2 || cr_lf || ,
' Log Type: ' || lfh_logtyp.2 || cr_lf || ,
' ' || cr_lf || ,
' Log File Path: ' || ,
strip(translate(lfh_logpath.2, ' ', '00'x )) || ,
cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' Number of Primary Log Files: ' || lfh_logact.2 || cr_lf || ,
' Number of Secondary Log Files: ' || lfh_logina.2 || cr_lf || ,
'Number of Pages in each Log File: ' || lfh_logsiz.2 || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
hflag_text || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' Base LSN: ' || lfh_baselsn.2 || cr_lf || ,
' Next LSN: ' || lfh_nextlsn.2 || cr_lf || ,
' Low Transaction LSN: ' || lfh_lowlsn.2 || cr_lf || ,
' Minimum Buffer LSN: ' || lfh_minblsn.2 || cr_lf || ,
' Head LSN: ' || lfh_headlsn.2 || cr_lf || ,
' Tail LSN: ' || lfh_taillsn.2 || cr_lf || ,
' Truncation LSN: ' || lfh_trnclsn.2 || cr_lf || ,
' Last Record Read LSN: ' || lfh_lrdlsn.2 || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' First Transaction ID: ' || lfh_basetid.2 || cr_lf || ,
' Size of Transaction Table: ' || lfh_ttblsiz.2 || cr_lf || ,
' Log Recs prior to Soft Chkpt: ' || lfh_softmax.2 || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf || ,
' Head Extent ID: ' || lfh_headext.2 || cr_lf || ,
' Last Extent ID: ' || lfh_lastext.2 || cr_lf || ,
' Database Creation Extent ID: ' || lfh_dbext.2 || cr_lf || ,
' Last Commit Extent ID: ' || lfh_cmitext.2 || cr_lf || ,
' First Archived Extent ID: ' || lfh_frstarc.2 || cr_lf || ,
' Last Archived Extent ID: ' || lfh_lastarc.2 || cr_lf || ,
' First Media Recovery Extent ID: ' || lfh_frstrec.2 || cr_lf || ,
' Next Media Recovery Extent ID: ' || lfh_nextrec.2 || cr_lf || ,
' First M-Rcvry Deleted Extent ID: ' || lfh_frstdel.2 || cr_lf || ,
' Last M-Rcvry Deleted Extent ID: ' || lfh_lastdel.2 || cr_lf || ,
' Head Media Recovery Extent ID: ' || lfh_headrec.2 || cr_lf || ,
' Truncation Extent ID: ' || lfh_trncext.2 || cr_lf || ,
' Last CID: ' || lfh_lastcid.2 || cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf
call wrt2rpt lfh_text
return
/******************************************************************
* SUBROUTINE: GETLFH_FIELDS *
* *
* DESCRIPTIVE NAME: Get Data from the fields in the LFH *
* *
* DESCRIPTION: This routine gets the data from the Log File *
* Header of the Log Control File. This routine *
* retrieves the data from the primary LFH as well *
* as the secondary LFH depending upon the value *
* of the shared variable "lfhdr". It stores the *
* values of the fields in the Primary LFH in a *
* compound variable "lfh_xxxxxx.1" and the values *
* of the fields in the Secondary LFH in another *
* compound variable "lfh_xxxxxx.2". *
* *
* INPUT: lfhdr - Offset to start of Primary or Secondary LFH. *
* lfh_i - Log File Header index *
* 1 -> Primary LFH *
* 2 -> Secondary LFH *
* *
* OUTPUT: none *
* *
******************************************************************/
getlfh_fields:
/* Consistency Counter 1 */
lfh_cnt1.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_cnt1o, lfh_cnt1l)))
/* Format Version */
lfh_fmtv.lfh_i = c2x(reverse(charin(logctl_name, lfhdr+lfh_fmtvo, lfh_fmtvl)))
/* Log File Type */
lfh_logtyp.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_logtypo, lfh_logtypl)))
/* Number of Primary Log Files */
lfh_logact.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_logacto, lfh_logactl)))
/* Number of Secondary Log Files */
lfh_logina.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_loginao, lfh_loginal)))
/* Total pages in Log Files */
lfh_logsiz.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_logsizo, lfh_logsizl)))
/* Size of Transaction Table */
lfh_ttblsiz.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_ttblsizo, lfh_ttblsizl)))
/* Records Written before Soft Checkpoint */
lfh_softmax.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_softmaxo, lfh_softmaxl)))
/* First LSN after final Stop Using */
lfh_baselsn.lfh_i = c2x(charin(logctl_name, lfhdr+lfh_baselsno, lfh_baselsnl))
/* Next LSN prior to final Stop Using */
lfh_nextlsn.lfh_i = c2x(charin(logctl_name, lfhdr+lfh_nextlsno, lfh_nextlsnl))
/* First LSN of oldest in-flight trans */
lfh_lowlsn.lfh_i = c2x(charin(logctl_name, lfhdr+lfh_lowlsno, lfh_lowlsnl))
/* First LSN of oldest page in buff pool */
lfh_minblsn.lfh_i = c2x(charin(logctl_name, lfhdr+lfh_minblsno, lfh_minblsnl))
/* First TID after hard checkpoint */
lfh_basetid.lfh_i = c2x(charin(logctl_name, lfhdr+lfh_basetido, lfh_basetidl))
/* LSN of Head of the Log File */
lfh_headlsn.lfh_i = c2x(charin(logctl_name, lfhdr+lfh_headlsno, lfh_headlsnl))
/* Last LSN of the Log File */
lfh_taillsn.lfh_i = c2x(charin(logctl_name, lfhdr+lfh_taillsno, lfh_taillsnl))
/* Log File Path */
lfh_logpath.lfh_i = charin(logctl_name, lfhdr+lfh_logpatho, lfh_logpathl)
/* HFLAG */
lfh_hflag.lfh_i = c2x(reverse(charin(logctl_name, lfhdr+lfh_hflago, lfh_hflagl)))
/* Head Extent ID */
lfh_headext.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_headexto+2, 2)) || ,
reverse(charin(logctl_name, lfhdr+lfh_headexto, 2)), 5)
/* Last Extent ID */
lfh_lastext.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_lastexto+2, 2)) || ,
reverse(charin(logctl_name, lfhdr+lfh_lastexto, 2)), 5)
/* Database Creation Extent ID */
lfh_dbext.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_dbexto+2, 2)) || ,
reverse(charin(logctl_name, lfhdr+lfh_dbexto, 2)), 5)
/* Last Commit Extent ID */
lfh_cmitext.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_cmitexto+2, 2)) || ,
reverse(charin(logctl_name, lfhdr+lfh_cmitexto, 2)), 5)
/* First Archived Extent ID */
lfh_frstarc.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_frstarco+2, 2)) || ,
reverse(charin(logctl_name, lfhdr+lfh_frstarco, 2)), 5)
/* Last Archived Extent ID */
lfh_lastarc.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_lastarco+2, 2)) || ,
reverse(charin(logctl_name, lfhdr+lfh_lastarco, 2)), 5)
/* Next Media Recovery Extent ID */
lfh_nextrec.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_nextreco+2, 2)) || ,
reverse(charin(logctl_name, lfhdr+lfh_nextreco, 2)), 5)
/* First Media Recovery Extent ID */
lfh_frstrec.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_frstreco+2, 2)) || ,
reverse(charin(logctl_name, lfhdr+lfh_frstreco, 2)), 5)
/* First Media Recovery Deleted Extent ID */
lfh_frstdel.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_frstdelo+2, 2)) || ,
reverse(charin(logctl_name, lfhdr+lfh_frstdelo, 2)), 5)
/* Last Media Recovery Deleted Extent ID */
lfh_lastdel.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_lastdelo+2, 2)) || ,
reverse(charin(logctl_name, lfhdr+lfh_lastdelo, 2)), 5)
/* Head Media Recovery Extent ID */
lfh_headrec.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_headreco+2, 2)) || ,
reverse(charin(logctl_name, lfhdr+lfh_headreco, 2)), 5)
/* Number of File in File Array */
lfh_filecnt.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_filecnto, lfh_filecntl)))
/* Truncation LSN */
lfh_trnclsn.lfh_i = c2x(charin(logctl_name, lfhdr+lfh_trnclsno, lfh_trnclsnl))
/* Truncation Extent ID */
lfh_trncext.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_trncexto+2, 2)) || ,
reverse(charin(logctl_name, lfhdr+lfh_trncexto, 2)), 5)
/* Last CID */
lfh_lastcid.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_lastcido+2, 2)) || ,
reverse(charin(logctl_name, lfhdr+lfh_lastcido, 2)), 5)
/* Last Record Read LSN */
lfh_lrdlsn.lfh_i = c2x(charin(logctl_name, lfhdr+lfh_lrdlsno, lfh_lrdlsnl))
/* Consistency Counter 2 */
lfh_cnt2.lfh_i = c2d(reverse(charin(logctl_name, lfhdr+lfh_cnt2o, lfh_cnt2l)))
return
/******************************************************************
* SUBROUTINE: UPDLSN *
* *
* DESCRIPTIVE NAME: Update Base LSN *
* *
* DESCRIPTION: This routine updates the Base LSN fields in the *
* Log Control File to effectively reset the Log. *
* It sets the Base LSN to the highest LSN value *
* between the Base LSN itself, and the Page LSNs *
* from the Partial Page 1 of the Log Control File, *
* the Partial Page 2 of the Log Control File, *
* the LOGFILEHEAD, and the LOGFILETAIL. *
* *
* INPUT: none *
* *
* *
* OUTPUT: none *
* *
******************************************************************/
updlsn:
/*********************************************
Determine the Currently Active Log File Header
*********************************************/
/* Compare the Consistency Count fields from both Log File Headers */
if lfh_cnt1.1 >= lfh_cnt1.2 then /* Primary LFH is most recent */
do
active_lfh = lfhdr1 /* Set offset for using Primary Log File Header */
act_i = 1 /* Index of active LFH */
active_lfh_text = ,
' ' || cr_lf || ,
' ' || cr_lf || ,
'Active Log File Header: Primary' || cr_lf
end
else /* Secondary LFH is most recent */
do
active_lfh = lfhdr2 /* Set offset for using Secondary Log File Hdr */
act_i = 2 /* Index of active LFH */
active_lfh_text = ,
' ' || cr_lf || ,
' ' || cr_lf || ,
'Active Log File Header: Secondary' || cr_lf
end
call wrt2rpt active_lfh_text
baselsn_reset = 'NO' /* Initialize Base LSN reset indicator */
consist_cnt_reset = 'NO' /* Initialize Consistency Count reset indicator */
hflag_reset = 'NO' /* Initialize HFLAG reset indicator */
updlsn_text = ,
' ' || cr_lf || ,
' ' || cr_lf || ,
'Base LSN Comparison: ' || cr_lf || ,
' ' || cr_lf || ,
'.........Base LSN from Active Log Control File Header: ' || ,
lfh_baselsn.act_i || ,
cr_lf || ,
'.........Next LSN from Active Log Control File Header: ' || ,
lfh_nextlsn.act_i || ,
cr_lf || ,
'..........Low LSN from Active Log Control File Header: ' || ,
lfh_lowlsn.act_i || ,
cr_lf || ,
'.....Min Buff LSN from Active Log Control File Header: ' || ,
lfh_minblsn.act_i || ,
cr_lf || ,
'.........Head LSN from Active Log Control File Header: ' || ,
lfh_headlsn.act_i || ,
cr_lf || ,
'.........Tail LSN from Active Log Control File Header: ' || ,
lfh_taillsn.act_i || ,
cr_lf || ,
'...Truncation LSN from Active Log Control File Header: ' || ,
lfh_trnclsn.act_i || ,
cr_lf || ,
'....Last Read LSN from Active Log Control File Header: ' || ,
lfh_lrdlsn.act_i || ,
cr_lf || ,
' ' || cr_lf || ,
' ' || cr_lf
call wrt2rpt updlsn_text
/* Reset Base LSN to Next LSN if larger */
if lfh_baselsn.act_i < lfh_nextlsn.act_i then
do
lfh_baselsn.act_i = lfh_nextlsn.act_i
baselsn_reset = 'YES'
end
/* Reset Base LSN to Low LSN if larger */
if lfh_baselsn.act_i < lfh_lowlsn.act_i then
do
lfh_baselsn.act_i = lfh_lowlsn.act_i
baselsn_reset = 'YES'
end
/* Reset Base LSN to Min Buff LSN if larger */
if lfh_baselsn.act_i < lfh_minblsn.act_i then
do
lfh_baselsn.act_i = lfh_minblsn.act_i
baselsn_reset = 'YES'
end
/* Reset Base LSN to Head LSN if larger */
if lfh_baselsn.act_i < lfh_headlsn.act_i then
do
lfh_baselsn.act_i = lfh_headlsn.act_i
baselsn_reset = 'YES'
end
/* Reset Base LSN to Tail LSN if larger */
if lfh_baselsn.act_i < lfh_taillsn.act_i then
do
lfh_baselsn.act_i = lfh_taillsn.act_i
baselsn_reset = 'YES'
end
/* Reset Base LSN to Truncation LSN if larger */
if lfh_baselsn.act_i < lfh_trnclsn.act_i then
do
lfh_baselsn.act_i = lfh_trnclsn.act_i
baselsn_reset = 'YES'
end
/* Reset Base LSN to Last Read LSN if larger */
if lfh_baselsn.act_i < lfh_lrdlsn.act_i then
do
lfh_baselsn.act_i = lfh_lrdlsn.act_i
baselsn_reset = 'YES'
end
/* Update the Consistency Count in the Active Log File Header if necessary */
if lfh_cnt1.act_i \= lfh_cnt2.act_i then
do
lfh_cnt1.act_i = max(lfh_cnt1.act_i, lfh_cnt2.act_i)
lfh_cnt2.act_i = lfh_cnt1.act_i
consist_cnt_reset = 'YES'
end
/* Update the HFLAG indicators in the Active Log File Header if necessary */
if lfh_hflag.act_i \= 1 then
do
lfh_hflag.act_i = 1 /* Mark database as consistent */
hflag_reset = 'YES'
end
if baselsn_reset = 'NO' then
do
/* Increment Base LSN by Log File Size Factor if desired */
/* Note: This routine may cause the Base LSN to be reset */
/* even though it has not been reset yet. */
call quantum_leap
end
if ((baselsn_reset = 'NO') & ,
(consist_cnt_reset = 'NO') & ,
(hflag_reset = 'NO')) then
do
say 'The Log File Header appears to be in a reset state and has not been changed.'
error_text = ' ' || cr_lf || ,
'The Log File Header appears to be in a reset state ' || ,
'and has not been changed.' || cr_lf || ,
' ' || cr_lf
call wrt2rpt error_text
end
else
do
if baselsn_reset = 'YES' then
do
/* Write the new Base LSN to the Log Control File */
rc = charout(logctl_name, x2c(lfh_baselsn.act_i), active_lfh+lfh_baselsno)
rst_text = 'The LFH has been reset with a new Base LSN of: ' || ,
lfh_baselsn.act_i || cr_lf
say rst_text
call wrt2rpt rst_text
end
if consist_cnt_reset = 'YES' then
do
/* Write the two Consistency Count Values */
rc = charout(logctl_name, d2c(lfh_cnt1.act_i), active_lfh+lfh_cnt1o)
rc = charout(logctl_name, d2c(lfh_cnt2.act_i), active_lfh+lfh_cnt2o)
rst_text = 'The LFH has been updated with a Consistency Count of: ' || ,
lfh_cnt1.act_i || cr_lf
say rst_text
call wrt2rpt rst_text
end
if hflag_reset = 'YES' then
do
/* Write the new HFLAG value */
rc = charout(logctl_name, x2c(lfh_hflag.act_i), active_lfh+lfh_hflago)
rst_text = 'The LFH has been reset with an HFLAG value of: ' || ,
lfh_hflag.act_i || cr_lf
say rst_text
call wrt2rpt rst_text
end
end
return
/******************************************************************
* SUBROUTINE: QUANTUM_LEAP *
* *
* DESCRIPTIVE NAME: Increment the Base LSN by Log File Size *
* *
* DESCRIPTION: This routine prompts the user to determine *
* if they would like to make a Quantum Leap by *
* incrementing the Base LSN by the size of a single *
* Log File. This may be necessary in some cases *
* (in which there has not been a previous soft *
* checkpoint) because the Log Control File will *
* not have the most current LSN information. *
* *
* By incrementing the Base LSN by the size of a *
* single Log File, it is fairly certain that the *
* Base LSN will be incremented to a value which *
* will truly put it in a reset state. *
* *
* *
* INPUT: act_i - Shared variable containing the index number of *
* Primary or Secondary Log File Header that is *
* currently the active LFH. *
* *
* *
* OUTPUT: none *
* *
******************************************************************/
quantum_leap:
say " "
say ,
" ╔══════════════════════════════════════════════════════════════════════╗ "
say ,
" ║ ║ "
say ,
" ║ From the information in the Log Control File, the Log already ║ "
say ,
" ║ appears to be in a Reset State. In certain cases, this may ║ "
say ,
" ║ be misleading. ║ "
say ,
" ║ Therefore, would you like to increase the Base LSN in order to ║ "
say ,
" ║ enhance the probability that the Log has actually been ║ "
say ,
" ║ reset? (y/n) ║ "
say ,
" ║ If so, type 'y' and press ENTER; ║ "
say ,
" ║ Otherwise, type 'n' and press ENTER. ║ "
say ,
" ║ ║ "
say ,
" ╚══════════════════════════════════════════════════════════════════════╝ "
say " "
say " "
pull quantum_leap_answer
if quantum_leap_answer = 'Y' then
do
/* Increase the Base LSN by a factor equal to the size of a Log File */
lfh_baselsn.act_i = d2x(x2d(lfh_baselsn.act_i) + (dbc_logsiz * 4096), (lfh_baselsnl*2))
/* Report the Quantum Leap in the Report File */
leap_text = ' ' || cr_lf || ,
'A Quantum Leap of the Base LSN was requested. ' || ,
' ' || cr_lf || ,
' ' || cr_lf
call wrt2rpt leap_text
/* Set this flag so the new Base LSN will be written to the Log */
baselsn_reset = 'YES'
end
return
/******************************************************************
* SUBROUTINE: GENERAL_HELP *
* *
* DESCRIPTIVE NAME: RESETLOG General Help *
* *
* DESCRIPTION: This routine displays the Help panels for the *
* Reset Log Control File tool. This routine *
* receives control when the input parameter is *
* a "?" instead of the database name. A brief *
* description of the RESETLOG Tool and its *
* syntax is included in the Help panels. *
* *
* INPUT: none *
* *
* *
* OUTPUT: none *
* *
******************************************************************/
general_help:
/* Display help panel */
say " "
say ,
" ┌────────────────────────────────────────────────────────────┐ "
say ,
" │ ┌────────────────────────────────────────┐ │ "
say ,
" │ │ *** R E S E T L O G *** │ │ "
say ,
" │ │ Reset the Log Control File │ │ "
say ,
" │ │ Version 3.1 │ │ "
say ,
" │ └────────────────────────────────────────┘ │ "
say ,
" │ ▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀ │ "
say ,
" │ ▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀ │ "
say ,
" │ ▀▀▀▀ ▀▀▀ ▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀ │ "
say ,
" │ ▀▀▀▀ ▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀ ▀▀▀▀▀▀ │ "
say ,
" │ ▀▀▀▀ ▀▀▀▀▀▀▀▀▀ ▀▀▀ ▀▀▀▀▀ ▀▀▀ │ "
say ,
" │ ▀▀▀▀ ▀▀▀ ▀▀▀▀ ▀▀▀ ▀▀▀ ▀▀▀ │ "
say ,
" │ ▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀ ▀ ▀▀▀▀ │ "
say ,
" │ ▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀ ▀▀▀▀ │ "
say ,
" └────────────────────────────────────────────────────────────┘ "
say ,
" ╔══════════════════════════════════════════════════════════════════════╗ "
say ,
" ║ The RESETLOG Tool is a mechanism for resetting the Log Control ║ "
say ,
" ║ File which governs the recovery of the database from the ║ "
say ,
" ║ Write-Ahead Log. By reseting the Log Control File, the database ║ "
say ,
" ║ will appear to be usable and not need recovery. ║ "
say ,
" ║ CAUTION: The use of this tool will prevent committed changes ║ "
say ,
" ║ which did not make it to media from being recovered and data ║ "
say ,
" ║ integrity could be lost. ║ "
say ,
" ╚══════════════════════════════════════════════════════════════════════╝ "
say " "
'pause'
say " "
say " "
say " "
say " "
say ,
" Syntax: RESETLOG [dbname] [rptname] "
say " "
say " "
say ,
" where: [dbname] is the alias name of the database. "
say " If no database name is specified , the user "
say " will be prompted for the database name. "
say " "
say " "
say ,
" [rptname] is the report file name. "
say " If no report file name is specified, then no "
say " report will be generated. "
say " "
say " "
say " "
say " "
say " "
say " "
say " "
say " "
return