Oracle FAQ | Your Portal to the Oracle Knowledge Grid |
![]() |
![]() |
Home -> Community -> Mailing Lists -> Oracle-L -> RE: Information on activity in Oracle's temporary segment under O
This message is in MIME format. Since your mail reader does not understand
this format, some or all of this message may not be legible.
------_=_NextPart_000_01BFC0A6.A83D9318
Content-Type: text/plain
Mark,
I rewrote the script n40758 a little. Major breakthru was the alteration of the constant size_int to 1. After that it worked like a charm. I hope it also works for you. Don't forget: the script should be run as user SYS !
Good hunting.
Remco
<<n40758_new.txt>>
> ----------
> From: mleith_at_bradmark.co.uk[SMTP:mleith_at_bradmark.co.uk]
> Sent: woensdag 17 mei 2000 11:44
> To: Multiple recipients of list ORACLE-L
> Subject: Information on activity in Oracle's temporary segment under
> Oracle 7
>
> <<File: N40758.TXT>><<File: N1069041.TXT>>
> Hi there,
>
> I am running 7.3.4.4, with a temporary tablespace (TEMP) of 500M, marked
> as
> type 'temporary'. I believe that this causes there to be a single
> temporary segment in the
> tablespace, shared by all users, which grows and shrinks according to
> demand.
>
> I occasionally see ORA-1652 errors in the alert log, such as 'ORA-1652:
> unable to extend temp segment by 63 in tablespace TEMP'. If I
> catch these quickly enough, I can see the state of the temporary segment
> using the V$SORT_SEGMENT view, as shown in the below example;
>
> TABLESPACE_NAME SEGMENT_FILE SEGMENT_BLOCK EXTENT_SIZE
> CURRENT_USERS TOTAL_EXTENTS TOTAL_BLOCKS USED_EXTENTS
> ------------------------------- ------------ ------------- -----------
> ------------- ------------- ------------ ------------
> USED_BLOCKS FREE_EXTENTS FREE_BLOCKS ADDED_EXTENTS EXTENT_HITS
> FREED_EXTENTS FREE_REQUESTS MAX_SIZE MAX_BLOCKS MAX_USED_SIZE
> ----------- ------------ ----------- ------------- -----------
> ------------- ------------- ---------- ---------- -------------
> MAX_USED_BLOCKS MAX_SORT_SIZE MAX_SORT_BLOCKS
> --------------- ------------- ---------------
> TEMP 3 62271 63
> 2 978 63569 16
> 1040 962 62529 978 3188
> 0 0 978 63569 978
> 63569 412 26780
>
> This example was taken while the system was quiet, but shows that there
> were
> two users using the segment, and were using 14 extents (978 - 962). What I
> cannot tell from this view is, a) who the two users are, and b) how many
> extents each is using.
>
> Occasionally, someone will report experiencing the problem, we will ask
> them
> to repeat the action, and invariably, it will work the second time around.
>
> What I suspect is happening when I see the ORA-1652 is that one user is
> running a large (and probably invalid) query which is taking up the lion's
> share of the temporary segment, and then some other 'innocent' user is
> running a genuine query which is requiring a sort, and failing because it
> is
> exhausting the remaining space in the segment.
>
> In the absence of any visibility of what is going on in there, I don't
> know
> who I should go and take a big stick to!
>
> Interestingly, there is a view provided in Oracle8 called V$SORT_USAGE
> which
> would do the job, but this doesn't help me on Oracle7.
>
> I also attach a couple of documents I received from Oracle when I raised
> this as a TAR. The first (n40758) is, I think, not exactly pertinent to my
> situation, and the second talks about 'dumping a systemstate'.
>
> <<n40758.txt>> <<n1069041.txt>> What I would like is a) visibility of
> who is doing what with regard to sorts
> in the temporary segment, and b) some means of monitoring this usage and
> raising an alert when some condition is met (e.g. user using more than nn
> extents, or something similar).
>
> Your mission, should you choose to accept it.......!
>
> TIA
>
> Mark
>
>
>
------_=_NextPart_000_01BFC0A6.A83D9318
Content-Type: text/plain;
name="n40758_new.txt"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="n40758_new.txt"
set serveroutput on size 1000000
create or replace procedure find_sort_segment_owners as=20
-- /* ** This procedure should ONLY be run as user SYS, because some=20 ** internal tables are being used. If the procedure still doesn't work, ** you can try to change the parameters in the section=20 ** PORT SPECIFIC VALUES below. */ -- ************ BEGIN PORT SPECIFIC VALUES ******************=20 sga_word_size number :=3D 4 ; /* 8 for Alpha o/w 4 = */ =20 byte_swapped boolean :=3D true ; /* True for Sequent = and DEC UNIX ow false */=20 size_int number :=3D 1 ;=20 debug boolean :=3D false;=20 -- ************ END PORT SPECIFIC VALUES *******************=20 size_kgglk number :=3D 2*sga_word_size ; =20 size_kssob number :=3D 4*sga_word_size; =20 offset_to_temp_table_dba number :=3D 0 ; =20 max_scan_count constant number :=3D 200; /* Max. no of so. to = scan */=20 -- type temp_seg_number_array is table of number index by = binary_integer;=20 -- temp_seg_file_no temp_seg_number_array;=20 temp_seg_block_no temp_seg_number_array;=20 temp_seg_owner temp_seg_number_array;=20 no_of_temp_segments number :=3D 0;=20 sga_base_address number;=20 sga_base_address_hex varchar2(50);=20 loop_cnt number;=20 temp_tmp_flag number;=20 perm_tmp_flag number;=20 temp_table_dba number;=20 temp_table_block_no number;=20 temp_table_file_no number;=20 temp_table_nblocks number;=20 temp_table_nextents number;=20 temp_table_tbs_num number;=20 sess_id number;=20 sess_addr varchar2(50);=20 sga_addr varchar2(50);=20 kssob_type_flag varchar2(50);=20 kssob_own_ptr varchar2(50);=20 kssob_nxt_link varchar2(50);=20 kssob_prv_link varchar2(50);=20 parent_head number;=20 gevonden boolean :=3D false; =20 total_used_extents number :=3D 0; total_used_mb number :=3D 0; l_s_username varchar2(30); l_s_osuser varchar2(30); l_n_serial# number; l_n_db_block_size number; l_n_max_extents number :=3D 0; l_n_max_blocks number :=3D 0; l_n_max_mb number :=3D 0; l_n_pct number; -- cursor c1 is select sid,rawtohex(saddr) from v$session;=20 -- function to_decimal (hex_str_in in varchar2) return number as=20 hex_str varchar2(50) :=3Dhex_str_in;=20 result number;=20 hex_char number;=20 begin=20 if ( sga_word_size =3D 8 )=20 then=20 hex_str :=3D lpad(upper(nvl(ltrim(hex_str,'0'),'0')),16,'0');=20 result :=3D 0;=20 for i in 1..16=20 loop=20 hex_char :=3D ascii(substr(hex_str,i,1));=20 if (hex_char - 64 > 0 )=20 then=20 hex_char :=3D hex_char - 64 + 9;=20 else=20 hex_char :=3D hex_char - 48 ;=20 end if;=20 result :=3D result + ( hex_char * power(2, ( 64 - (i*4) ) ) );=20 end loop;=20 return (trunc(result));=20 else=20 hex_str :=3D lpad(upper(nvl(ltrim(hex_str,'0'),'0')),8,'0');=20 result :=3D 0;=20 for i in 1..8 loop=20 hex_char :=3D ascii(substr(hex_str,i,1));=20 if (hex_char - 64 > 0 )=20 then=20 hex_char :=3D hex_char - 64 + 9;=20 else=20 hex_char :=3D hex_char - 48 ;=20 end if;=20 result :=3D result + ( hex_char * power(2, ( 32 - (i*4) ) ) );=20 end loop;=20 return (trunc(result));=20 end if;=20 end;=20 -- -- procedure get_base_address as=20 hex_address varchar2(40);=20 begin=20 select rawtohex(addr)=20 into hex_address=20 from x$ksmmem=20 where indx =3D 0;=20 sga_base_address :=3D to_decimal(hex_address);=20 sga_base_address_hex :=3D hex_address;=20 end;=20 -- function get_sga_index(sga_address in varchar2) return number as=20 begin=20 return = trunc((to_decimal(sga_address)-sga_base_address)/sga_word_size );=20 end;=20 -- function get_sga_index_rem (sga_address in varchar2) return number as=20 begin=20 return = (mod((to_decimal(sga_address)-sga_base_address),sga_word_size));=20 end;=20 -- function get_sga_value (hex_address in varchar2,adjustment in number = default 0)=20 return varchar2 as=20 sga_index number;=20 local_value varchar2(50);=20 begin=20 sga_index :=3D get_sga_index(hex_address) + adjustment;=20 -- if (debug)=20 -- then=20 -- dbms_output.put_line('. get_sga_value '||hex_address||' '||=20 -- to_char(adjustment));=20 -- dbms_output.put_line('. get_sga_value get_sga_index = '||sga_index);=20 -- end if;=20 select rawtohex(ksmmmval) into local_value from x$ksmmem=20 where indx =3D sga_index;=20 -- dbms_output.put_line('. local_value '||local_value);=20 return local_value;=20 end;=20 -- function get_temp_table_state_object(state_name in varchar2) =20 return number as=20 -- local_state_object number;=20 hex_str varchar2(50);=20 state_object_address varchar2(50);=20 state_object_offset number;=20 sga_structure boolean;=20 sga_col_count number;=20 c1 integer;=20 rc integer;=20 sql_stmt varchar2(255);=20 begin=20 select count(*)=20 into sga_col_count from x$kqfta a, x$kqfco b=20 where a.kqftanam =3D 'X$KSMFSV' and a.indx =3D b.KQFCOTAB=20 and b.KQFCONAM =3D 'KSMFSADR';=20 if ( sga_col_count =3D 1 )=20 then=20 sga_structure :=3D false;=20 else=20 sga_structure :=3D true;=20 end if;=20 if ( sga_structure ) then=20 c1 :=3D dbms_sql.open_cursor;=20 sql_stmt :=3D 'select KSMFSOFF from x$ksmfsv=20 where KSMFSNAM like '''||state_name||'''';=20 dbms_sql.parse(c1,sql_stmt,dbms_sql.native);=20 dbms_sql.define_column(c1,1,state_object_offset);=20 rc :=3D dbms_sql.execute(c1);=20 rc :=3D dbms_sql.fetch_rows(c1);=20 dbms_sql.column_value(c1,1,state_object_offset);=20 dbms_sql.close_cursor(c1);=20 local_state_object:=3Dto_decimal(=20 get_sga_value(sga_base_address_hex,=20 = state_object_offset/sga_word_size));=20 else=20 c1 :=3D dbms_sql.open_cursor;=20 sql_stmt :=3D 'select rawtohex(KSMFSADR) from x$ksmfsv=20 where KSMFSNAM like '''||state_name||'''' ;=20 dbms_sql.parse(c1,sql_stmt,dbms_sql.native);=20 dbms_sql.define_column(c1,1,state_object_address,50);=20 rc :=3D dbms_sql.execute(c1);=20 rc :=3D dbms_sql.fetch_rows(c1);=20 dbms_sql.column_value(c1,1,state_object_address);=20 dbms_sql.close_cursor(c1);=20 if (debug)=20 then=20 dbms_output.put_line('state_object_address '||=20 state_object_address );=20 end if; if ( sga_word_size =3D 8 )=20 then =20 hex_str :=3D get_sga_value(state_object_address);=20 if (debug)=20 then=20 dbms_output.put_line('. temp flag value at address = '||hex_str);=20 end if; hex_str :=3D lpad(upper(nvl(ltrim(hex_str,'0'),'0')),16,'0');=20 if ( get_sga_index_rem(state_object_address) !=3D 0 )=20 then =20 hex_str :=3D substr(hex_str,1,8);=20 else =20 hex_str :=3D substr(hex_str,9,16);=20 end if;=20 dbms_output.put_line('. substr temp flag value at address = '||hex_str);=20 local_state_object :=3D to_decimal(hex_str);=20 else=20 = local_state_object:=3Dto_decimal(get_sga_value(state_object_address));=20 end if;=20 end if;=20 if (debug)=20 then=20 dbms_output.put_line('. temp_table_state_object = '||local_state_object);=20 end if; return(local_state_object);=20 end;=20 -- function state_object_initialised(flags in varchar2) return boolean=20 as=20 begin=20 if ( sga_word_size =3D 8 and byte_swapped )=20 then=20 if ( to_decimal(substr(flags,14,1)) =3D 1 )=20 then=20 return true;=20 else=20 return false;=20 end if;=20 else=20 if ( byte_swapped )=20 then=20 if ( to_decimal(substr(flags,6,1)) =3D 1 )=20 then=20 return true;=20 else=20 return false;=20 end if;=20 else=20 if ( to_decimal(substr(flags,8,1)) =3D 1 )=20 then=20 return true;=20 else=20 return false;=20 end if;=20 end if;=20 end if;=20 end;=20 -- function match_flag(state_flag in number,flags in out varchar2) return = boolean=20 is=20 begin=20 if ( byte_swapped )=20 then=20 if ( sga_word_size =3D 8 )=20 then=20 flags:=3Dlpad(upper(nvl(ltrim(flags,'0'),'0')),16,'0');=20 if (debug)=20 then=20 dbms_output.put_line('. '||=20 to_decimal(substr(flags,15,2))||=20 '?=3D'||state_flag);=20 end if;=20 if ( to_decimal(substr(flags,15,2)) =3D state_flag )=20 then=20 return true;=20 else=20 return false;=20 end if;=20 else=20 if ( to_decimal(substr(flags,7,2)) =3D state_flag )=20 then=20 return true;=20 else=20 return false;=20 end if;=20 end if;=20 else=20 if ( to_decimal(substr(flags,1,2)) =3D state_flag )=20 then=20 return true;=20 else=20 return false;=20 end if;=20 end if;=20 end;=20 -- procedure build_active_temp_segments as=20 cursor c1 is select file#,block# from seg$ where type=3D3;=20 local_file_no number;=20 local_block_no number;=20 begin=20 open c1;=20 no_of_temp_segments :=3D 0 ;=20 loop=20 fetch c1 into local_file_no,local_block_no;=20 exit when c1%notfound;=20 no_of_temp_segments :=3D no_of_temp_segments + 1;=20 temp_seg_file_no(no_of_temp_segments) :=3D local_file_no ;=20 temp_seg_block_no(no_of_temp_segments) :=3D local_block_no;=20 temp_seg_owner(no_of_temp_segments) :=3D (-1);=20 end loop;=20 close c1;=20 end;=20 -- function valid_temp_seg_dba (t_file_no number, t_block_no number,=20 sess_id number ) return boolean=20 is=20 begin=20 for i in 1..no_of_temp_segments=20 loop=20 if ( temp_seg_file_no(i) =3D t_file_no =20 and temp_seg_block_no(i)=3D t_block_no=20 )=20 then=20 temp_seg_owner(i) :=3D sess_id ;=20 return true;=20 end if;=20 end loop;=20 return false;=20 end;=20 -- -- begin=20 select value=20 into l_n_db_block_size=20 from v$parameter=20 where name=3D'db_block_size'; select sum(bytes)/(1024*1024)=20 into l_n_max_mb from dba_data_files df,dba_tablespaces t where df.tablespace_name=3Dt.tablespace_name and t.contents=3D'TEMPORARY'; select floor((l_n_max_mb*(1024*1024) - initial_extent)/next_extent)=20 into l_n_max_extents from dba_tablespaces=20 where contents=3D'TEMPORARY'; get_base_address;=20 if (debug)=20 then=20 dbms_output.put_line('SGA base '||sga_base_address);=20 end if; temp_tmp_flag:=3Dget_temp_table_state_object('%ktstud%');=20 perm_tmp_flag:=3Dget_temp_table_state_object('%ktatlt%');=20 if (debug)=20 then=20 dbms_output.put_line('temp tmp state '||temp_tmp_flag);=20 dbms_output.put_line('perm tmp state '||perm_tmp_flag);=20 end if; build_active_temp_segments;=20 open c1;=20 loop=20 fetch c1 into sess_id,sess_addr ;=20 exit when c1%notfound;=20 kssob_type_flag :=3D get_sga_value(sess_addr);=20 if (debug)=20 then=20 dbms_output.put_line('. kssob_type_flag '||kssob_type_flag);=20 end if;=20 parent_head :=3D to_decimal(sess_addr) + size_kssob; =20 kssob_nxt_link :=3D = get_sga_value(sess_addr,size_kssob/sga_word_size);=20 if (debug)=20 then dbms_output.put_line('. kssob_nxt_link '||kssob_nxt_link);=20 end if;=20 sga_addr :=3D parent_head ;=20 loop_cnt :=3D 0;=20 if ( state_object_initialised(kssob_type_flag) )=20 then=20 loop=20 exit when to_decimal(kssob_nxt_link) =3D parent_head;=20 exit when loop_cnt > max_scan_count ;=20 loop_cnt :=3D loop_cnt + 1;=20 sga_addr :=3D kssob_nxt_link;=20 kssob_type_flag :=3D get_sga_value(sga_addr,=20 - (size_kgglk/sga_word_size) );=20 kssob_nxt_link :=3D get_sga_value(sga_addr,0);=20 if (debug)=20 then=20 dbms_output.put_line('. type flag '||kssob_type_flag);=20 end if;=20 if ( state_object_initialised(kssob_type_flag)) then=20 if (match_flag(perm_tmp_flag,kssob_type_flag))=20 then=20 temp_table_dba :=3D to_decimal( get_sga_value(sga_addr,=20 ( size_kgglk ) / sga_word_size =20 + offset_to_temp_table_dba ));=20 temp_table_file_no:=3D = dbms_utility.data_block_address_file(temp_table_dba);=20 = temp_table_block_no:=3Ddbms_utility.data_block_address_block(temp_table_= dba);=20 if = (valid_temp_seg_dba(temp_table_file_no,temp_table_block_no,=20 sess_id) )=20 then=20 dbms_output.put_line( 'Session = '||rpad(to_char(sess_id),6,' ') ||' DBA = '||rpad(temp_table_dba,10,' ') ||' File No = '||rpad(temp_table_file_no,6,' ') ||' Block No ' ||rpad(temp_table_block_no,10,' = '));=20 end if;=20 end if;=20 if (match_flag(temp_tmp_flag,kssob_type_flag) )=20 then=20 temp_table_tbs_num:=3Dto_decimal( get_sga_value(sga_addr,=20 ( size_kgglk ) / sga_word_size=20 + (size_int) ));=20 temp_table_nextents:=3Dto_decimal( get_sga_value(sga_addr, = ( size_kgglk ) / sga_word_size=20 + (3*size_int) ));=20 temp_table_nblocks:=3Dto_decimal( get_sga_value(sga_addr,=20 ( size_kgglk ) / sga_word_size=20 + (4*size_int) ));=20 if not gevonden then dbms_output.put_line(rpad('=3D',100,'=3D')); dbms_output.put_line( rpad('SID',7,' ') ||rpad('Serial#',8,' ') ||rpad('Username ',31,' ') ||rpad('Osuser ',31,' ') ||rpad('Extents',9,' ') ||rpad('Mb',9,' ') ||rpad('%',5,' ') ); dbms_output.put_line( rpad('=3D=3D=3D=3D=3D=3D',7,' ') = ||rpad('=3D=3D=3D=3D=3D=3D=3D',8,' ') = ||rpad('=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D',31,' ') = ||rpad('=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D',31,' ') = ||rpad('=3D=3D=3D=3D=3D=3D=3D=3D',9,' ') = ||rpad('=3D=3D=3D=3D=3D=3D=3D=3D',9,' ') ||rpad('=3D=3D=3D=3D=3D',6,' ') ); gevonden :=3D true; end if; select serial#,username,osuser=20 into l_n_serial#,l_s_username,l_s_osuser from v$session=20 where sid=3Dsess_id; l_n_pct :=3D = round((((temp_table_nblocks*l_n_db_block_size)/(1024*1024))/l_n_max_mb)*= 100,1); dbms_output.put_line( rpad(to_char(sess_id),7,' ') ||rpad(to_char(l_n_serial#),8,' ') ||rpad(l_s_username,31,' ') ||rpad(NVL(l_s_osuser,'<Niet = gevuld>'),31,' ') ||rpad(temp_table_nextents,9,' ') = ||rpad(round(temp_table_nblocks*l_n_db_block_size/(1024*1024)),9,' ') ||rpad(l_n_pct,6,' ') );=20 total_used_extents :=3D total_used_extents + = temp_table_nextents; total_used_mb :=3D total_used_mb + = (temp_table_nblocks*l_n_db_block_size/(1024*1024)); end if;=20 end if;=20 end loop;=20 end if;=20 end loop;=20 close c1;=20 if not gevonden then dbms_output.put_line(rpad('=3D',100,'=3D')); dbms_output.put_line( rpad('SID',7,' ') ||rpad('Serial#',8,' ') ||rpad('Username ',31,' ') ||rpad('Osuser ',31,' ') ||rpad('Extents',9,' ') ||rpad('Mb',9,' ') ||rpad('%',6,' ') ); end if; dbms_output.put_line( rpad('.',77,' ') ||rpad('=3D=3D=3D=3D=3D=3D=3D=3D',9,' ') ||rpad('=3D=3D=3D=3D=3D=3D=3D=3D',9,' ') ||rpad('=3D=3D=3D=3D=3D',6,' ') ); l_n_pct :=3D round((total_used_mb/l_n_max_mb)*100,1); dbms_output.put_line( rpad('Total in use : ',77,' ') ||rpad(total_used_extents,9,' ') ||rpad(round(total_used_mb),9,' ') ||rpad(l_n_pct,6,' ') ); dbms_output.put_line( rpad('.',77,' ') ||rpad('=3D=3D=3D=3D=3D=3D=3D=3D',9,' ') ||rpad('=3D=3D=3D=3D=3D=3D=3D=3D',9,' ') ||rpad('=3D=3D=3D=3D=3D',6,' ') ); dbms_output.put_line( rpad('Maximum : ',77,' ') ||rpad(l_n_max_extents,9,' ')Received on Thu May 18 2000 - 04:04:51 CDT
![]() |
![]() |