Oracle 12c新特性對于業務上的一些影響總結
1、不可見字段
在Oracle 11g R1中,Oracle以不可見索引和虛擬字段的形式引入了一些不錯的增強特性。繼承前者并發揚光大,Oracle 12c R1中引入了不可見字段思想。在之前的版本中,為了隱藏重要的數據字段以避免在通用查詢中顯示,我們往往會創建一個視圖來隱藏所需信息或應用某些安全條件。
在12c R1中,你可以在表中創建不可見字段。當一個字段定義為不可見時,這一字段就不會出現在通用查詢中,除非在SQL語句或條件中有顯式的提及這一字段,或是在表定義中有DESCRIBED。要添加或是修改一個不可見字段是非常容易的,反之亦然。
- SQL> CREATE TABLE emp (eno number(6), ename name varchar2(40), sal number(9) INVISIBLE);
- SQL> ALTER TABLE emp MODIFY (sal visible);
你必須在INSERT語句中顯式提及不可見字段名以將不可見字段插入到數據庫中。虛擬字段和分區字段同樣也可以定義為不可見類型。但臨時表,外部表和集群表并不支持不可見字段。
2、 DDL日志
在之前的版本中沒有可選方法來對DDL操作進行日志記錄。而在12c R1中,你現在可以將DDL操作寫入xml和日志文件中。這對于了解誰在什么時間執行了create或drop命令是十分有用的。要開啟這一功能必須對ENABLE_DDL_LOGGING 初始參數加以配置。這一參數可以在數據庫或會話級加以設置。當此參數為啟用狀態,所有的DDL命令會記錄在$ORACLE_BASE/diag/rdbms/DBNAME/log|ddl 路徑下的xml和日志文件中。一個xml中包含DDL命令,IP地址,時間戳等信息。這可以幫助確定在什么時候對用戶或表進行了刪除亦或是一條DDL語句在何時觸發。
開啟DDL日志功能
- SQL> ALTER SYSTEM|SESSION SET ENABLE_DDL_LOGGING=TRUE;
以下的DDL語句可能會記錄在xml或日志文件中:
-
CREATE|ALTER|DROP|TRUNCATE TABLE
-
DROP USER
-
CREATE|ALTER|DROP PACKAGE|FUNCTION|VIEW|SYNONYM|SEQUENC
3、如何在RMAN中執行SQL語句
在12c中,你可以在不需要SQL前綴的情況下在RMAN中執行任何SQL和PL/SQL命令,即你可以從RMAN直接執行任何SQL和PL/SQL命令。如下便是在RMAN中執行SQL語句的示例:
- RMAN> SELECT username,machine FROM v$session;
- RMAN> ALTER TABLESPACE users ADD DATAFILE SIZE 121m;
4、 RMAN中的表恢復和分區恢復
Oracle數據庫備份主要分為兩類:邏輯和物理備份。每種備份類型都有其自身的優缺點。在之前的版本中,利用現有物理備份來恢復表或分區是不可行的。為了恢復特定對象,邏輯備份是必需的。對于12c R1,你可以在發生drop或truncate的情況下從RMAN備份將一個特定的表或分區恢復到某個時間點或SCN。
當通過RMAN發起一個表或分區恢復時,大概流程是這樣的:
-
確定要恢復表或分區所需的備份集
-
在恢復表或分區的過程中,一個輔助數據庫會臨時設置為某個時間點
-
利用數據泵將所需表或分區導出到一個dumpfile
-
你可以從源數據庫導入表或分區(可選)
-
在恢復過程中進行重命名操作
以下是一個通過RMAN對表進行時間點恢復的示例(確保你已經對稍早的數據庫進行了完整備份):
- RMAN> connect target "username/password as SYSBACKUP";
- RMAN> RECOVER TABLE username.tablename UNTIL TIME 'TIMESTAMP…'
- AUXILIARY DESTINATION '/u01/tablerecovery'
- DATAPUMP DESTINATION '/u01/dpump'
- DUMP FILE 'tablename.dmp'
- NOTABLEIMPORT -- this option avoids importing the table automatically.(此選項避免自動導入表)
- REMAP TABLE 'username.tablename': 'username.new_table_name'; -- can rename table with this option.(此選項可以對表重命名)
重要提示:
-
確保對于輔助數據庫在/u01文件系統下有足夠的可用空間,同時對數據泵文件也有同樣保證
-
必須要存在一份完整的數據庫備份,或者至少是要有SYSTEM相關的表空間備份
以下是在RMAN中應用表或分區恢復的限制和約束:
-
SYS用戶表或分區無法恢復
-
存儲于SYSAUX和SYSTEM表空間下的表和分區無法恢復
-
當REMAP選項用來恢復的表包含NOT NULL約束時,恢復此表是不可行的
5、 限制PGA的大小
在Oracle 12c R1之前,沒有選項可以用來限制和控制PGA的大小。雖然你設置某個大小為PGA_AGGREGATE_TARGET 的初始參數,Oracle會根據工作負載和需求來動態地增大或減小PGA的大小。而在12c中,你可以通過開啟自動PGA管理來對PGA設定硬性限制,這需要對PGA_AGGREGATE_LIMIT 參數進行設置。因此,你現在可以通過設置新的參數來對PGA設定硬性限制以避免過度使用PGA。
- SQL> ALTER SYSTEM SET PGA_AGGREGATE_LIMIT=2G;
- SQL> ALTER SYSTEM SET PGA_AGGREGATE_LIMIT=0; --disables the hard limit
重要提示:
當超過了當前PGA的限制,Oracle會自動終止/中止會話或進程以保持最合適的PGA內存。
6、 對表分區維護的增強
在第一部分中,我解釋了如何在線或是離線狀態下遷移一個表分區或子分區到另一個不同的表空間。在本文中,主要介紹表分區其他方面的改進。
添加多個新分區
在Oracle 12c R1之前,一次只可能添加一個新分區到一個已存在的分區表。要添加一個以上的新分區,需要對每個新分區都單獨執行一次ALTER TABLE ADD PARTITION語句。而Oracle 12c只需要使用一條單獨的ALTER TABLE ADD PARTITION 命令就可以添加多個新分區,這增加了數據庫靈活性。以下示例說明了如何添加多個新分區到已存在的分區表:
- SQL> CREATE TABLE emp_part
- (eno number(8), ename varchar2(40), sal number (6))
- PARTITION BY RANGE (sal)
- (PARTITION p1 VALUES LESS THAN (10000),
- PARTITION p2 VALUES LESS THAN (20000),
- PARTITION p3 VALUES LESS THAN (30000)
- );
添加兩個新分區:
- SQL> ALTER TABLE emp_part ADD PARTITION
- PARTITION p4 VALUES LESS THAN (35000),
- PARTITION p5 VALUES LESS THAN (40000);
同樣,只要MAXVALUE分區不存在,你就可以添加多個新分區到一個列表和系統分區表。
如何刪除和截斷多個分區/子分區
作為數據維護的一部分,DBA通常會在一個分區表上進行刪除或截斷分區的維護任務。在12c R1之前,對于一個已存在的分區表一次只可能刪除或截斷一個分區。而對于Oracle 12c, 可以用單條ALTER TABLE table_name {DROP|TRUNCATE} PARTITIONS 命令來撤銷或合并多個分區和子分區。
下例說明了如何在一個已存在分區表上刪除或截斷多個分區:
- SQL> ALTER TABLE emp_part DROP PARTITIONS p4,p5;
- SQL> ALTER TABLE emp_part TRUNCATE PARTITONS p4,p5;
要保持索引更新,使用UPDATE INDEXES或UPDATE GLOBAL INDEXES語句,如下所示:
- SQL> ALTER TABLE emp_part DROP PARTITIONS p4,p5 UPDATE GLOBAL INDEXES;
- SQL> ALTER TABLE emp_part TRUNCATE PARTITIONS p4,p5 UPDATE GLOBAL INDEXES;
如果你在不使用UPDATE GLOBAL INDEXES 語句的情況下刪除或截斷一個分區,你可以在USER_INDEXES或USER_IND_PARTITIONS 字典視圖下查詢ORPHANED_ENTRIES字段以找出是否有索引包含任何的過期條目。
將單個分區分割為多個新分區
在12c中新增強的SPLIT PARTITION 語句可以讓你只使用一個單獨命令將一個特定分區或子分區分割為多個新分區。下例說明了如何將一個分區分割為多個新分區:
- SQL> CREATE TABLE emp_part
- (eno number(8), ename varchar2(40), sal number (6))
- PARTITION BY RANGE (sal)
- (PARTITION p1 VALUES LESS THAN (10000),
- PARTITION p2 VALUES LESS THAN (20000),
- PARTITION p_max (MAXVALUE)
- );
- SQL> ALTER TABLE emp_part SPLIT PARTITION p_max INTO
- (PARTITION p3 VALUES LESS THAN (25000),
- PARTITION p4 VALUES LESS THAN (30000), PARTITION p_max);
將多個分區合并為一個分區
你可以使用單條ALTER TBALE MERGE PARTITIONS 語句將多個分區合并為一個單獨分區:
- SQL> CREATE TABLE emp_part
- (eno number(8), ename varchar2(40), sal number (6))
- PARTITION BY RANGE (sal)
- (PARTITION p1 VALUES LESS THAN (10000),
- PARTITION p2 VALUES LESS THAN (20000),
- PARTITION p3 VALUES LESS THAN (30000),
- PARTITION p4 VALUES LESS THAN (40000),
- PARTITION p5 VALUES LESS THAN (50000),
- PARTITION p_max (MAXVALUE)
- );
- SQL> ALTER TABLE emp_part MERGE PARTITIONS p3,p4,p5 INTO PARTITION p_merge;
如果分區范圍形成序列,你可以使用如下示例:
- SQL> ALTER TABLE emp_part MERGE PARTITIONS p3 TO p5 INTO PARTITION p_merge;
7、數據庫升級改進
每當一個新的Oracle版本發布,DBA所要面臨的挑戰就是升級過程。該部分我將介紹12c中引入的針對升級的兩個改進。
預升級腳本
在12c R1中,原有的utlu[121]s.sql 腳本由一個大為改善的預升級信息腳本preupgrd.sql所取代。除了預升級檢查驗證,此腳本還能以修復腳本的形式解決在升級過程前后出現的各種問題。
可以對產生的修復腳本加以執行來解決不同級別的問題,例如,預升級和升級后的問題。當手動升級數據庫時,腳本必須在實際升級過程初始化之前加以手動執行。然而,當使用DBUA工具來進行數據庫升級時,它會將預升級腳本作為升級過程的一部分加以自動執行,而且會提示你去執行修復腳本以防止報錯。
如何執行腳本:
- SQL> @$ORACLE_12GHOME/rdbms/admin/preupgrd.sql
以上腳本會產生一份日志文件以及一個[pre/post]upgrade_fixup.sql 腳本。所有這些文件都位于$ORACLE_BASE/cfgtoollogs 目錄下。在你繼續真正的升級過程之前,你應該瀏覽日志文件中所提到的建議并執行腳本以修復問題。
注意:你要確保將preupgrd.sql和utluppkg.sql 腳本從12c Oracle的目錄home/rdbms/admin directory拷貝至當前的Oracle的database/rdbms/admin路徑。
并行升級功能
數據庫升級時間的長短取決于數據庫上所配置的組件數量,而不是數據庫的大小。在之前的版本中,我們是無法并行運行升級程序,從而快速完成整個升級過程的。
在12c R1中,原有的catupgrd.sql 腳本由catctl.pl 腳本(并行升級功能)替代,現在我們可以采用并行模式運行升級程序了。
以下流程說明了如何初始化并行升級功能(3個過程);你需要在升級模式下在啟動數據庫后運行這一腳本:
- cd $ORACLE_12_HOME/perl/bin
- $ ./perl catctl.pl –n 3 -catupgrd.sql
以上兩個步驟需要在手動升級數據庫時運行。而DBUA也繼承了這兩個新變化。
8、通過網絡恢復數據文件
在12c R1中另一個重要的增強是,你現在可以在主數據庫和備用數據庫之間用一個服務名重新獲得或恢復數據文件、控制文件、參數文件、表空間或整個數據庫。這對于同步主數據庫和備用數據庫極為有用。
當主數據庫和備用數據庫之間存在相當大的差異時,你不再需要復雜的前滾流程來填補它們之間的差異。RMAN能夠通過網絡執行備用恢復以進行增量備份,并且可以將它們應用到物理備用數據庫。你可以用服務名直接將所需數據文件從備用點拷貝至主站,這是為了防止主數據庫上數據文件、表空間的丟失,或是沒有真正從備份集恢復數據文件。
以下流程演示了如何用此新功能執行一個前滾來對備用數據庫和主數據庫進行同步:
在物理備用數據庫上:
- ./rman target "username/password@standby_db_tns as SYSBACKUP"
- RMAN> RECOVER DATABASE FROM SERVICE primary_db_tns USING COMPRESSED BACKUPSET;
以上示例使用備用數據庫上定義的primary_db_tns 連接字符串連接到主數據庫,然后執行了一個增量備份,再將這些增量備份傳輸至備用目的地,接著將應用這些文件到備用數據庫來進行同步。然而,需要確保已經對primary_db_tns 進行了配置,即在備份數據庫端將其指向主數據庫。
在以下示例中,我將演示一個場景通過從備用數據庫獲取數據文件來恢復主數據庫上丟失的數據文件:
在主數據庫上:
- ./rman target "username/password@primary_db_tns as SYSBACKUP"
- RMAN> RESTORE DATAFILE ‘+DG_DISKGROUP/DBANME/DATAFILE/filename’ FROM SERVICE standby_db_tns;
#p#
9、 對Data Pump的增強
Data Pump版本有了不少有用的改進,例如在導出時將視圖轉換為表,以及在導入時關閉日志記錄等。
關閉redo日志的生成
Data Pump中引入了新的TRANSFORM選項,這對于對象在導入期間提供了關閉重做生成的靈活性。當為TRANSFORM選項指定了DISABLE_ARCHIVE_LOGGING 值,那么在整個導入期間,重做生成就會處于關閉狀態。這一功能在導入大型表時緩解了壓力,并且減少了過度的redo產生,從而加快了導入。這一屬性還可應用到表以及索引。以下示例演示了這一功能:
- $ ./impdp directory=dpump dumpfile=abcd.dmp logfile=abcd.log TRANSFORM=DISABLE_ARCHIVE_LOGGING:Y
將視圖轉換為表
這是Data Pump中另外一個改進。有了VIEWS_AS_TABLES 選項,你就可以將視圖數據載入表中。以下示例演示了如何在導出過程中將視圖數據載入到表中:
- $ ./expdp directory=dpump dumpfile=abcd.dmp logfile=abcd.log views_as_tables=my_view:my_table
5. 實時自動數據診斷監視器 (ADDM) 分析
通過使用諸如AWR、ASH以及ADDM之類的自動診斷工具來分析數據庫的健康狀況,是每個DBA日程工作的一部分。盡管每種工具都可以在多個層面衡量數據庫的整體健康狀況和性能,但沒有哪個工具可以在數據庫反應遲鈍或是完全掛起的時候使用。
當數據庫反應遲鈍或是掛起狀態時,而且你已經配置了Oracle 企業管理器 12c的云控制,你就可以對嚴重的性能問題進行診斷。這對于你了解當前數據庫發生了什么狀況有很大幫助,而且還能夠對此問題給出解決方案。
以下步驟演示了如何在Oracle 企業管理器 12c上分析數據庫狀態:
-
在訪問數據庫訪問主頁面從Performance菜單選擇Emergency Monitoring 選項。這會顯示掛起分析表中排名靠前的阻止會話。
-
在Performance菜單選擇Real-Time ADDM 選項來執行實時ADDM分析。
-
在收集了性能數據后,點擊Findings標簽以獲得所有結果的交互總結。
10、 同時在多個表上收集統計數據
在之前的Oracle數據庫版本中,當你執行一個DBMS_STATS 程序來收集表、索引、模式或者數據庫級別的統計數據時,Oracle習慣于一次一個表的收集統計數據。如果表很大,那么推薦你采用并行方式。在12c R1中,你現在可以同時在多個表、分區以及子分區上收集統計數據。在你開始使用它之前,你必須對數據庫進行以下設置以開啟此功能:
- SQL> ALTER SYSTEM SET RESOURCE_MANAGER_PLAN='DEFAULT_MAIN';
- SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=4;
- SQL> EXEC DBMS_STATS.SET_GLOBAL_PREFS('CONCURRENT', 'ALL');
- SQL> EXEC DBMS_STATS.GATHER_SCHEMA_STATS('SCOTT');
11、 自動存儲管理(ASM)中的增強
Flex ASM
在一個典型的網格基礎架構安裝環境中,每個節點都運行自身的ASM實例,并將其作為運行于此節點上數據庫的存儲容器。但這種設置會存在相應的單點故障危險。例如,如果此節點上的ASM實例發生故障,則運行于此節點上的所有數據庫和實例都會受到影響。為了避免ASM實例的單點故障,Oracle 12c提供了一個名為Flex ASM的功能。Flex ASM是一個不同的概念和架構,只有很少數量的ASM實例需要運行在集群中的一些服務器上。當某節點上的一個ASM實例發生故障,Oracle集群就會在另一個不同的節點上自動啟動替代ASM實例以加強可用性。另外,這一設置還為運行在此節點上的實例提供了ASM實例負載均衡能力。Flex ASM的另一個優勢就是可以在單獨節點上加以配置。
當選擇Flex Cluster選項作為集群安裝環境的第一部分時,鑒于Flex Cluster的要求,Flex ASM配置就會被自動選擇。傳統集群同樣也適用于Flex ASM。當你決定使用Flex ASM時,你必須保證所需的網絡是可用的。你可以選擇Flex ASM存儲選項作為集群安裝環境的一部分,或是使用ASMCA在一個標準集群環境下啟用Flex ASM。
以下命令顯示了當前的ASM模式:
- $ ./asmcmd showclustermode
- $ ./srvctl config asm
或是連接到ASM實例并查詢INSTANCE_TYPE參數。如果輸出值為ASMPROX,那么,就說明Flex ASM已經配置好了。
ASM存儲限制放寬
ASM存儲硬性限額在最大ASM磁盤群組和磁盤大小上已經大幅提升。在 12c R1中,ASM支持511個ASM磁盤群組,而在11g R2中只支持63個。同樣,相比起在11g R2中20 PB的磁盤大小,現在已經將這一數字提高到32 PB。
對ASM均衡操作的優化
12c 中新的EXPLAIN WORK FOR 語句用于衡量一個給定ASM均衡操作所需的工作量,并在V$ASM_ESTIMATE動態視圖中輸入結果。使用此動態視圖,你可以調整POWERLIMIT語句對重新平衡操作工作進行改善。例如,如果你想衡量添加一個新ASM磁盤所需的工作量,在實際執行手動均衡操作之前,你可以使用以下命令:
- SQL> EXPLAIN WORK FOR ALTER DISKGROUP DG_DATA ADD DISK data_005;
- SQL> SELECT est_work FROM V$ASM_ESTIMATE;
- SQL> EXPLAIN WORK SET STATEMENT_ID='ADD_DISK' FOR ALTER DISKGROUP DG_DATA AD DISK data_005;
- SQL> SELECT est_work FROM V$ASM_ESTIMATE WHERE STATEMENT_ID = 'ADD_DISK’;
你可以根據從動態視圖中獲取的輸出來調整POWER的限制以改善均衡操作。
ASM 磁盤清理
在一個ASM磁盤群組中,新的ASM磁盤清理操作分為正常或高冗余兩個級別,它可以檢驗ASM磁盤群組中所有磁盤的邏輯數據破壞,并且可以自動對邏輯破壞進行修復,如果檢測到有邏輯數據破壞,就會使用ASM鏡像磁盤。磁盤清理可以在磁盤群組,特定磁盤或是某個文件上執行,這樣其影響可降到最小程度。以下演示了磁盤清理場景:
- SQL> ALTER DISKGROUP dg_data SCRUB POWER LOW:HIGH:AUTO:MAX;
- SQL> ALTER DISKGROUP dg_data SCRUB FILE '+DG_DATA/MYDB/DATAFILE/filename.xxxx.xxxx'
- REPAIR POWER AUTO;
ASM的活動會話歷史(ASH)
V$ACTIVE_SESSION_HISOTRY 動態視圖現在還可以提供ASM實例的活動會話抽樣。然而,診斷包的使用是受到許可限制的。
12、 網格(Grid)基礎架構的增強
Flex 集群
Oracle 12c 在集群安裝時支持兩類配置:傳統標準集群和Flex集群。在一個傳統標準集群中,所有集群中的節點都彼此緊密地整合在一起,并通過私有網絡進行互動,而且可以直接訪問存儲。另一方面,Flex集群在Hub和Leaf節點結構間引入了兩類節點。分配在Hub中的節點類似于傳統標準集群,它們通過私有網絡彼此互連在一起并對存儲可以進行直接讀寫訪問。而Leaf節點不同于Hub節點,它們不需要直接訪問底層存儲;相反的是,它們通過Hub節點對存儲和數據進行訪問。
你可以配置多達64個Hub節點,而Leaf節點則可以更多。在Oracle Flex集群中,無需配置Leaf節點就可以擁有Hub節點,而如果沒有Hub節點的話,Leaf節點是不會存在的。對于一個單獨Hub節點,你可以配置多個Leaf節點。在Oracle Flex集群中,只有Hub節點會直接訪問OCR和Voting磁盤。當你規劃大規模的集群環境時,這將是一個非常不錯的功能。這一系列設置會大大降低互連擁堵,并為傳統標準集群提供空間以擴大集群。
部署Flex集群的兩種途徑:
1. 在配置一個全新集群的時候部署
2. 升級一個標準集群模式到Flex集群
如果你正在配置一個全新的集群,你需要在步驟3中選擇集群配置的類型,選擇配置一個Flex集群選項,然后你需要在步驟6中對Hub和Leaf節點進行分類。對于每個節點,選擇相應角色是Hub或是Leaf,而虛擬主機名也是可選的。
將一個標準集群模式轉換為Flex 集群模式需要以下步驟:
1. 用以下命令獲取集群的當前狀態:
$ ./crsctl get cluster mode status |
2. 以root用戶執行以下命令:
$ ./crsctl set cluster mode flex |
3. 根據設計改變節點角色:
$ ./crsctl get node role config |
注意:
· 你無法從Flex恢復回標準集群模式
· 改變集群節點模式需要集群棧停止
· 確保以一個固定的VIP配置GNS
ASM磁盤群組中的OCR備份
對于12c,OCR現在可以在ASM磁盤群組中得以備份。這簡化了通過所有節點對OCR備份文件的訪問。為了防止OCR的恢復,你不必擔心OCR最新的備份是在哪個節點上。可以從任何節點輕易識別存儲在ASM中的最新備份并能很容易地執行恢復。
以下演示了如何將ASM磁盤群組設置為OCR備份位置:
$ ./ocrconfig -backuploc +DG_OCR |
支持IPv6協議
對于12c,Oracle是支持IPv6網絡協議配置的。你現在可以在IPv4或IPv6上配置共有或私有網絡接口,盡管如此,你需要確保在所有集群中的節點上使用相同的IP協議。
13、 RAC數據庫的增強
What-if命令評估
通過srvctl使用新的What-if命令評估選項,現在可以確定運行此命令所造成的影響。這一新添加到srvctl的命令,可以在沒有實際執行或是不對當前系統做任何改變的情況下模擬此命令。這在想要對一個已存在的系統進行更改卻對結果不確定的時候特別有用。這樣,此命令就會提供進行變更的效果。而–eval 選項也可以通過crsctl 命令來使用。
例如,如果你想要知道停止一個特定數據庫會發生什么,那么你就可以使用以下示例:
$ ./srvctl stop database –d MYDB –eval |
srvctl的改進
對于srvctl命令還有一些新增功能。以下演示了如何用這些新增功能停止或啟動集群上的數據庫或實例資源。
srvctl start database|instance –startoption NOMOUNT|MOUNT|OPEN |
13、截斷表CASCADE
在之前的版本中,在子表引用一個主表以及子表存在記錄的情況下,是不提供截斷此主表操作的。而在12c中的帶有CASCADE操作的TRUNCATE TABLE可以截斷主表中的記錄,并自動對子表進行遞歸截斷,并作為DELETE ON CASCADE服從外鍵引用。由于這是應用到所有子表的,所以對遞歸層級的數量是沒有CAP的,可以是孫子表或是重孫子表等等。
這一增強擯棄了要在截斷一個主表之前先截斷所有子表記錄的前提。新的CASCADE語句同樣也可以應用到表分區和子表分區等。
SQL> TRUNCATE TABLE CASCADE; |
如果對于子表的外鍵沒有定義ON DELETE CASCADE 選項,便會拋出一個ORA-14705錯誤。
14、對Top-N查詢結果限制記錄
在之前的版本中有多種間接手段來對頂部或底部記錄獲取Top-N查詢結果。而在12c中,通過新的FETCH FIRST|NEXT|PERCENT語句簡化了這一過程并使其變得更為直接。為了從EMP表檢索排名前10的工資記錄,可以用以下新的SQL語句:
SQL> SELECT eno,ename,sal FROM emp ORDER BY SAL DESC |
以下示例獲取排名前N的所有相似的記錄。例如,如果第十行的工資值是5000,并且還有其他員工的工資符合排名前N的標準,那么它們也同樣會由WITH TIES語句獲取。
SQL> SELECT eno,ename,sal FROM emp ORDER BY SAL DESC |
以下示例限制從EMP表中獲取排名前10%的記錄:
SQL> SELECT eno,ename,sal FROM emp ORDER BY SAL DESC |
以下示例忽略前5條記錄并會顯示表的下5條記錄:
SQL> SELECT eno,ename,sal FROM emp ORDER BY SAL DESC |
所有這些限制同樣可以很好的應用于PL/SQL塊。
- BEGIN
- SELECT sal BULK COLLECT INTO sal_v FROM EMP
- FETCH FIRST 100 ROWS ONLY;
- END;
15、對SQL*Plus的各種增強
SQL*Plus的隱式結果:12c中,在沒有實際綁定某個RefCursor的情況下,SQL*Plus從一個PL/SQL塊的一個隱式游標返回結果。這一新的dbms_sql.return_result過程將會對PL/SQL 塊中由SELECT 語句查詢所指定的結果加以返回并進行格式化。以下代碼對此用法進行了描述:
- SQL> CREATE PROCEDURE mp1
- res1 sys_refcursor;
- BEGIN
- open res1 for SELECT eno,ename,sal FROM emp;
- dbms_sql.return_result(res1);
- END;
- SQL> execute mp1;
當此過程得以執行,會在SQL*Plus上返回格式化的記錄。
顯示不可見字段:在本系列文章的第一部分,我已經對不可見字段的新特性做了相關闡述。當字段定義為不可見時,在描述表結構時它們將不會顯示。然而,你可以通過在SQL*Plus提示符下進行以下設置來顯示不可見字段的相關信息:
SQL> SET COLINVISIBLE ON|OFF |
以上設置僅對DESCRIBE 命令有效。目前它還無法對不可見字段上的SELECT 語句結果產生效果。
16、會話級序列
在12c中現在可以創建新的會話級數據庫序列來支持會話級序列值。這些序列的類型在有會話級的全局臨時表上最為適用。
會話級序列會產生一個獨特范圍的值,這些值是限制在此會話內的,而非超越此會話。一旦會話終止,會話序列的狀態也會消失。以下示例解釋了創建一個會話級序列:
- SQL> CREATE SEQUENCE my_seq START WITH 1 INCREMENT BY 1 SESSION;
- SQL> ALTER SEQUENCE my_seq GLOBAL|SESSION;
對于會話級序列,CACHE, NOCACHE, ORDER 或 NOORDER 語句會予以忽略。
17、WITH語句的改善
在12c中,你可以用SQL更快的運行PL/SQL函數或過程,這些是由SQL語句的WITH語句加以定義和聲明的。以下示例演示了如何在WITH語句中定義和聲明一個過程或函數:
- WITH
- PROCEDURE|FUNCTION test1 (…)
- BEGIN
- END;
- SELECT FROM table_name;
- /
盡管你不能在PL/SQL單元直接使用WITH語句,但其可以在PL/SQL單元中通過一個動態SQL加以引用。
18、擴展數據類型
在12c中,與早期版本相比,諸如VARCHAR2, NAVARCHAR2以及 RAW這些數據類型的大小會從4K以及2K字節擴展至32K字節。只要可能,擴展字符的大小會降低對LOB數據類型的使用。為了啟用擴展字符大小,你必須將MAX_STRING_SIZE的初始數據庫參數設置為EXTENDED。
要使用擴展字符類型需要執行以下過程:
1. 關閉數據庫
2. 以升級模式重啟數據庫
3. 更改參數: ALTERSYSTEM SET MAX_STRING_SIZE=EXTENDED;
4. 執行 utl32k.sql as sysdba: SQL> @?/rdbms/admin/utl32k.sql
5. 關閉數據庫
6. 以讀寫模式重啟數據庫
對比LOB數據類型,在ASSM表空間管理中,擴展數據類型的字段以SecureFiles LOB加以存儲,而在非ASSM表空間管理中,它們則是以BasciFiles LOB進行存儲的。
注意:一旦更改,你就不能再將設置改回STANDARD。
19、 在線重命名和重新定位活躍數據文件
不同于以往的版本,在Oracle數據庫12c R1版本中對數據文件的遷移或重命名不再需要太多繁瑣的步驟,即把表空間置為只讀模式,接下來是對數據文件進行離線操作。在12c R1中,可以使用ALTER DATABASE MOVE DATAFILE這樣的SQL語句對數據文件進行在線重命名和移動。而當此數據文件正在傳輸時,終端用戶可以執行查詢,DML以及DDL方面的任務。另外,數據文件可以在存儲設備間遷移,如從非ASM遷移至ASM,反之亦然。
重命名數據文件:
SQL> ALTER DATABASE MOVE DATAFILE '/u00/data/users01.dbf' TO '/u00/data/users_01.dbf'; |
從非ASM遷移數據文件至ASM:
SQL> ALTER DATABASE MOVE DATAFILE '/u00/data/users_01.dbf' TO '+DG_DATA'; |
將數據文件從一個ASM磁盤群組遷移至另一個ASM磁盤群組:
SQL> ALTER DATABASE MOVE DATAFILE '+DG_DATA/DBNAME/DATAFILE/users_01.dbf ' TO '+DG_DATA_02'; |
在數據文件已存在于新路徑的情況下,以相同的命名將其覆蓋:
SQL> ALTER DATABASE MOVE DATAFILE '/u00/data/users_01.dbf' TO '/u00/data_new/users_01.dbf' REUSE; |
復制文件到一個新路徑,同時在原路徑下保留其拷貝:
SQL> ALTER DATABASE MOVE DATAFILE '/u00/data/users_01.dbf' TO '/u00/data_new/users_01.dbf' KEEP; |
當通過查詢v$session_longops動態視圖來移動文件時,你可以監控這一過程。另外,你也可以引用alert.log,Oracle會在其中記錄具體的行為。
20、 表分區或子分區的在線遷移
在Oracle 12c R1中遷移表分區或子分區到不同的表空間不再需要復雜的過程。與之前版本中未分區表進行在線遷移類似,表分區或子分區可以在線或是離線遷移至一個不同的表空間。當指定了ONLINE語句,所有的DML操作可以在沒有任何中斷的情況下,在參與這一過程的分區或子分區上執行。與此相反,分區或子分區遷移如果是在離線情況下進行的,DML操作是不被允許的。
示例:
SQL> ALTER TABLE table_name MOVE PARTITION|SUBPARTITION partition_name TO tablespace tablespace_name; |
第一個示例是用來在離線狀況下將一個表分區或子分區遷移至一個新的表空間。第二個示例是在線遷移表分區或子分區并維護表上任何本地或全局的索引。此外,當使用ONLINE語句時,DML操作是不會中斷的。
重要提示:
-
UPDATE INDEXES語句可以避免出現表中任何本地或全局索引無法使用的情況。
-
表的在線遷移限制也適用于此。
-
引入加鎖機制來完成這一過程,當然它也會導致性能下降并會產生大量的redo,這取決于分區和子分區的大小。