Skip to Main Content
  • Questions
  • Coalsce not necessary in Locally Managed Tablespaces

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, John.

Asked: December 18, 2012 - 6:12 pm UTC

Last updated: January 22, 2013 - 2:44 am UTC

Version: 11.2

Viewed 1000+ times

You Asked

Tom,

I heard that coalescing of indexes is not necessary in locally managed tablespaces. Is this true?

If you answered yes, then:
- is rebuilding of indexes not necessary in locally manged tablespaces?
- is reorg'ing of tables not necessary in locally managed tablespaces?
- What about LMT over dictionary managed tablespaces makes it unnecessary to perform operations that you answered 'yes' to?

Thank you


and Tom said...

coalescing with respect to a tablespace means to join together contiguous free extents into a single extent.

locally managed tablespaces (LMT) do this automagically, coalescing them will never accomplish anything.


it has nothing to do with rebuilding indexes.
it has nothing to do with reorging tables


coalescing was about making multiple free extends in the SYS.FET$ table into a single extent when possible. This is an activity that SMON performs on a schedule but you could manually do with an alter tablespace command. But again, it does nothing for an LMT.

Rating

  (7 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Index Rebuild and Table Reorg not required for LMT

A reader, December 22, 2012 - 3:26 am UTC

Sir,

My Question is Index Rebuild and Table Reorg not required for LMT?

Regards,
Bathula
Oracle DBA
Tom Kyte
January 04, 2013 - 10:22 am UTC

LMT versus DMT doesn't have any impact on the need to reorganize a structure.


So the fact that sometimes in the past with a DMT you had to rebuild a table or index means you still have to sometimes rebuild an index or table in an LMT since the fact that a segment is in either or doesn't really have a meaningful impact on whether it needs to be rebuilt or not.



If you insert 1,000,000 rows into a table and over time delete all 1,000,000 - you'll have a big empty table. Regardless of whether it is in DMT or LMT. You might want to re-organize that table to reclaim space, lower the high water mark, whatever.

If you have what I call a sweeper index (search this site for that term), it doesn't matter if it is in a DMT or LMT - you might consider a reorganization of that index over time to reclaim the "brown" left hand side of the index.

and so on.

How to run pl/sql procedure parallely for multiple update

saurabh mittal, January 01, 2013 - 9:14 pm UTC

Hi Experts,

I have one pl/sql block and having cursor for loop whichis having 25 tables which is getting updated parallely.Please help me by givng best solution for doing this activity.
Tom Kyte
January 04, 2013 - 1:39 pm UTC

insufficient data to comment and has nothing to do with the original question at all.

Data Processing Skip

Anand, January 11, 2013 - 12:32 am UTC

Hi Tom,

We have a table in production which is in LMT. Client informed us that some of the processing skip during batch process.And after we check we found that's true.if i drop and re-create the table and run the stub it works perfectly.

Then we asked DBA to check this issue. DBA said table is not corrupt.

The problem is it start again after few days of drop and re-create.Even we didn't change the code at all.And its running the same code from last 3 years.

Please suggest.
Tom Kyte
January 14, 2013 - 1:28 pm UTC

you have a bug in your code.

hopefully, you have instrumented your code and can just turn on some tracing to help diagnose the issue.


I'll make an educated guess based on seeing it happen for over 25 years now. Someone has an error handler. The error handler is getting an error. The error handler is IGNORING the error, the person that called this bit of code naturally assumes that the code ran and worked (it didn't, it got an error but is hiding it).


In other words you have a bit a code somewhere that looks like this:

begin
   ... do stuff  ...
exception
when others
then
    print out an error message;
end;



in whatever language you are coding in. It "ignores" the error and turns it into "not an error" and the rest of the code continues on as if life were grand.



I am 99.99999999999999999999% sure this is issue - it is up to you to find it in your code.


If you use plsql - you can find this easily by enabling warnings and recompiling your code - we'll tell you what plsql units you have that do this!!! (in 11g and above)

Anand, January 18, 2013 - 12:14 am UTC

Hi Tom,

Okay let me share the code with you.The code will distribute the no of account equally.But it updates only few records not all(this is the issue).

Below is the code.I am sharing only the logic :

var_pi_cod_stream := 10
l_sream_list is class type.

cod_stream - This will update accordingly and it is null currntly.My expectaion is after execute all account should have some stream but not null.

BEGIN
FOR i IN 1 .. var_pi_cod_stream LOOP
BEGIN
SELECT cod_acct_no BULK COLLECT
INTO l_stream_list
FROM (SELECT cod_acct_no,
NTILE(var_pi_cod_stream) OVER(ORDER BY cod_xfer_brn) stream
FROM test )
GROUP BY cod_acct_no
HAVING MIN(stream) = i;
FORALL j IN 1 .. l_stream_list.LAST
UPDATE test
SET cod_stream = i
WHERE cod_acct_no = l_stream_list(j)
END;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
ora_raiserror(SQLCODE,
' Error in updation of test table',
154);
var_l_return := -1;
END;
END;
Tom Kyte
January 18, 2013 - 10:22 am UTC


EXCEPTION
WHEN OTHERS THEN
ora_raiserror(SQLCODE,
' Error in updation of test table',
154);
var_l_return := -1;
END;



right there. what is "ora_raiserror" (besides spelled strangely ;) ) - does it invoke RAISE or RAISE_APPLICATION_ERROR. If not, there is your bug.

Just add "RAISE" right before "end;"

why is this not just a single sql statement??? what is the point in querying TEST var_pi_cod_tream times and then updating test that many times. Why isn't this just a single *merge* statement - or even better - an insert append into a new table - dropping the old table and renaming the new table (if you are updating every row in a table, you are doing something wrong)


Anand, January 19, 2013 - 2:46 am UTC

Hi Tom,

ora_raiserr is procedure which calling raise_application_error.


This logic used in so many place in our application (to divide the account across the stream).

can you tell me how can we do in single merge statment ?

Below is the create and insert script and i want to update the cod_stream_id from 1 to 10 :

drop table test
/
create table test (cod_acct_no CHAR(16),cod_stream_id number(5))
/
insert into test values ('a',0)
/
insert into test values ('b',0)
/
insert into test values ('c',0)
/
insert into test values ('d',0)
/
insert into test values ('e',0)
/
insert into test values ('f',0)
/
insert into test values ('g',0)
/
insert into test values ('h',0)
/
insert into test values ('i',0)
/
insert into test values ('j',0)
/
insert into test values ('k',0)


I am curious to know why if i drop and re-create the table it work perfectly(with the same logic).If there is some bug on code it must be simulate every time.rite ?

Tom Kyte
January 21, 2013 - 3:32 am UTC

If there is some bug on code it must be simulate
every time.rite ?


of course not, there are errors you can get on one execution that you do not on another - for example, ORA-1555 snapshot too old, you might get that error once out of ever 100 runs (or more or less)

answer me this - if hour ora_raise thing raises an error, why do you have this line of code:


EXCEPTION
WHEN OTHERS THEN
ora_raiserror(SQLCODE,
' Error in updation of test table',
154);
var_l_return := -1;
END;


that bit of code could never be reached if what you say is true. so tell me, why does it exist?

sure looks like a return code to me. are you sure of what you say??????

I'm very suspicious of your code - you are doing some funky error handling. You have code that either does return code processing (bad idea in 2013) OR you are in fact raising the error here (which means you have suspicious dead code, whoever wrote this didn't understand how things work)...



to merge, just generate the set of cod_acct_no/streams you want and merge that into the original table:

merge into test
using (
SELECT cod_acct_no,
       NTILE(var_pi_cod_stream) OVER(ORDER BY cod_xfer_brn) stream
  FROM test                      )
 GROUP BY cod_acct_no ) x
on (test.cod_acct_no = x.cod_acct_no )
when matched then update set cod_stream = x.stream;


Anand, January 22, 2013 - 12:48 am UTC

Hi Tom,

Yeah its true that var_l_return := -1 will never occur(doesnt make any sense as well ).And its written long back.

Let me share the code with you :


CREATE OR REPLACE PROCEDURE ora_raiserror(errnum number,
errmsg varchar2,
lineno number) AS
msg varchar2(1000);
errno number;
msg_trace VARCHAR2(1000);
BEGIN
msg_trace := DBMS_UTILITY.format_error_backtrace;
IF (INSTR(msg_trace, 'ORA_RAISERROR')) != 0 THEN
msg_trace := substring(msg_trace,
INSTR(msg_trace, CHR(10)),
datalength(msg_trace) - INSTR(msg_trace, CHR(10)));
END IF;
msg := SQLERRM(errnum) || msg_trace;
if (datalength(msg) > 300) THEN
BEGIN
msg := substring(msg, 1, 300);
END;
ELSE
BEGIN
msg := ltrim(rtrim(msg)) || ' ' || ltrim(rtrim(errmsg));
END;
END IF;
errno := errnum;
raise_application_error(-20000, msg || ' Line: ' || lineno, FALSE);
END;



So you still think there is bug in my code ?
Tom Kyte
January 22, 2013 - 2:44 am UTC

at some point, there is, at some point in the code - maybe further up the call stack, someone is catching and ignoring an error - I have no doubt about it.

If I had a nickle for every time someone said "sometimes my code only runs halfway - Oracle doesn't run all of my code every time" - I'd be very very rich.

and every time - every. single. time - the error is in the developed code and is due to a when others not followed by a raise/raise application error.


it is funny - if you just let the error propagate in the first place - if this function never existed - you would get a full error stack - with all line numbers - with a ton more information. the *only thing* this function does is remove information that could be used to debug.

and it has funny things in it like "errno := errnum;". what does that do for example?



I would change this procedure to be an autonomous transaction.

it would then log into a database table using an insert the full error stack, the timestamp and the entire call stack. That will go a long way towards you being able to figure out what the error is.

and think about using merge and remove all procedural code.

less code = less bugs

Anand, January 24, 2013 - 9:18 pm UTC

Hi Tom,

Thanks a lot for you help.i will try to change the code as you suggested.