11g中關於表新增欄位default屬性研究
在客戶現場碰到一個問題,客戶在業務期間,對一張非常大的表新增了一個欄位,並且採用default欄位預設非空,從而導致表被鎖定,undo被大量消耗,資源被大量佔用,接下來客戶主動掐掉了回話,導致資料庫回滾,資料庫直接無法連線。回滾結束後資料庫資源釋放,系統正常。重新新增欄位,預設欄位為空,新增成功。回想了一下,其實有幾點是不正確的,首先,最好不要在正常的業務期間對錶做大變更,特別是一張大表。其次新增欄位時要考慮謹慎,不要新增相關的default引數,這也是引起本次事故的原因,導致該表被直接鎖定,業務無法正常訪問。最好的辦法應該是先新增列,在業務空閒的時候執行對列的修改:alter table table_name add col_name data_type;
atler table table_name modify col_name default default_value;
在後來我想如果回滾時間非常久,那資料庫資源一直得不到釋放,那資料庫不是一直無法連線了,於是在網上找找看看有什麼相關的應急辦法。找到11G新特性中關於這個問題的解決辦法。
在11g中,可以直接修改資料字典將已有行的default值更新 而無需修改實際的表記錄。在10g中一旦新增某表並使用default引數,資料庫就會鎖定該表,並更新所有的行。而在11g中
我們採用alter table table_name add col_name data_type default 'XX' not null;時,oracle會將預設值寫到資料字典(sys.col$.default$)中,這樣,當我們新增了一個新列時,對於以前原有的資料,oracle採用資料字典中的資訊來表達,而對於新新增進來的列,則採用預設值寫入,這樣我們就可以將一個新列定義為非空並具有預設值,同時不會導致任何重做和undo開銷。本次測試旨在對該新特性有一個基本的瞭解。不做深入分析。
testing:
會話一:
SQL> create table test(a number);
Table created.
SQL> insert into test values(1);
1 row created.
SQL> insert into test values(2);
1 row created.
會話二:
SQL> conn frank/frank
Connected.
SQL> select * from test;
no rows selected
SQL> desc test;
Name Null? Type
—————————————– ——– —————————-
A NUMBER
SQL> alter table test add(b number default 10);
alter table test add(b number default 10)
*
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
SQL> alter table test add(b number default 10 not null);
(回話被hang住)
會話一:
SQL> commit;
Commit complete.
SQL>
會話二:
SQL> alter table test add(b number default 10 not null);
Table altered.
此時我們可以在回話一種查詢一下:
SQL> select * from test;
A B
———- ———-
1 10
2 10
預設欄位被新增進入,我們在查詢時,oracle內部其實對於已經存在的資料是不在做修改,它將從資料字典(sys.col$.default$)獲取預設值並將其返回給使用者,我們可以看一下儲存的資料:
SQL> select object_name,object_id from dba_objects where object_name='TEST';
OBJECT_NAM OBJECT_ID
———- ———-
TEST 18458
SQL> select OBJ#,COL#,NAME,DEFAULT$ from col$ where OBJ#=18458;
OBJ# COL# NAME DEFAULT$
———- ———- ———- ———-
18458 1 A
18458 2 B 10
我們可以看到,預設的default=10被寫入了ecl$基表中,當我們做查詢時。oracle其實是從這一部分取出值來應用。
本次資料庫實驗環境是11gR2 我們可以看出如果有其他事務未作提交,那麼當我新增具有default的值的列式如果是不是not null 的新列,是會報ORA-00054資源繁忙錯誤的,而如果新增not null時,則資料庫會hang住。(這和11gR1不一樣,在11gR1(11.1.0.6)中測試時,是可以成功的,可能對於R2做了改變),此時我們提交回話一的事務,則回話2獲得資源,會話也成功。
也就是說11g 後可以直接修改資料字典將已有行的default值更新 而無需修改實際的表記錄,他已經可以做到實時應用而不會因為表很大而造成效能問題。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23732248/viewspace-714916/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle大表新增欄位default經驗分享Oracle
- hibernate怎樣處理資料庫表中的有'default'屬性的欄位.資料庫
- 共有的表單欄位屬性
- ms sql 獲取表欄位的屬性SQL
- oracle 11g對大表中新增DEFAULT值的NOT NULL欄位速度有大幅度的提升OracleNull
- SQL新增表欄位SQL
- odoo ORM研究3 - odoo fields常用的欄位屬性OdooORM
- windows域控裡,屬性和欄位對映表Windows
- odoo欄位屬性列舉Odoo
- C#屬性與欄位C#
- 如何在水晶報表中動態新增欄位
- C#中的屬性和欄位的區別C#
- Scala的類、屬性、物件欄位物件
- [提問交流]建立模型,新增屬性,欄位型別如何設定2位小數的欄位型別模型型別
- destoon中自定義欄位的前臺顯示,及修改相關屬性
- oracle 11G 新增欄位調整效能Oracle
- Kotlin——中級篇(二): 屬性與欄位詳解Kotlin
- lambda方法引用獲取欄位屬性
- c#之事件_方法_屬性_欄位C#事件
- 利用 alter 語句修改欄位屬性
- Oracle 檢視 表屬性 :“表名(註釋)/列名(註釋)/欄位是否NULL”OracleNull
- oracle中判斷欄位是否存在和新增表結構Oracle
- MySQL information_schema庫中關於三個關於鎖相關表的欄位解釋彙總MySqlORM
- 在高併發、高負載的情況下,如何給表新增欄位並設定DEFAULT值?負載
- IL角度理解C#中欄位,屬性與方法的區別C#
- html5之新增表單屬性HTML
- 裝備屬性欄位設計和投放詳解
- Scala類的屬性以及物件私有欄位物件
- 關於oracle中blob欄位的錄入問題Oracle
- fastadmin 新增欄位記圖片欄位AST
- lambda 表示式從集合中獲取某個欄位屬性的集合
- Python SqlAlchemy動態新增資料表欄位PythonSQL
- C#通過反射獲取物件屬性,列印所有欄位屬性的值C#反射物件
- 從Sql server 2008獲取表欄位屬性資訊,註釋資訊SQLServer
- mysql-欄位設定Default值問題MySql
- Oracle 11g 向表中大欄位插入資料Oracle
- C#快速入門教程(5)——欄位與屬性C#
- 始終使用屬性(Property),而不是欄位(Data Member)