Ora-01536:超出了表空間users的空間限量

風靈使發表於2018-12-30

正在開會,同事跑過來說資料庫有問題,通訊程式不能入庫,趕快獲取一條insert into a values()語句後在toad工具中手動插入,發現報錯:Ora-01536:超出了表空間users的空間限量。

該表a的是使用者A下的一個大表,表空間是users,而非A使用者的預設表空間。users表空間有大約70%的空閒空間,為什麼a表就不能使用了呢?從網上搜尋後終於明白:

ora-1536 是指的你建表的那個user 所能使用的空間沒有了,不是那個表所在的tablespace 沒有free space 了。你需要做的是給那個user 對那個tablespace 有更多的space 可以使用。

解決辦法增大能夠使用的表空間數或授予無限制的使用許可權

ALTER USER A QUOTA 50M ON users;

ALTER USER  A  QUOTA UNLIMITED ON users;

但為什麼會出現這樣的問題呢,原來設計的時候使用者A,賦予DBA和resource許可權,並沒有設定表空間限額。但現在怎麼會出現這麼多的空間限額呢?

會不會是上次更改使用者A的預設表空間造成的呀?

上次為了資料庫便於維護,將使用者A的表從別的表空間移到了表空間中,然後更改表空間TS_A 為使用者A的預設表空間

select 'alter table '||table_name||' move tablespace TS_A ;'

from user_tables

where tablespace_name='LEE_TEST' ;

alter user A DEFAULT TABLESPACE TS_A;

把使用者A下的表全部移到表空間TS_A下,但因為a是一個比較大的表,所以沒有移動成功,a的表空間仍然是users

估計跟這次操作有關係 ,改天進行測試。那天進行移動表的儲存空間時還造成索引無效的錯誤,看來這次操作帶來負面影響還是真不少。

建立一個使用者,分配了400M的表空間,結果在用到13.3M時報錯:

ORA-01536: 超出表空間 '***' 的空間限額

經查,表空間跟表空間限額兩個值是不一樣的.
推測按預設的話oracle應該會給每個使用者分配一個預設的表空間限額,具體比例待查,但這比例肯定遠小於100%.
所以說分配了400M的表空間未必能儲存400M的資料.

解決辦法如下:

檢視使用者表空間的限額

select * from user_ts_quotas;

max_bytes欄位就是了
-1是代表沒有限制,其它值多少就是多少了.

不對使用者做表空間限額控制:

GRANT UNLIMITED TABLESPACE TO ***(使用者);

這種方式是全域性性的.
或者

alter user ***(使用者名稱) quota unlimited on ***(表空間);

這種方式是針對特定的表空間的.

可以分配自然也可以回收了:

revoke unlimited tablespace from ***(使用者)

或者

alter user *** quota 0 on ***

表空間的大小與使用者的配額大小是兩種不同的概念。表空間的大小是指實際的使用者表空間的大小,而配額大小指的是使用者指定使用表空間的的大小

把表空間檔案增大,還是出現這個問題,使用者在使用表空間的同時使用空間的限額,如果超出限制,就算有空的地方,也不會讓使用者使用。

遇到ORA-01536錯誤,首先要檢視使用者的表空間的限額

   select * from dba_ts_quotas;

   select * from user_ts_quotas;

max_bytes欄位-1是代表沒有限制,其它值多少就是多少.

dba_ts_quotas :描述所有使用者表空間的限額

user_ts_quotas :描述當前使用者表空間的限額。

如果查詢結果中max_bytes欄位不為-1,修改為無限制或者指定的大小。

不對使用者做表空間限額控制:

    GRANT UNLIMITED TABLESPACE TOuser;

這種方式是全域性性的。 或者

    alter user  user  quota unlimited on  user_tablespace;

這種方式是針對特定的表空間的.

回收表空間限額控制:

    revoke unlimited tablespace from  user;

或者

    alter user  user  quota 0 on  user_tablespace;

ORACLE 表和索引遷移表空間

表做空間遷移時,使用如下語句:

例1:alter table tb_name move tablespace tbs_name;

索引表空間做遷移,使用如下語句:

例2:alter index index_name rebuild tablespace tbs_name;

對於含有lob欄位的表,在建立時,oracle會自動為lob欄位建立兩個單獨的segment,一個用來存放資料,另一個用來存放索引,並且它們都會儲存在對應表指定的表空間中,而例1:只能移動非lob欄位以外的資料,所以在對含有lob欄位的表進行空間遷移,需要使用如下語句:

例3:alter table tb_name move tablespace tbs_name lob (col_lob1,col_lob2) store as(tablesapce tbs_name);

專案例項:

表空間遷移

select 'alter table' ||table_name|| 'move tablespace tbs_name;' table_name from dba_tables where wner='%***%' and table_name like '%***%'

帶lob欄位

select 'alter table' ||table_name|| 'move lob('||index_name||') store as (tablespace tbs_name);' from dba_indexes where wner='%***%' and index_name like '%***%'

索引表空間

select 'alter index' ||index_name|| 'rebuild tablespace tbs_name;' index_name from dba_indexes where wner='%***%' and table_name like '%***%'

以上在oracle 的SQL*Plus Worksheet中執行,將得出的執行結果再執行一次即可

相關文章