在Oracle數據庫中,管理tablespaces通常很難實現從SQL查詢得到數據的可視化。一種實現tablespaces可視化且更加容易管理的方法是建立類似于碎片重組功能(defragmentation utilities)的分段使用映射(block usage maps)。
不需要任何圖表或者圖形功能,你可以使用簡單的由Oracelmodplsql包産生的HTML,而modplsql包可在安裝Oracle8i和9i時安裝。
這其中也包含著風險,因爲這一程序必須由一個DBA帳號來運行,所以DBA帳號必須將使用權限賦予每一個操作計劃,而操作計劃必須包含在wdbsvr.app文件中。爲了保護這一文件,你必須確保這一文件只能被Oracle用戶和DBA組查閱。如果你願意把這一程序編寫成一個JSP頁或者servlet,你也應該非常小心,以防止外部能夠使用DBA帳號。
DBA視不能在一個PL/SQL查詢,所以你必須將PL/SQL安裝爲SYS,然後將使用權限分配給允許運行PL/SQL的帳號:
connect sys/<password
@blkmap.sql
grant execute on blkmap to system;
connect system/<password
create synonym blkmap for sys.blkmap;
在這個例子中,我們建立一個名爲blkmap包,這一blkmap包具有兩個入口點。其中一個是顯示tablespaces列表的一個菜單,另一個是實際使用的tablespace分段映射:
create or replace package blkma
as
procedure ts_menu;
procedure ts_map(p_name varchar2);
end blkmap;
/
show errors;
Tablespace菜單的代碼可以是一個與分段映射(block map)頁關聯的tablespaces列表:
procedure ts_menu
is
begin
htp.p('<html');
htp.p('<body bgcolor="white"');
htp.p('<h2Tablespaces</h2');
htp.p('<ul');
for ts in (select tablespace_name from dba_tablespaces) loop
htp.p('<li<a href="blkmap.ts_map?p_id='||ts.tablespace_name||'"'
||ts.tablespace_name||'</a</li');
end loop;
htp.p('</ul');
htp.p('</body');
htp.p('</html');
end ts_menu;
對于tablespace映射,可以生成一個tablespace名稱,並請求包含tablespace的每一文件的分段映射。
procedure ts_map(p_name varchar2)
is
begin
page_open;
-- open the page
htp.p('Tablespace: '||p_name);
htp.p('<hr /');
for file in
(
select file_id
from dba_data_files
where tablespace_name = p_name
order by file_id
)
loop
filemap(file.file_id);
-- generate a block map for the file
htp.p('<hr /');
end loop;
info_form;
-- generate a form for segment info
legend;
-- generate a legend for color mappings
page_close;
-- close the page
end ts_map;
對于實際使用的分段映射,我們通常需要顯示一個「block」並用顔色表示。使用<table標簽比較複雜。一個更好的方法是生成字符次序,即一段時間之後是間隔,這一間隔允許在任何位置給文本以顔色化。
爲了使得分段映射更加有用,我們想列出鼠標位置的block信息,並且突出組成這一片段的block,我們可以使用<a標簽。首先,生成一個指定a和a:hover的類型,然後建立每一Oracle數據庫段的類型:
<style type="text/css"
a
{
text-decoration: none;
font-family: monospace;
font-size: 6pt;
}
a:hover {background-color: yellow}
a.free {background-color: white}
a.cache {background-color: #FFCC00}
a.cluster {background-color: #9A0000}
a.index {background-color: #009900}
a.lobindex {background-color: #9AFE66}
a.lobsegment {background-color: #9A99FF}
a.rollback {background-color: #FF3300}
a.temporary {background-color: #DFFEFF}
a.table {background-color: #003399}
a.other {background-color: magenta}
body
{
background-color: white;
font-family: sans-serif;
font-size: 10pt;
}
</style
我們可以列出有關鼠標位置的block使用者、名稱、類型、block數量、以及片段的長度。爲了實現這一目的,我們需要兩個JavaScript函數,包含以上信息的這兩個函數被調用,並傳遞到表單的域內:
<script language="javascript"
function hover(own,nam,typ,bid,len)
{
document.form.owner.value = own;
document.form.name.value = nam;
document.form.type.value = typ;
document.form.block_id.value = bid;
document.form.length.value = len;
return true;
}
function leave()
{
document.form.owner.value = "";
document.form.name.value = "";
document.form.type.value = "";
document.form.block_id.value = "";
document.form.length.value = "";
return true;
}
</script
. . .
<form name="form"
<table border=0
<tr<tdOwner:</td<td<input name="owner" /</td</tr
<tr<tdName:</td<td<input name="name" /</td</tr
<tr<tdType:</td<td<input name="type" /</td</tr
<tr<tdBlock#:</td<td<input name="block_id" /</td</tr
<tr<tdLength:</td<td<input name="length" /</td</tr
</table
</form
對于每一片段,我們需要建立一個block的<a標簽。最後,建立一個顯示不同顔色含義的圖表:
<table border=0
<tr<thcolspan="2"Legend</th</tr
<tr<td<a name="free" class="free". </a</td
<tdFree Space</td</tr
<tr<td<a name="cache" class="cache". </a</td
<tdCache</td</tr
<tr<td<a name="cluster" class="cluster". </a</td
<tdCluster</td</tr
<tr<td<a name="index" class="index". </a</td
<tdIndex</td</tr
<tr<td<a name="lobindex" class="lobindex". </a</td
<tdLobIndex</td</tr
<tr<td<a name="lobsegment" class="lobsegment". </a</td
<tdLobSegment</td</tr
<tr<td<a name="rollback" class="rollback". </a</td
<tdRollback</td</tr
<tr<td<a name="temporary" class="temporary". </a</td
<tdTemporary</td</tr
<tr<td<a name="table" class="table". </a</td
<tdTable</td</tr
<tr<td<a name="other" class="other". </a</td
<tdOther</td</tr
</table
以下是完整代碼:
create or replace package blkmap
authidcurrent_user
as
procedure ts_menu;
procedure ts_map(p_name varchar2);
end blkmap;
/
show errors;
create or replace package body blkmap
as
procedure page_open;
procedure info_form;
procedure filemap(p_id number);
procedure legend;
procedure page_close;
--
procedure ts_menu
is
begin
htp.p('<html');
htp.p('<body bgcolor="white"');
htp.p('<h2Tablespaces</h2');
htp.p('<ul');
for ts in (select tablespace_name from dba_tablespaces) loop
htp.p('<li<a href="blkmap.ts_map?p_name='||ts.tablespace_name||'"'
||ts.tablespace_name||'</a</li');
end loop;
htp.p('</ul');
htp.p('</body');
htp.p('</html');
end ts_menu;
--
procedure ts_map(p_name varchar2)
is
begin