DBA Data[Home] [Help]

PACKAGE BODY: SYS.INITJVMAUX

Source


1 package body initjvmaux is
2 
3 deallocate_rollback_name varchar2(30);
4 sec_rollback_segment_name varchar2(32);
5 
6 current_step varchar2(40);
7 standalone_action boolean := false;
8 do_debug_output boolean := false;
9 
10 alt_tablespace_limit number := 0;
11 
12 procedure require_sys as
13 begin
14 if login_user != 'SYS' then
15   declare
16    foo exception;
17    pragma exception_init(foo,-1031);
18   begin
19    raise foo;
20   end;
21 end if;
22 end;
23 
24 procedure exec (x varchar2) as
25 begin
26 dbms_output.put_line(substr(x, 1, 250));
27 require_sys;
28 execute immediate x;
29 end;
30 
31 procedure drp (x varchar2) as
32 begin
33 exec(x);
34 exception
35 when others then
36 if sqlcode not in (-4080, -1418, -1919, -942, -1432, -4043, -1918, -2289,
37                    -6550, -1598, -1534, -1434) then raise; end if;
38 end;
39 
40 procedure rollbacksetup as
41   x number;
42   rollback_segment_name varchar2(30);
43 BEGIN
44   deallocate_rollback_name := null;
45   sec_rollback_segment_name := null;
46 
47 -- no rollback actions when undo_management is AUTO
48   begin
49     select num into x from v$parameter
50        where name='undo_management' and value='AUTO';
51     return;
52   exception when no_data_found then null;
53   end;
54 
55 -- or in pdbs
56   declare
57     pdbname varchar2(128) := sys_context('USERENV', 'CON_NAME');
58   begin
59     if pdbname is not null and pdbname != 'CDB$ROOT' then return; end if;
60   end;
61 
62   begin
63     select segment_name into rollback_segment_name from dba_rollback_segs
64       where tablespace_name='SYSTEM' and next_extent*max_extents>100000000 and
65             status='ONLINE' and initial_extent>1000000 and rownum < 2;
66     debug_output('found good enough rollback segment ' ||
67        rollback_segment_name);
68   exception when no_data_found then
69     debug_output('didnt find good enough rollback segment');
70     x := 1;
71     rollback_segment_name := 'MONSTER';
72     loop
73       begin
74         select segment_name into deallocate_rollback_name
75         from dba_rollback_segs where segment_name = rollback_segment_name;
76         debug_output('skipped rollback segment ' || rollback_segment_name);
77       exception when no_data_found then
78         deallocate_rollback_name := rollback_segment_name;
79         sec_rollback_segment_name :=
80           sys.dbms_assert.simple_sql_name(rollback_segment_name);
81         begin
82           exec('create rollback segment ' || sec_rollback_segment_name ||
83                ' storage (initial 2 m next 2 m maxextents unlimited)');
84           exec('alter rollback segment ' ||
85                sec_rollback_segment_name || ' online');
86           debug_output('created rollback segment ' || rollback_segment_name);
87         exception when others then
88           if sqlcode not in (-65091) then raise; end if;
89           sec_rollback_segment_name := null;
90           deallocate_rollback_name := null;
91           return;
92         end;
93         exit;
94       end;
95       rollback_segment_name := 'MONSTER' || x;
96       x := x + 1;
97     end loop;
98   end;
99 
100   sec_rollback_segment_name :=
101     sys.dbms_assert.simple_sql_name(rollback_segment_name);
102 END;
103 
104 procedure rollbackset as
105 begin
106 if sec_rollback_segment_name is not null then
107    execute immediate 'set transaction use rollback segment ' ||
108      sec_rollback_segment_name;
109 end if;
110 end;
111 
112 procedure rollbackcleanup as
113 counter number := 0;
114 begin
115 if deallocate_rollback_name is not null then
116     loop
117     declare
118       sec_name varchar2(32); --  30+2
119     begin
120     sec_name := sys.dbms_assert.simple_sql_name(deallocate_rollback_name);
121     drp('alter rollback segment ' || sec_name || ' offline');
122     begin
123     drp('drop rollback segment ' || sec_name);
124     exit;
125     exception when others then
126         if sqlcode not in (-1545) then raise; end if;
127     end;
128     counter := counter + 1;
129     dbms_output.put_line('retrying because of ORA-01545');
130     dbms_lock.sleep(2);
131     exit when counter > 150;
132     exception when others then
133       if sqlcode in (-20000) then
134         dbms_output.disable;
135         dbms_output.enable;
136       else
137         raise;
138       end if;
139     end;
140     end loop;
141 end if;
142 end;
143 
144 procedure setloading as
145 begin
146 dbms_registry.loading('JAVAVM',
147                       'JServer JAVA Virtual Machine',
148                       'initjvmaux.validate_javavm');
149 end;
150 
151 procedure setloaded as
152 begin
153 dbms_registry.loaded('JAVAVM');
154 validate_javavm;
155 end;
156 
157 procedure validate_javavm as
158 begin
159   execute immediate
160   'declare junk varchar2(10) := dbms_java.longname(''foo''); begin null; end;';
161   dbms_registry.valid('JAVAVM');
162 exception when others then
163   dbms_registry.invalid('JAVAVM');
164 end;
165 
166 function registrystatus return varchar2 as
167 result varchar2(30) := dbms_registry.status('JAVAVM');
168 begin
169   if result = 'VALID' then result := 'LOADED'; end if;
170   return result;
171 end;
172 
173 function startup_pending_p return boolean as
174  result boolean := false;
175  rmjvmtime date;
176 begin
177   begin
178     select rmjvmtime into rmjvmtime from java$jvm$status
179        where rmjvmtime = (select startup_time from v$instance);
180     result := true;
181   exception when no_data_found then null;
182   end;
183   return result;
184 end;
185 
186 procedure check_sizes_for_cjs(required_shared_pool number := 24000000,
187                               required_shared_pool_if_10049
188                                       number := 70000000,
189                               required_java_pool number := 12000000,
190                               required_tablespace number := 70000000) as
191 foo exception;
192 pragma exception_init(foo, -29554);
193 free number;
194 shared_pool_limit number := required_shared_pool;
195 tablespace_limit number := required_tablespace;
196 step_name varchar2(40) := 'CHECK_SIZES';
197 sga_target_value number := 0;
198 begin
199   if alt_tablespace_limit != 0 then
200     tablespace_limit := alt_tablespace_limit;
201   end if;
202   if startstep(step_name) then
203     exec('alter system flush shared_pool');
204     begin
205       select 0 into free from v$parameter2
206          where name='event' and value like '%10049 trace%'
207          and not exists (select * from v$parameter2
208                          where name='event'
209                          and value='10049 trace name all off');
210       shared_pool_limit := required_shared_pool_if_10049;
211     exception when no_data_found then null;
212     end;
213     begin
214       select current_size into sga_target_value
215         from v$memory_dynamic_components
216         where component='SGA Target';
217     exception when no_data_found then null;
218     end;
219     if sga_target_value = 0 then
220       begin
221         select sum(bytes) into free from v$sgastat where pool='java pool';
222       exception when no_data_found then free := 0;
223       end;
224       if free < required_java_pool then
225         abort_message('Aborting because available java pool, ' || free ||
226                       ', is less than ' || required_java_pool || ' .');
227         raise foo;
228       end if;
229       declare
230         msg1 varchar2(200);
231       begin
232         select bytes into free from v$sgastat
233            where name='free memory' and
234                  pool='shared pool' and
235                  bytes < shared_pool_limit;
236         msg1 := 'Aborting because available shared pool, ' || free ||
237                 ', is less than ' || shared_pool_limit || ' .';
238         if shared_pool_limit = required_shared_pool_if_10049 then
239           abort_message(msg1,
240                         'Required value is large because event 10049 is set.');
241         else
242           abort_message(msg1);
243         end if;
244         raise foo;
245       exception when no_data_found then null;
246       end;
247     else
248       if sga_target_value <
249          required_java_pool + shared_pool_limit + 1000000 then
250         abort_message('Aborting because sga_target value, ' ||
251                        sga_target_value ||
252                       ', is not sufficiently larger than the sum of '||
253                       ' the required java_pool size, ' || required_java_pool ||
254                       ', and the required shared_pool size, ' ||
255                       shared_pool_limit || ' .');
256         raise foo;
257       end if;
258     end if;
259     if sys_context('USERENV', 'CON_ID') < 2 then
260       select sum(length) into free from idl_ub1$,x$joxft
261          where obj#=joxftobn and bitand(joxftflags,96)!=0;
262       tablespace_limit := tablespace_limit - free;
263       select sum(length) into free from idl_ub1$ u,obj$ o
264          where o.obj#=u.obj# and o.type#=56 and name like 'Locale%';
265       tablespace_limit := tablespace_limit - free;
266       select sum(bytes) into free from dba_free_space
267          where tablespace_name='SYSTEM';
268       if free < tablespace_limit then
269         abort_message('Aborting because available SYSTEM tablespace, ' ||
270                       free ||
271                       ', is less than ' || tablespace_limit || ' .');
272         raise foo;
273       end if;
274     end if;
275   end if;
276   endstep;
277   delete from java$jvm$steps$done where step = step_name;
278   commit;
279 end;
280 
281 procedure create_if_not_present(command varchar2) as
282 begin
283   exec(command);
284 exception when others then
285   if sqlcode not in (-955, -1921) then raise; end if;
286 end;
287 
288 procedure alter_if_not_present(command varchar2) as
289 begin
290   exec(command);
291 exception when others then
292   if sqlcode not in (-2260) then raise; end if;
293 end;
294 
295 procedure abort_message(msg1 varchar2, msg2 varchar2 default null) as
296 begin
297     dbms_output.put_line('.');
298     dbms_output.put_line('###');
299     dbms_output.put_line('### ' || msg1);
300     if msg2 is not null then dbms_output.put_line('### ' || msg2);end if;
301     dbms_output.put_line('###');
302     dbms_output.put_line('.');
303 end;
304 
305 function jvmuscript(patchset varchar2) return varchar2 as
306 result varchar2(30) := 'jvmempty.sql';
307 stat varchar2(30);
308 registry_version varchar2(30);
309 begin
310   begin
311     select status, version into stat, registry_version from dba_registry
312       where comp_id='JAVAVM';
313     if stat = 'UPGRADING' or patchset = 'TRUE' then
314       result := 'jvmu' || substr(translate(registry_version,'x.','x'), 1, 3) || '.sql';
315     end if;
316   exception when no_data_found then null;
317   end;
318   return result;
319 end;
320 
321 function jvmversion return varchar2 as
322 begin
323   return dbms_registry.version('JAVAVM');
324 end;
325 
326 function current_release_version return varchar2 as
327 v varchar2(20);
328 begin
329   SELECT version INTO v from v$instance;
330   return v;
331 end;
332 
333 procedure drop_sys_class(name varchar2) as
334 begin
335   drp('drop java class ' || sys.dbms_assert.enquote_name(name, false));
336   drp('drop public synonym ' || sys.dbms_assert.enquote_name(name, false));
337 end;
338 
339 procedure drop_sys_resource(name varchar2) as
340 begin
341   drp('drop java resource ' || sys.dbms_assert.enquote_name(name, false));
342 end;
343 
344 function compare_releases(first varchar2, second varchar2) return varchar2 as
345  posx number:=0;
346  indx number;
347  posy number:=0;
348  indy number;
349  xt varchar2(100);
350  yt varchar2(100);
351  res varchar2(30):='SAME';
352 begin
353  if first is null then return 'FIRST IS NULL'; end if;
354  loop
355   indx := instr(first, '.', posx + 1);
356   indy := instr(second, '.', posy + 1);
357   if indx = 0 then indx := 10000; end if;
358   if indy = 0 then indy := 10000; end if;
359   xt := substr(first, posx + 1, indx - posx - 1);
360   yt := substr(second, posx + 1, indy - posy - 1);
361   if xt <> yt then
362     if least(10000, xt, yt) = least(10000, xt) then
363       res := 'FIRST IS OLDER';
364     else
365       res := 'FIRST IS NEWER';
366     end if;
367     exit;
368   end if;
369   if indx = 10000 then
370     if indy < 10000 then res := 'FIRST IS OLDER'; end if;
371     exit;
372   end if;
373   if indy = 10000 then
374     res := 'FIRST IS NEWER';
375     exit;
376   end if;
377   posx := indx;
378   posy := indy;
379  end loop;
380  return res;
381 end;
382 
383 -- actions: LOAD       initjvm.sql
384 --          UNLOAD     rmjvm.sql
385 --          UPGRADE    udjvmrm from jvmdbmig
386 --          DOWNGRADE* jvmexxx
387 --          STANDALONE initsec
388 
389 -- If input action is compatible with the current action status, as
390 -- given by the values in the single row in table java$jvm$status,
391 -- then change java$jvm$status to reflect that the input action is
392 -- now (or again) in progress.  If the input action is incompatible,
393 -- set the punting column in java$jvm$status so that until a subsequent
394 -- endaction or startaction call resets things, startstep will always
395 -- indicate that a given step should be skipped.
396 procedure startaction_outarg(newaction IN OUT varchar2) as
397 lastaction varchar2(40);
398 inprogress varchar2(1);
399 inaction varchar(40) := newaction;
400 begin
401   begin
402     select action,inprogress into lastaction,inprogress from java$jvm$status;
403   exception when no_data_found then
404     lastaction := 'NONE';
405     inprogress := 'N';
406     insert into java$jvm$status values('NONE','N',null,null,'TRUE');
407   end;
408   standalone_action := false;
409   if inprogress = 'Y' then
410     if not (newaction = lastaction or
411             (newaction = 'UNLOAD' and lastaction = 'LOAD') or
412             (substr(newaction,1,13) = 'DOWNGRADE_TO_' and
413              substr(lastaction,1,13) = 'DOWNGRADE_TO_')) then
414       newaction := 'PUNT';
415     end if;
416   elsif newaction = 'LOAD' then
417     if lastaction != 'UNLOAD' and lastaction != 'NONE' then
418       newaction := 'PUNT';
419     end if;
420   elsif newaction = 'UPGRADE' then
421     if (not (lastaction = 'LOAD' or lastaction = 'NONE')) or
422        jvmversion = current_release_version
423     then
424       newaction := 'PUNT';
425     end if;
426   elsif newaction = 'DOWNGRADERELOAD' then
427     if substr(lastaction,1,9) != 'DOWNGRADE' then
428       newaction := 'PUNT';
429     end if;
430   elsif substr(newaction,1,9) = 'DOWNGRADE' then
431     if lastaction != 'LOAD' then
432       newaction := 'PUNT';
433     end if;
434   elsif newaction = 'PATCHSET' then
435     if lastaction != 'LOAD' then
436       newaction := 'PUNT';
437     end if;
438   elsif newaction = 'STANDALONE' then
439     if lastaction != 'LOAD' then
440       newaction := 'PUNT';
441     end if;
442   elsif newaction != 'UNLOAD' then
443     newaction := 'PUNT';
444   end if;
445 
446   if newaction = 'PUNT' then
447     debug_output('startaction(' || inaction || ') PUNTED');
448     update java$jvm$status set punting = 'TRUE';
449   elsif newaction = 'STANDALONE' then
450     standalone_action := true;
451     update java$jvm$status set punting = 'FALSE';
452   else
453     debug_output('startaction(' || inaction || ') STARTED');
454     update java$jvm$status set
455       action = newaction,
456       inprogress = 'Y',
457       execid = currentexecid,
458       punting = 'FALSE';
459   end if;
460 
461   commit;
462 
463 end;
464 
465 procedure startaction(newaction IN varchar2) as
466 newaction_outarg varchar2(40) := newaction;
467 begin
468   startaction_outarg(newaction_outarg);
469 end;
470 
471 procedure endaction_outarg(action OUT varchar2) as
472 begin
473   if standalone_action then
474     update java$jvm$status set punting = 'FALSE';
475     standalone_action := false;
476     action := 'STANDALONE';
477   else
478     begin
479       select action into action from java$jvm$status where
480          punting = 'FALSE' and
481          execid = currentexecid;
482       delete from java$jvm$steps$done;
483       update java$jvm$status set inprogress = 'N', execid = null;
484       debug_output('endaction(' || action || ') DONE');
485     exception when no_data_found then
486       debug_output('endaction while PUNTING');
487       update java$jvm$status set punting = 'FALSE';
488       action := 'PUNT';
489     end;
490   end if;
491 
492   commit;
493 
494 end;
495 
496 procedure endaction as
497 outarg varchar2(40);
498 begin
499   endaction_outarg(outarg);
500 end;
501 
502 procedure endaction_asload as
503 outarg varchar2(40);
504 begin
505   endaction_outarg(outarg);
506   if (outarg != 'PUNT') then
507     update java$jvm$status set action = 'LOAD';
508     commit;
509   end if;
510 end;
511 
512 function startstep(newstep varchar2) return boolean as
513 punting varchar2(5);
514 execid varchar2(40);
515 oldstep varchar2(40);
516 try boolean := false;
517 begin
518   current_step := null;
519   begin
520     select execid, punting into execid, punting from java$jvm$status;
521     if punting = 'FALSE' then
522       debug_output('NOT YET PUNTING AT ' || newstep);
523       if standalone_action then
524         try := true;
525         update java$jvm$status set punting = 'TRUE';
526       elsif execid = currentexecid then
527         begin
528           select step into oldstep from java$jvm$steps$done where step = newstep;
529         exception when no_data_found then
530           try := true;
531           current_step := newstep;
532           update java$jvm$status set punting = 'TRUE';
533         end;
534       else
535         debug_output('startstep(' || newstep || ') PUNTED');
536         update java$jvm$status set punting = 'TRUE';
537       end if;
538     end if;
539   exception when no_data_found then
540     insert into java$jvm$status values('NONE','N',null,null,'TRUE');
541   end;
542 
543   commit;
544 
545   if try then
546     debug_output('TRIED ' || newstep);
547   else
548     debug_output('SKIPPED ' || newstep);
549   end if;
550 
551   return try;
552 
553 end;
554 
555 procedure endstep as
556 begin
557   if current_step is not null then
558     debug_output('COMPLETED ' || current_step);
559     insert into java$jvm$steps$done values(current_step);
560     current_step := null;
561   end if;
562   update java$jvm$status set punting = 'FALSE';
563   commit;
564 end;
565 
566 function currentexecid return varchar2 as
567 execid varchar2(40);
568 begin
569   select sid||'-'||serial# into execid from v$session
570          where sid = (select unique(sid) from v$mystat);
571   return execid;
572 end;
573 
574 procedure set_debug_output_on as begin do_debug_output := true; end;
575 procedure set_debug_output_off as begin do_debug_output := false; end;
576 
577 procedure debug_output(line varchar2) as
578 begin
579   if do_debug_output then dbms_output.put_line(line);end if;
580 end;
581 
582 procedure set_alt_tablespace_limit(l number) as
583 begin
584   alt_tablespace_limit := l;
585 end;
586 
587 -- drop sros during up/downgrade
588 procedure drop_sros as
589 begin
590   update obj$ set status=5 where obj#=(select obj# from obj$,javasnm$
591     where owner#=0 and type#=29 and short(+)=name and
592     nvl(longdbcs,name)='oracle/aurora/rdbms/Compiler');
593   commit;
594   declare
595     cursor C1 is select
596        u.name, o.name
597        from obj$ o,user$ u where o.type#=56 and u.user#=o.owner#;
598     ddl_statement varchar2(200);
599     uname         varchar2(30);
600     oname         varchar2(30);
601     iterations number;
602     previous_iterations number;
603     loop_count number;
604     my_err     number;
605   begin
606     previous_iterations := 10000000;
607     loop
608       -- To make sure we eventually stop, pick a max number of iterations
609       select count(*) into iterations from obj$ where type#=56;
610       exit when iterations=0 or iterations >= previous_iterations;
611       previous_iterations := iterations;
612       loop_count := 0;
613       open C1;
614       loop
615         begin
616           fetch C1 into uname,oname;
617           -- zsqi LRG 4937433 (Enquote_Name in place of manually added quotes)
618           ddl_statement := 'DROP JAVA DATA ' ||
619                            sys.dbms_assert.enquote_name(uname,FALSE) || '.' ||
620                            sys.dbms_assert.enquote_name(oname,FALSE);
621           exit when C1%NOTFOUND or loop_count > iterations;
622         exception when others then
623            my_err := sqlcode;
624            if my_err = -1555 then -- snapshot too old, re-execute fetch query
625              exit;
626            else
627              raise;
628            end if;
629         end;
630         initjvmaux.exec(ddl_statement);
631         loop_count := loop_count + 1;
632       end loop;
633       close C1;
634     end loop;
635   end;
636   commit;
637   drp('delete from java$policy$shared$table');
638   update obj$ set status=1 where obj#=(select obj# from obj$,javasnm$
639     where owner#=0 and type#=29 and short(+)=name and
640     nvl(longdbcs,name)='oracle/aurora/rdbms/Compiler');
641   commit;
642 end;
643 
644 procedure create_property_defs_table as
645 begin
646   require_sys;
647   exec('create table ' ||
648        'SYS.java$jvm$system$property$defs(user_name varchar2(128), ' ||
649                                          'property_name varchar2(4000), ' ||
650                                          'property_value varchar2(4000))');
651   exec('create or replace view java_system_property_settings as ' ||
652        'select * from sys.java$jvm$system$property$defs ' ||
653        'where user_name=SYS_CONTEXT(''userenv'',''SESSION_USER'') ' ||
654        'with check option');
655   exec('grant update,select,delete,insert on ' ||
656         'SYS.java_system_property_settings to public');
657   exec('create or replace public synonym java_system_property_settings for ' ||
658         'SYS.java_system_property_settings');
659   exec('begin dbms_java.reset_property_defs_table_flag; end;');
660 end;
661 
662 end;