Decode360's Blog

          業(yè)精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 ::  :: 管理 ::
            302 隨筆 :: 26 文章 :: 82 評論 :: 0 Trackbacks
          本文作者: junsansi???? 轉(zhuǎn)載網(wǎng)址: http://www.5ienet.com/index.shtml
          ?
          ?
          第三部分邏輯standby(1)創(chuàng)建步驟? 2008.02.03
          ?
          ?
          一、準(zhǔn)備工作
          ?
          ??? 正如我們打小就被叮囑飯前一定要洗手,在創(chuàng)建邏輯standby 之前,準(zhǔn)備工作同樣必不可少。
          ?
          ??? 在創(chuàng)建邏輯standby 之前,首先檢查primary 數(shù)據(jù)庫的狀態(tài),確保primary 數(shù)據(jù)庫已經(jīng)為創(chuàng)建邏輯standby做好了全部準(zhǔn)備工作,比如說是否啟動了歸檔,是否啟用了forced logging 等,這部分可以參考創(chuàng)建物理standby時的準(zhǔn)備工作。
          ?
          ??? 除此之外呢,由于邏輯standby 是通過sql 應(yīng)用來保持與primary 數(shù)據(jù)庫的同步。sql 應(yīng)用與redo 應(yīng)用是有很大區(qū)別地,這事兒咱們前面提到過,redo 應(yīng)用實際上是物理standby 端進(jìn)行recover,sql 應(yīng)用則是分析redo 文件,將其轉(zhuǎn)換為sql 語句在邏輯standby 端執(zhí)行,因此,需要注意:
          ?
          ??? 并非所有的數(shù)據(jù)類型都能被邏輯standby支持;
          ?
          ????支持的數(shù)據(jù)類型有:
          ????BINARY_DOUBLE、BINARY_FLOAT、BLOB、CHAR、CLOB and NCLOB、DATE、INTERVAL YEAR TOMONTH、INTERVAL DAY TO SECOND、LONG、LONG RAW、NCHAR、NUMBER、NVARCHAR2、RAW、TIMESTAMP、TIMESTAMP WITH LOCAL TIMEZONE、TIMESTAMP WITH TIMEZONE、VARCHAR2 andVARCHAR

          ??? 提示:
          ??? 下列類型在獲取standby 支持時需要注意兼容性:
          ????¤ clob,需要primary 數(shù)據(jù)庫的兼容級別運行于10.1 或更高
          ????¤ 含lob 字段的索引組織表(IOT),需要primary 數(shù)據(jù)庫的兼容級別運行于10.2 或更高
          ????¤ 不含lob 字段的索引組織表(IOT),需要primary 數(shù)據(jù)庫的兼容級別運行于10.1 或更高

          ?
          ??? 不支持的數(shù)據(jù)類型有:
          ??? BFILE、Encrypted columns、ROWID, UROWID、XMLType、對象類型、VARRAYS、嵌套表、自定義類型。
          ?
          ??? 洗手殺菌可以用肥皂或洗手液,檢查數(shù)據(jù)庫是否有不被邏輯standby 支持的對象也同樣有簡單方式,我們可以通過查詢視圖DBA_LOGSTDBY_UNSUPPORTED 來確定主數(shù)據(jù)庫中是否含有不支持的對象:

          ??? SQL> SELECT * FROM DBA_LOGSTDBY_UNSUPPORTED;

          ?

          ??? 提示:關(guān)于DBA_LOGSTDBY_UNSUPPORTED
          ??? 該視圖顯示包含不被支持的數(shù)據(jù)類型的表的列名及該列的數(shù)據(jù)類型。注意該視圖的ATTRIBUTES 列,列值會顯示表不被sql 應(yīng)用支持的原因。

          ?
          ??? 并非所有的存儲類型都能被邏輯standby支持;
          ?
          ?? 支持簇表(Cluster tables)、索引組織表(Index-organized tables)、堆組織表(Heap-organized tables),不支持段壓縮(segment compression)存儲類型
          ?
          ??? 并非所有的pl/sql包都能被SQL應(yīng)用支持。
          ?
          ??? 那些可能修改系統(tǒng)元數(shù)據(jù)的包不會被sql 應(yīng)用支持,因此即使它們在primary 執(zhí)行過,并且被成功傳輸?shù)竭壿媠tandby 端, 也不會執(zhí)行, 例如: DBMS_JAVA, DBMS_REGISTRY, DBMS_ALERT,DBMS_SPACE_ADMIN, DBMS_REFRESH, DBMS_REDEFINITION, DBMS_SCHEDULER, and DBMS_AQ等。
          ??? 只有dbms_job 例外,primary 數(shù)據(jù)庫的jobs 會被復(fù)制到邏輯standby,不過在standby 數(shù)據(jù)庫不會執(zhí)行這些job。
          ?
          ??? 并非所有的sql語句都能在邏輯standby執(zhí)行;
          ?
          ??? 默認(rèn)情況下,下列sql 語句在邏輯standby 會被sql 應(yīng)用自動跳過:
          ??? ALTER DATABASE
          ??? ALTER MATERIALIZED VIEW
          ??? ALTER MATERIALIZED VIEW LOG
          ??? ALTER SESSION
          ??? ALTER SYSTEM
          ??? CREATE CONTROL FILE
          ??? CREATE DATABASE
          ??? CREATE DATABASE LINK
          ??? CREATE PFILE FROM SPFILE
          ??? CREATE MATERIALIZED VIEW
          ??? CREATE MATERIALIZED VIEW LOG
          ??? CREATE SCHEMA AUTHORIZATION
          ??? CREATE SPFILE FROM PFILE
          ??? DROP DATABASE LINK
          ??? DROP MATERIALIZED VIEW
          ??? DROP MATERIALIZED VIEW LOG
          ??? EXPLAIN
          ??? LOCK TABLE
          ??? SET CONSTRAINTS
          ??? SET ROLE
          ??? SET TRANSACTION

          ?
          ??? 另外,還有一大批ddl 操作,同樣也不會在邏輯standby 端執(zhí)行,由于數(shù)目較重,此處不再一一列舉,感興趣的話請google 查看官方文檔。
          ?
          ??? 并非所有的dml操作都能在邏輯standby端SQL 應(yīng)用;
          ?
          ??? 維護(hù)邏輯standby 與primary 的數(shù)據(jù)庫同步是通過sql 應(yīng)用實現(xiàn),SQL 應(yīng)用轉(zhuǎn)換的SQL 語句在執(zhí)行時,對于insert 還好說,對于update,delete 操作則必須能夠唯一定位到數(shù)據(jù)庫待更新的那條記錄。問題就在這里,如果primary 庫中表設(shè)置不當(dāng),可能就無法確認(rèn)唯一條件。
          ??? 你可能會說可以通過rowid 唯一嘛!!同學(xué),千萬要謹(jǐn)記啊,邏輯standby,為啥叫邏輯standby 呢,它跟物理standby 有啥區(qū)別呢,就是因為它只是邏輯上與primary 數(shù)據(jù)庫相同,物理上可能與primary 數(shù)據(jù)庫存在相當(dāng)大差異,一定要認(rèn)識到,邏輯standby 的物理結(jié)構(gòu)與primary 是不相同的(即使初始邏輯standby 是通過primary 的備份創(chuàng)建),因此想通過rowid 更新顯然是不好使的,就不能再將其做為唯一條件。那怎么辦泥,OK,話題被引入,下面請聽三思向您一一道來:
          ?
          ??? 如何確保primary庫中各表的行可被唯一標(biāo)識
          ?
          ??? Oracle 通過主鍵、唯一索引/約束補(bǔ)充日志(supplemental logging)來確定待更新邏輯standby 庫中的行。當(dāng)數(shù)據(jù)庫啟用了補(bǔ)充日志(supplemental logging),每一條update 語句寫redo 的時候會附加列值唯一信息,比如:
          ????◆ 如果表定義了主鍵,則主鍵值會隨同被更新列一起做為update 語句的一部分,以便執(zhí)行時區(qū)別哪些列應(yīng)該被更新。
          ??? ◆ 如果沒有主鍵,則非空的唯一索引/約束會隨同被更新列做為update 語句的一部分,以便執(zhí)行時區(qū)分哪些列應(yīng)該被更新,如果該表有多個唯一索引/約束,則oracle 自動選擇最短的那個。
          ??? ◆ 如果表即無主鍵,也沒有定義唯一索引/約束,所有可定長度的列連同被更新列作為update 語句的一部分。更明確的話,可定長度的列是指那些除:long,lob,long raw,object type,collection 類型外的列。
          ?
          ??? 確定在主數(shù)據(jù)庫上,補(bǔ)充日志是否被啟用,可以查詢v$database,如下:

          ??? SQL> select supplemental_log_data_pk,supplemental_log_data_ui from v$database;
          ??? SUP SUP
          ??? --- ---
          ??? YES YES


          ??? 因此,Oracle 建議你為表創(chuàng)建一個主鍵或非空的唯一索引/約束,以盡可能確保sql 應(yīng)用能夠有效應(yīng)用redo 數(shù)據(jù),更新邏輯standby 數(shù)據(jù)庫。
          ?
          ??? 執(zhí)行下列語句檢查sql 應(yīng)用能否唯一識別表列,找出不被支持的表

          ??? SQL> SELECT OWNER, TABLE_NAME FROM DBA_LOGSTDBY_NOT_UNIQUE
          ????? 2> WHERE (OWNER, TABLE_NAME) NOT IN
          ???? ?3> (SELECT DISTINCT OWNER, TABLE_NAME FROM DBA_LOGSTDBY_UNSUPPORTED)
          ????? 4> AND BAD_COLLUMN = 'Y';

          ??? 提示:關(guān)于DBA_LOGSTDBY_NOT_UNIQUE
          ??? 該視圖顯示所有即沒主鍵也沒唯一索引的表。如果表中的列包括足夠多的信息通常也可支持在邏輯standby 的更新,不被支持的表通常是由于列的定義包含了不支持的數(shù)據(jù)類型。
          ??? 注意BAD_COLUMN 列值,該列有兩個值:
          ??? Y:表示該表中有采用大數(shù)據(jù)類型的字段,比如LONG 啦,CLOB 啦之類。如果表中除log 列某些行記錄完全匹配,則該表無法成功應(yīng)用于邏輯standby。standby 會嘗試維護(hù)這些表,不過你必須保證應(yīng)用不允許
          ??? N:表示該表擁有足夠的信息,能夠支持在邏輯standby 的更新,不過仍然建議你為該表創(chuàng)建一個主鍵或者唯一索引/約束以提高log 應(yīng)用效率。

          ??? 假設(shè)某張表你可以確認(rèn)數(shù)據(jù)是唯一的,但是因為效率方面的考慮,不想為其創(chuàng)建主鍵或唯一約束,怎么辦呢,沒關(guān)系,oracle 想到了這一點,你可以創(chuàng)建一個disable 的primary-key rely 約束:
          ?
          ??? 關(guān)于primary-key RELY 約束:
          ??? 如果你能夠確認(rèn)表中的行是唯一的,那么可以為該表創(chuàng)建rely 的主鍵,RELY 約束并不會造成系統(tǒng)維護(hù)主鍵的開銷,主你對一個表創(chuàng)建了rely 約束,系統(tǒng)則會假定該表中的行是唯一,這樣能夠提供sql 應(yīng)用時的性能。但是需要注意,由于rely 的主鍵約束只是假定唯一,如果實際并不唯一的話,有可能會造成錯誤的更新喲。
          ?
          ??? 創(chuàng)建rely 的主鍵約束非常簡單,只要在標(biāo)準(zhǔn)的創(chuàng)建語句后加上RELY DISABLE 即可,例如:

          ??? SQL> alter table jss.b add primary key (id) rely disable;
          ??? 表已更改。

          ?

          二、創(chuàng)建步驟
          ?
          1、創(chuàng)建物理standby
          ?
          ??? 最方便的創(chuàng)建邏輯standby 的方式就是先創(chuàng)建一個物理standby,然后再將其轉(zhuǎn)換成邏輯standby,因此第一步就是先創(chuàng)建一個物理standby。注意,在將其轉(zhuǎn)換為邏輯standby 前,可以隨時啟動和應(yīng)用redo,但是如果你決定將其轉(zhuǎn)換為邏輯standby,就必須先停止該物理standby 的redo 應(yīng)用,以避免提前應(yīng)用含
          LogMiner 字典的redo 數(shù)據(jù),造成轉(zhuǎn)換為邏輯standby 后,sql 應(yīng)用時logMiner 字典數(shù)據(jù)不足而影響到邏輯standby 與primary 的正常同步。
          ?
          2、設(shè)置primary 數(shù)據(jù)庫
          ?
          ??? 在前面創(chuàng)建standby 時我們曾經(jīng)設(shè)置過無數(shù)個初始化參數(shù)用于primary 與物理standby 的角色切換,我想說的是,對于邏輯standby 的角色切換,那些參數(shù)同樣好使。
          ??? 不過注意,如果希望primary 數(shù)據(jù)庫能夠正常切換為邏輯standby 角色的話,那么你還需要設(shè)置相應(yīng)的log_archive_dest_N,并且valid_for 屬性,需要更改成:(STANDBY_LOGFILES,STANDBY_ROLE)。
          ?
          ??? 然后需要生成LogMiner 字典信息,通過執(zhí)行下列語句生成(務(wù)必執(zhí)行):

          ??? SQL> EXECUTE DBMS_LOGSTDBY.BUILD;

          ?
          ??? 該過程專門用于生成記錄的元數(shù)據(jù)信息到redo log,這樣改動才會被傳輸?shù)竭壿媠tandby,然后才會被邏輯standby 進(jìn)行SQL 應(yīng)用。

          ??? 提示:
          ????¤ 該過程會自動啟用primary 數(shù)據(jù)庫的補(bǔ)充日志(supplemental logging)功能(如果未啟用的話)。
          ????¤ 該過程執(zhí)行需要等待當(dāng)前所有事務(wù)完成,因此如果當(dāng)前有較長的事務(wù)運行,可能該過程執(zhí)行也需要多花一些等待時間。
          ????¤ 該過程是通過閃回查詢的方式來獲取數(shù)據(jù)字典的一致性, 因此oracle 初始化參數(shù)UNDO_RETENTION 值需要設(shè)置的足夠大。

          3、轉(zhuǎn)換物理standby 為邏輯standby

          ??? 執(zhí)行下列語句,轉(zhuǎn)換物理standby 為邏輯standby:

          ??? SQL> alter database recover to logical standby NEW_DBNAME;

          ??? 關(guān)于db_name(注意喲,這可不是db_unique_name,不同于物理standby,邏輯standby 是一個全新的數(shù)據(jù)庫,因此建議你指定一個唯一的,與primary 不同的數(shù)據(jù)庫名),如果當(dāng)前使用spfile,則數(shù)據(jù)庫會自動修改其中的相關(guān)信息,如果使用的pfile,在下次執(zhí)行shutdown 的時候oracle 會提示你去修改db_name 初始化參數(shù)的值。

          ??? 提示:執(zhí)行該語句前務(wù)必確保已經(jīng)暫停了redo 應(yīng)用,另外轉(zhuǎn)換是單向的,即只能由物理standby 向邏輯standby 轉(zhuǎn)換,而不能由邏輯standby 轉(zhuǎn)成物理standby。這并不僅僅是因為dbname 發(fā)生了修改,更主要的原因是邏輯standby 僅是數(shù)據(jù)與primary 一致,其它如存儲結(jié)構(gòu),scn 等基于dbid 都不一相同。

          ?
          ??? 另外,該語句執(zhí)行過程中,需要應(yīng)用全部的LogMiner 字典相關(guān)的redo 數(shù)據(jù)。這部分操作完全依賴于primary 數(shù)據(jù)庫DBMS_LOGSTDBY.BUILD 的執(zhí)行以及傳輸?shù)絪tandby 后有多少數(shù)據(jù)需要被應(yīng)用。如果primary 數(shù)據(jù)庫執(zhí)行DBMS_LOGSTDBY.BUILD 失敗,則轉(zhuǎn)換操作也不會有結(jié)果,這時候你恐怕不得不先cancel 掉它,解決primary 數(shù)據(jù)庫的問題之后再嘗試執(zhí)行轉(zhuǎn)換。
          ?
          4、重建邏輯standby 的密碼文件

          ??? 主要是由于轉(zhuǎn)換操作修改了數(shù)據(jù)庫名,因此密碼文件也需要重建,這個操作我們做的比較多,這里就不詳述了。
          ?
          5、調(diào)整邏輯standby 初始化參數(shù)
          ?
          ??? 之所以要調(diào)整初始化參數(shù),一方面是由于此處我們的邏輯standby 是從物理standby 轉(zhuǎn)換來的,某些參數(shù)并不適合甚至可能造成錯誤,比如log_archive_dest_n 參數(shù)的設(shè)置。另一方面,由于邏輯standby 會有讀寫操作,因此需要讀寫本地online redologs 及并產(chǎn)生archivelogs,務(wù)必需要注意本地的archivelogs 路徑不要與應(yīng)用接收自primary 數(shù)據(jù)庫的redo 數(shù)據(jù)生成的archivelogs 路徑?jīng)_突。當(dāng)然歸根結(jié)底是因為邏輯standby是從物理standby 轉(zhuǎn)換而來,因此standby 的初始化參數(shù)就需要第二次調(diào)整(第一次是創(chuàng)建物理standby),這里為什么要選擇從物理standby 轉(zhuǎn)換呢?很簡單,因為前面測試過程中創(chuàng)建了兩個standby,所以我覺著直接轉(zhuǎn)換一個當(dāng)成邏輯standby,操作更省事兒:)
          ??? 當(dāng)然我相信,看完這個系列,如果你對于創(chuàng)建的流程能夠非常清晰,完全可以跳過先創(chuàng)建物理standby的過程,直接創(chuàng)建邏輯standby。
          ??? 關(guān)于修改初始化參數(shù)的方式有多種,通過alter system set 也可以,或者先生成pfile 修改相關(guān)參數(shù),然后再根據(jù)修改過的pfile 生成spfile 也可以。
          ?
          6、打開邏輯standby
          ?
          ??? 由于邏輯standby 與primary 數(shù)據(jù)庫事務(wù)并不一致,因此第一次打開時必須指定resetlogs 選擇,如下:

          ??? SQL> alter database open resetlogs;

          ??? 然后可以通過執(zhí)行下列sql 命令應(yīng)用redo 數(shù)據(jù):

          ??? SQL> alter database start logical standby apply immediate;

          ??? 如果想停止邏輯standby 的sql 應(yīng)用,可以通過下列命令:

          ??? SQL> alter database stop logical standby apply immediate;

          ?
          ?




          -The End-

          posted on 2009-02-23 23:15 decode360-3 閱讀(429) 評論(0)  編輯  收藏 所屬分類: DBA
          主站蜘蛛池模板: 义乌市| 龙胜| 美姑县| 沧源| 沙坪坝区| 南安市| 平罗县| 信阳市| 玛纳斯县| 崇州市| 左权县| 嘉鱼县| 视频| 荣成市| 武隆县| 措勤县| 会同县| 都兰县| 崇礼县| 巴马| 西昌市| 平乐县| 汕尾市| 枝江市| 瓦房店市| 唐海县| 隆回县| 金山区| 商南县| 墨竹工卡县| 顺平县| 高要市| 永定县| 区。| 信丰县| 玉溪市| 晋州市| 睢宁县| 揭西县| 千阳县| 阿坝|