We have a problem on one of the data warehouse databases at work. There is an overnight resource profile in place that is designed to stop any users from running long-running queries while other activities are happening. The main limit is on logical_reads_per_call, for example (and this is just a simple example I’ve been playing with at home)
SQL> alter profile default limit logical_reads_per_call 10000;
Profile altered.
Now I’ll connect to the testuser account and look at the table I’m going to test this with – DUDE (why it’s called that should become clearer when I blog about DUDE soon)
SQL> select table_name, blocks from user_tables where table_name = 'DUDE';
TABLE_NAME BLOCKS
------------------------------ ----------
DUDE 25431
So you can see that the table DUDE consists of 25431 blocks. Therefore, if I try to perform a full table scan of it, I’ll hit the limit.
SQL> set autotrace trace statistics
SQL> select count(*) from dude;
select count(*) from dude
*
ERROR at line 1:
ORA-02395: exceeded call limit on IO usage
But, if I try the same query using parallel execution, it doesn’t exceed the limit.
SQL> select /*+ parallel(dude, 2) */ count(*) from dude;
Statistics
----------------------------------------------------------
27 recursive calls
3 db block gets
25537 consistent gets
25403 physical reads
672 redo size
414 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
1 rows processed
And even if I reduce the limit to 500 :-
SQL> connect / as sysdba
Connected.
SQL> alter profile default limit logical_reads_per_call 500;
Profile altered.
SQL> connect testuser/testuser
Connected.
SQL> set autotrace trace statistics
SQL> select /*+ parallel(dude, 2) */ count(*) from dude;
Statistics
----------------------------------------------------------
6 recursive calls
0 db block gets
25536 consistent gets
25403 physical reads
0 redo size
414 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
1 rows processed
There are only two slaves in use, each of which is clearly reading more than 500 blocks, but I assume that because they’re background processes, their statistics aren’t included.
I’m still digging around with this, but I’m interested in hearing anyone else’s experiences because this is causing us a problem because just when we want to limit system load, some of the most resource-hungry SQL statements are being executed and not limited, because they’re using PX. I can think of several solutions to this, but it would appear that the existing approach isn’t going to work.
Additional info
I missed this off the original post. At work I was using x$ksuru to try to work out what was going on. These are the results I’m getting locally, which show that the original slaves are exceeding the limit that’s still in place. (Note that this is on a bigger table, though, to give me more chance to monitor the changes)
select * from x$ksuru
where addr IN (select saddr from v$px_session where qcsid = &parent)
and ksurind = 4
SQL> /
Enter value for parent: 1073
old 2: where addr IN (select saddr from v$px_session where qcsid = &parent)
new 2: where addr IN (select saddr from v$px_session where qcsid = 1073)
ADDR INDX INST_ID KSUSEIDL KSURIND KSURUSE
-------- ---------- ---------- ---------- ---------- ----------
7D0532C4 1069 1 1 4 50090
7D057D94 1073 1 1 4 26
7D05DB18 1078 1 1 4 49302
SQL> /
Enter value for parent: 1073
old 2: where addr IN (select saddr from v$px_session where qcsid = &parent)
new 2: where addr IN (select saddr from v$px_session where qcsid = 1073)
ADDR INDX INST_ID KSUSEIDL KSURIND KSURUSE
-------- ---------- ---------- ---------- ---------- ----------
7D0532C4 1069 1 1 4 55499
7D057D94 1073 1 1 4 26
7D05DB18 1078 1 1 4 54508
Preventing long running quiries you might want prevent parallel queries as well.
Perhaps, selective ALTER SESSION DISABLE PARALLEL QUERY or using more sophisticated Resource Manager.
Agreed, that’s what I meant by this
” I can think of several solutions to this, but it would appear that the existing approach isn’t going to work.”
Resource Manager is the most likely solution at the moment, but the developers were obviously assuming that resource profiles would work and I can’t say I’d ever tried the combination myself.
I woke up thinking about this blog. Bad sign 😉 I realised that it might seem that somehow I’m stunned by this behaviour when, in fact, I expected it *once I was asked about it*. I’d just never really had cause to think about it so thought I’d test it.
The idea was that I might help someone from hitting the same mistake by showing the behaviour and also that someone might flesh out the detail. e.g. That x$ksuru query is a bit cobbled together and I’m not 100% sure I’ve got it right.
I hoped to hear some suggested alternatives too, so thanks Alex.
I should also have said this is on 10gR2. I’m terrible for forgetting to mention which version something is on if I don’t think it’s relevant. That’s really going to catch me out one day!
Doug,
I think the reason for the contradictory aspect of this behaviour is that someone has fiddled with the code for “session logical reads” in 10g, and not done so properly.
You will probably find that the statistic “session logical reads” (in your test) matches “consistent gets”; and that “consistent gets” is the sum of “consistent gets from cache” and “consistent gets direct”.
The PX slaves are doing direct path reads – which count under the ‘consistent gets direct’ in 10g. But the block gets were NOT added to “session logical reads” prior to 10g.
BUT – the direct gets are NOT calls to functions listed in x$kcbsw, and it is probably only code in that set of functions that updates the counters used by the profile code to check the limit.
Regards
Jonathan Lewis
Thanks Jonathan.
The work problem was on 10.2 and my test system at home is 10.2
One of the guys at work ran his tests on 9.2 and we noticed the difference in behaviour. I spent last night downloading 9.2 (I should really have multiple versions anyway) and will be putting up a new blog showing the differences in behaviour some time this weekend.
Thanks for your suggestions because I can include those details in the blog.
btw, I had a feeling you might put in an appearance on this blog and I had a feeling it might be at the weekend 😉
Cheers,
Doug