create or replace package body initjvmaux is deallocate_rollback_name varchar2(30); rollback_set_command varchar2(50); current_step varchar2(40); standalone_action boolean := false; do_debug_output boolean := false; alt_tablespace_limit number := 0; procedure exec (x varchar2) as begin dbms_output.put_line(substr(x, 1, 250)); if login_user != 'SYS' then declare foo exception; pragma exception_init(foo,-1031); begin raise foo; end; end if; execute immediate dbms_assert.noop(x); end; procedure drp (x varchar2) as begin exec(x); exception when others then if sqlcode not in (-4080, -1418, -1919, -942, -1432, -4043, -1918, -2289, -6550, -1598, -1534, -1434) then raise; end if; end; procedure rollbacksetup as x number; rollback_segment_name varchar2(30); BEGIN deallocate_rollback_name := null; rollback_set_command := null; -- no rollback actions when undo_management is AUTO begin select num into x from v$parameter where name='undo_management' and value='AUTO'; return; exception when no_data_found then null; end; begin select segment_name into rollback_segment_name from dba_rollback_segs where tablespace_name='SYSTEM' and next_extent*max_extents>100000000 and status='ONLINE' and initial_extent>1000000 and rownum < 2; debug_output('found good enough rollback segment ' || rollback_segment_name); exception when no_data_found then debug_output('didnt find good enough rollback segment'); x := 1; rollback_segment_name := 'MONSTER'; loop begin select segment_name into deallocate_rollback_name from dba_rollback_segs where segment_name = rollback_segment_name; debug_output('skipped rollback segment ' || rollback_segment_name); exception when no_data_found then deallocate_rollback_name := rollback_segment_name; exec('create rollback segment ' || rollback_segment_name || ' storage (initial 2 m next 2 m maxextents unlimited)'); exec('alter rollback segment ' || rollback_segment_name || ' online'); debug_output('created rollback segment ' || rollback_segment_name); exit; end; rollback_segment_name := 'MONSTER' || x; x := x + 1; end loop; end; rollback_set_command := 'set transaction use rollback segment ' || rollback_segment_name; END; procedure rollbackset as begin if rollback_set_command is not null then execute immediate dbms_assert.noop(rollback_set_command); end if; end; procedure rollbackcleanup as counter number := 0; begin if deallocate_rollback_name is not null then loop begin drp('alter rollback segment ' || deallocate_rollback_name || ' offline'); begin drp('drop rollback segment ' || deallocate_rollback_name); exit; exception when others then if sqlcode not in (-1545) then raise; end if; end; counter := counter + 1; dbms_output.put_line('retrying because of ORA-01545'); dbms_lock.sleep(2); exit when counter > 150; exception when others then if sqlcode in (-20000) then dbms_output.disable; dbms_output.enable; else raise; end if; end; end loop; end if; end; procedure setloading as begin dbms_registry.loading('JAVAVM', 'JServer JAVA Virtual Machine', 'initjvmaux.validate_javavm'); end; procedure setloaded as begin dbms_registry.loaded('JAVAVM'); validate_javavm; end; procedure validate_javavm as begin execute immediate 'declare junk varchar2(10) := dbms_java.longname(''foo''); begin null; end;'; dbms_registry.valid('JAVAVM'); exception when others then dbms_registry.invalid('JAVAVM'); end; function registrystatus return varchar2 as result varchar2(30) := dbms_registry.status('JAVAVM'); begin if result = 'VALID' then result := 'LOADED'; end if; return result; end; function startup_pending_p return boolean as result boolean := false; rmjvmtime date; begin begin select rmjvmtime into rmjvmtime from java$jvm$status where rmjvmtime = (select startup_time from v$instance); result := true; exception when no_data_found then null; end; return result; end; procedure check_sizes_for_cjs(required_shared_pool number := 24000000, required_shared_pool_if_10049 number := 70000000, required_java_pool number := 12000000, required_tablespace number := 70000000) as foo exception; pragma exception_init(foo, -29554); free number; shared_pool_limit number := required_shared_pool; tablespace_limit number := required_tablespace; step_name varchar2(40) := 'CHECK_SIZES'; sga_target_value number := 0; begin if alt_tablespace_limit != 0 then tablespace_limit := alt_tablespace_limit; end if; if startstep(step_name) then exec('alter system flush shared_pool'); begin select 0 into free from v$parameter2 where name='event' and value like '%10049 trace%' and not exists (select * from v$parameter2 where name='event' and value='10049 trace name all off'); shared_pool_limit := required_shared_pool_if_10049; exception when no_data_found then null; end; begin select value into sga_target_value from v$parameter2 where name='sga_target'; exception when no_data_found then null; end; if sga_target_value = 0 then begin select sum(bytes) into free from v$sgastat where pool='java pool'; exception when no_data_found then free := 0; end; if free < required_java_pool then abort_message('Aborting because available java pool, ' || free || ', is less than ' || required_java_pool || ' .'); raise foo; end if; declare msg1 varchar2(200); begin select bytes into free from v$sgastat where name='free memory' and pool='shared pool' and bytes < shared_pool_limit; msg1 := 'Aborting because available shared pool, ' || free || ', is less than ' || shared_pool_limit || ' .'; if shared_pool_limit = required_shared_pool_if_10049 then abort_message(msg1, 'Required value is large because event 10049 is set.'); else abort_message(msg1); end if; raise foo; exception when no_data_found then null; end; else if sga_target_value < required_java_pool + shared_pool_limit + 1000000 then abort_message('Aborting because sga_target value, ' || sga_target_value || ', is not sufficiently larger than the sum of '|| ' the required java_pool size, ' || required_java_pool || ', and the required shared_pool size, ' || shared_pool_limit || ' .'); raise foo; end if; end if; select sum(length) into free from idl_ub1$,x$joxft where obj#=joxftobn and bitand(joxftflags,96)!=0; tablespace_limit := tablespace_limit - free; select sum(length) into free from idl_ub1$ u,obj$ o where o.obj#=u.obj# and o.type#=56 and name like 'Locale%'; tablespace_limit := tablespace_limit - free; select sum(bytes) into free from dba_free_space where tablespace_name='SYSTEM'; if free < tablespace_limit then abort_message('Aborting because available SYSTEM tablespace, ' || free || ', is less than ' || tablespace_limit || ' .'); raise foo; end if; end if; endstep; delete from java$jvm$steps$done where step = step_name; commit; end; procedure create_if_not_present(command varchar2) as begin exec(command); exception when others then if sqlcode not in (-955, -1921) then raise; end if; end; procedure abort_message(msg1 varchar2, msg2 varchar2 default null) as begin dbms_output.put_line('.'); dbms_output.put_line('###'); dbms_output.put_line('### ' || msg1); if msg2 is not null then dbms_output.put_line('### ' || msg2);end if; dbms_output.put_line('###'); dbms_output.put_line('.'); end; function jvmuscript return varchar2 as result varchar2(30) := 'jvmempty.sql'; stat varchar2(30); registry_version varchar2(30); begin begin select status, version into stat, registry_version from dba_registry where comp_id='JAVAVM'; if stat = 'UPGRADING' then result := 'jvmu' || substr(translate(registry_version,'x.','x'), 1, 3) || '.sql'; end if; exception when no_data_found then null; end; return result; end; function jvmversion return varchar2 as begin return dbms_registry.version('JAVAVM'); end; function current_release_version return varchar2 as v varchar2(20); begin SELECT version INTO v from v$instance; return v; end; procedure drop_sys_class(name varchar2) as begin drp('drop java class "' || name || '"'); drp('drop public synonym "' || name || '"'); end; procedure drop_sys_resource(name varchar2) as begin drp('drop java resource "' || name || '"'); end; function do_jis_drop return boolean as junk number; begin select count(*) into junk from obj$ where type#=4 and owner#=0 and name='ALL_IDS'; if junk = 0 then return false; end if; update obj$ set status=5 where obj#=(select obj# from obj$,javasnm$ where owner#=0 and type#=29 and short(+)=name and nvl(longdbcs,name)='oracle/aurora/rdbms/Compiler'); commit; return true; end; -- actions: LOAD initjvm.sql -- UNLOAD rmjvm.sql -- UPGRADE udjvmrm from jvmdbmig -- DOWNGRADE* jvmexxx -- STANDALONE initsec -- If input action is compatible with the current action status, as -- given by the values in the single row in table java$jvm$status, -- then change java$jvm$status to reflect that the input action is -- now (or again) in progress. If the input action is incompatible, -- set the punting column in java$jvm$status so that until a subsequent -- endaction or startaction call resets things, startstep will always -- indicate that a given step should be skipped. procedure startaction_outarg(newaction IN OUT varchar2) as lastaction varchar2(40); inprogress varchar2(1); inaction varchar(40) := newaction; begin begin select action,inprogress into lastaction,inprogress from java$jvm$status; exception when no_data_found then lastaction := 'NONE'; inprogress := 'N'; insert into java$jvm$status values('NONE','N',null,null,'TRUE'); end; standalone_action := false; if inprogress = 'Y' then if not (newaction = lastaction or (newaction = 'UNLOAD' and lastaction = 'LOAD') or (newaction = 'DOWNGRADE_TO_9.2.0' and lastaction = 'DOWNGRADE_TO_10.1.0') or (newaction = 'DOWNGRADE_TO_9.0.1' and lastaction = 'DOWNGRADE_TO_9.2.0') or (newaction = 'DOWNGRADE_TO_8.1.7' and lastaction = 'DOWNGRADE_TO_9.0.1') or (newaction = 'DOWNGRADE_TO_8.1.6' and lastaction = 'DOWNGRADE_TO_8.1.7') or (newaction = 'DOWNGRADE_TO_8.1.5' and lastaction = 'DOWNGRADE_TO_8.1.6')) then newaction := 'PUNT'; end if; elsif newaction = 'LOAD' then if lastaction != 'UNLOAD' and lastaction != 'NONE' then newaction := 'PUNT'; end if; elsif newaction = 'UPGRADE' then if (not (lastaction = 'LOAD' or lastaction = 'NONE')) or jvmversion = current_release_version then newaction := 'PUNT'; end if; elsif newaction = 'DOWNGRADERELOAD' then if substr(lastaction,1,9) != 'DOWNGRADE' then newaction := 'PUNT'; end if; elsif substr(newaction,1,9) = 'DOWNGRADE' then if lastaction != 'LOAD' then newaction := 'PUNT'; end if; elsif newaction = 'PATCHSET' then if lastaction != 'LOAD' then newaction := 'PUNT'; end if; elsif newaction = 'STANDALONE' then if lastaction != 'LOAD' then newaction := 'PUNT'; end if; elsif newaction != 'UNLOAD' then newaction := 'PUNT'; end if; if newaction = 'PUNT' then debug_output('startaction(' || inaction || ') PUNTED'); update java$jvm$status set punting = 'TRUE'; elsif newaction = 'STANDALONE' then standalone_action := true; update java$jvm$status set punting = 'FALSE'; else debug_output('startaction(' || inaction || ') STARTED'); update java$jvm$status set action = newaction, inprogress = 'Y', execid = currentexecid, punting = 'FALSE'; end if; commit; end; procedure startaction(newaction IN varchar2) as newaction_outarg varchar2(40) := newaction; begin startaction_outarg(newaction_outarg); end; procedure endaction_outarg(action OUT varchar2) as begin if standalone_action then update java$jvm$status set punting = 'FALSE'; standalone_action := false; action := 'STANDALONE'; else begin select action into action from java$jvm$status where punting = 'FALSE' and execid = currentexecid; delete from java$jvm$steps$done; update java$jvm$status set inprogress = 'N', execid = null; debug_output('endaction(' || action || ') DONE'); exception when no_data_found then debug_output('endaction while PUNTING'); update java$jvm$status set punting = 'FALSE'; action := 'PUNT'; end; end if; commit; end; procedure endaction as outarg varchar2(40); begin endaction_outarg(outarg); end; procedure endaction_asload as outarg varchar2(40); begin endaction_outarg(outarg); if (outarg != 'PUNT') then update java$jvm$status set action = 'LOAD'; commit; end if; end; function startstep(newstep varchar2) return boolean as punting varchar2(5); execid varchar2(40); oldstep varchar2(40); try boolean := false; begin current_step := null; begin select execid, punting into execid, punting from java$jvm$status; if punting = 'FALSE' then debug_output('NOT YET PUNTING AT ' || newstep); if standalone_action then try := true; update java$jvm$status set punting = 'TRUE'; elsif execid = currentexecid then begin select step into oldstep from java$jvm$steps$done where step = newstep; exception when no_data_found then try := true; current_step := newstep; update java$jvm$status set punting = 'TRUE'; end; else debug_output('startstep(' || newstep || ') PUNTED'); update java$jvm$status set punting = 'TRUE'; end if; end if; exception when no_data_found then insert into java$jvm$status values('NONE','N',null,null,'TRUE'); end; commit; if try then debug_output('TRIED ' || newstep); else debug_output('SKIPPED ' || newstep); end if; return try; end; procedure endstep as begin if current_step is not null then debug_output('COMPLETED ' || current_step); insert into java$jvm$steps$done values(current_step); current_step := null; end if; update java$jvm$status set punting = 'FALSE'; commit; end; function currentexecid return varchar2 as execid varchar2(40); begin select sid||'-'||serial# into execid from v$session where sid = (select unique(sid) from v$mystat); return execid; end; procedure set_debug_output_on as begin do_debug_output := true; end; procedure set_debug_output_off as begin do_debug_output := false; end; procedure debug_output(line varchar2) as begin if do_debug_output then dbms_output.put_line(line);end if; end; procedure set_alt_tablespace_limit(l number) as begin alt_tablespace_limit := l; end; end;