That's a good question.
![]()
And the answer is simple: Yes, but NO!
Well, ok; that's not very helpful. But whenever is anything simple in modern IT?
So I'll show why Yes, it's possible:
first as SYS create a dummy user without special permissions and a function to drop the shared pool:
Unfortunately I can not use the gv$ function as user berx directly.
So a view does the trick:
and now it's so simple to flush on all instances:
or
But at the same time the answer is NO, as I'm using the gv$ function - and this is not documented, so it's not wise to use it.
If it was not about an Active DataGuard, I'd use a scheduler job to run the flush shared_pool on all instances, but as the ADG is read only, I can't use it.
If you have another idea, how to do this (only with oracle means, no cronjob or similar), please let me know!

And the answer is simple: Yes, but NO!
Well, ok; that's not very helpful. But whenever is anything simple in modern IT?
So I'll show why Yes, it's possible:
first as SYS create a dummy user without special permissions and a function to drop the shared pool:
create user berx identified by xxx;
grant connect to berx;
grant select on v_$instance to berx;
create or replace function sys.flush_shared_pool_bx return varchar2
as
begin
execute immediate 'alter system flush shared_pool';
return 'Flush_Shared_Pool executed on ' || sysdate || ' by ' || sys_context('USERENV', 'SESSION_USER');
end;
/
grant execute on sys.flush_shared_pool_bx to public;
SELECT * FROM TABLE(gv$(CURSOR(
SELECT INSTANCE_NUMBER, sys.flush_shared_pool_bx flush_result
FROM v$instance)));
Unfortunately I can not use the gv$ function as user berx directly.
So a view does the trick:
create view v_flush_shared_pool_bx
as
SELECT * FROM TABLE(gv$(CURSOR(
SELECT INSTANCE_NUMBER, sys.flush_shared_pool_bx flush_result
FROM v$instance)));
grant select on v_flush_shared_pool_bx to public;
create or replace
function f_gv_flush
return DBMS_DEBUG_VC2COLL
PIPELINED
IS
res varchar2(120);
cursor c1 is
SELECT INSTANCE_NUMBER || ' - ' || FLUSH_RESULT as in_result
FROM TABLE(gv$(CURSOR(
SELECT INSTANCE_NUMBER, sys.flush_shared_pool_bx flush_result
FROM v$instance)));
begin
FOR res_row in c1
LOOP
pipe row (to_char(res_row.in_result)) ;
END LOOP;
return;
end;
/
and now it's so simple to flush on all instances:
connect berx/
select * from sys.v_flush_shared_pool_bx;
INSTANCE_NUMBER FLUSH_RESULT
--------------- --------------------------------------------------
1 Flush_Shared_Pool executed on 10-APR-17 by BERX
3 Flush_Shared_Pool executed on 10-APR-17 by BERX
2 Flush_Shared_Pool executed on 10-APR-17 by BERX
or
select * from table(sys.f_gv_flush);So obviously the answer if I an flush shared pool in all RAC instances - even in Active DataGuard is: Yes.
COLUMN_VALUE
-----------------------------------------------------
1 - Flush_Shared_Pool executed on 10-APR-17 by BERX
2 - Flush_Shared_Pool executed on 10-APR-17 by BERX
3 - Flush_Shared_Pool executed on 10-APR-17 by BERX
But at the same time the answer is NO, as I'm using the gv$ function - and this is not documented, so it's not wise to use it.
If it was not about an Active DataGuard, I'd use a scheduler job to run the flush shared_pool on all instances, but as the ADG is read only, I can't use it.
If you have another idea, how to do this (only with oracle means, no cronjob or similar), please let me know!