Tommy 碎碎念
https://blog.teatime.com.tw/
Tommy Wu's blog
tommy
2024-03-19T12:46:36Z
-
如何在 PRIMARY 與 STANDBY DATABASE 切換
https://blog.teatime.com.tw/1/post/11
當你的 PRIMARY DATABASE 的主機, 需要做一些維護時, 是否你的 ORACLE 資料庫就必須要停止服務一段不算短的時間呢? 這對於一個需要 7*24 服務的主機來說, 實在是一個很難接受的情形.<p>如果你有 STANDBY DATABASE, 這時, 就可以將這個停機的時間, 大幅的減少到幾分鐘內. 讓你的 STANDBY DATABASE 轉換成 PRIMARY DATABASE, 繼續提供服務, 等原本的主機維護完成之後, 再切換回來.</p> <ul> <li>Step 1: <br /> </li> </ul> <blockquote> <p>因為要當做 PRIMARY DATABASE 的 ORACLE, 必須在 MAXIMIZE PERFORMANCE 的狀態下執行, 但是有些 STANDBY DATABASE 並非在這個狀態下執行, 所以, 在你要接手的 STANDBY DATABASE 上執行下面的指令:</p></blockquote><pre>alter database set standby database to maximize performance; <br /></pre><blockquote> </blockquote> <ul><li>Step 2: </li></ul> <ul> </ul> <blockquote> <p>在 PRIMARY DATABASE 上面, 中斷所有用戶的連線, 執行下面的指令:</p></blockquote><pre>alter system enable restricted session;<br />select switchover_status from v$database; <br /></pre><blockquote> </blockquote> <blockquote>上面那個 SWITCHOVER_STATUS, 據 ORALCE 的文件表示, 必須在 TO STANDBY 的情形下, 才可以做這個切換. 不過... 我怎麼試都會是 SESSION ACIVE, 因為... 至少我指令的這一個 SESSION 並還連線著, 如果不連著, 要怎麼下指令? 總之, 你可以在確定除了你這個連線外, 並沒有其他連線存在時, 執行下面的指令:</blockquote><pre>alter database commit to switchover to physical standby;<br />shutdown immediate; <br /></pre><blockquote> </blockquote> <blockquote>這時, 如果沒有錯誤, 原本這個 PRIMARY DATABASE 應該就可以被當成 STANDBY DATABASE 使用. (這兒要注意的是, 如果你的 STANDBY DATABASE 不止一個, 要確定你所設定的所有 LOG_ARCHIVE_DEST_n 都可以成功的寫出, 否則切換動作會失敗.</blockquote><blockquote> </blockquote> <ul> <li>Step 3:</li> </ul> <blockquote> <p>這時就把原本的 PRIMARY DATABASE 的 listener.ora, init$ORACLE_SID.ora 做一些更改, 改成 STANDBY DATABASE 使用的狀態. 也把 IP 換成不是 PRIMARY DATABASE 使用. 然後, 試試看可不可以用 STANDBY DATABASE 的方式啟動資料庫:</p></blockquote><pre>startup nomount;<br />alter database mount standby database; <br /></pre><blockquote> </blockquote> <blockquote>如果都成功, 執行下面的指令看看:</blockquote><pre>select switchover_status from v$database; <br /></pre><blockquote> </blockquote> <blockquote>這時, 據 ORACLE 的手冊來看, 應該會是 SWITCHOVER PENDING 才對, 不過, 同上, 我只得到 SESSION ACTIVE... :(<br /></blockquote> <blockquote> </blockquote> <ul> <li>Step 4:</li> </ul> <blockquote> <p>這時, 到原本的 STANDBY DATABASE 主機上, 執行下面的指令:</p></blockquote><pre>alter database commit to switchover to primary;<br />shutdown; <br /></pre><blockquote> </blockquote> <blockquote>這時, 這個 STANDBY DATABASE 應該就可以用一般資料庫的方式來啟動. 在啟動之前, 我們必須將 listener.ora, init$ORACLE_SID.ora 做一些更改, 改成 PRIMARY DATABASE 使用的狀態. 且也把原本 PRIMARY DATABASE 使用的 IP 加到這台主機上頭. 做好之後, 就可以啟動 ORACLE 了, 我們先用 RESTRICT 的方式啟動, 以免其他使用者連上線:</blockquote><pre>startup restrict; <br /></pre><blockquote> </blockquote> <ul><li>Step 5:</li></ul><blockquote><p>這時, 回到原本 PRIMARY DATABASE 的主機上, 執行下面的指令:</p></blockquote><pre>alter database recover managed standby database disconnect from session; <br /></pre><ul><li>Step 6:</li></ul><blockquote><p>再回到原本 STANDBY DATABASE (新的 PRIMARY DATABASE) 上頭, 執行下面的指令:</p></blockquote><pre>alter system archive log current; <br /></pre><blockquote><p>然後檢查看看是否正確產生到新的 STANDBY DATABASE (原本的 PRIMARY DATABASE) 中, 且正確的寫入.</p></blockquote><ul><li>Step 7:</li></ul><blockquote><p>如果一切都正常的話, 就在新的 PRIMARY DATABASE (原本的 STANDBY DATABASE) 執行下面 的指令開放連線:</p></blockquote><pre>alter system disable restricted session; <br /></pre><ul><li>Step 8:</li></ul><blockquote><p>要注意一下, 由於 TEMP 的 TABLESPACE 並不會在 STANDBY DATABASE 中產生檔案, 所以如果你新的 PRIMARY DATABASE 之前都未曾切換過, 則可能沒有 TEMP 的 DATAFILE 存在. 如果沒有的話, 可以執行類似下面的指令, 產生所需要的檔案:</p></blockquote><pre>ALTER TABLESPACE TEMP ADD TEMPFILE '/hisdb/oradata/SUN2/temp01.dbf' SIZE 500M REUSE;<br />ALTER TABLESPACE USRTEMP ADD TEMPFILE '/hisdb/oradata/SUN2/usrtemp01.dbf' SIZE 2000M REUSE;<br />ALTER TABLESPACE USRTEMP ADD TEMPFILE '/hisdb/oradata/SUN2/usrtemp02.dbf' SIZE 2000M REUSE;<br />ALTER TABLESPACE USRTEMP ADD TEMPFILE '/hisdb/oradata/SUN2/usrtemp03.dbf' SIZE 2000M REUSE; <br /></pre><p>這樣子, 你就可以用原本的 STANDBY DATABASE 暫時取代 PRIMARY DATABASE 的服務. 然後對原本的 PRIMARY DATABASE 的主機做維護. 等到維護完成, 如果有必要, 可以利用上述的動作, 再切換回來.</p>
Oracle
2003-10-10T21:45:53Z
tommy
-
使用 RMAN 在沒有 catalog 資料庫時的備份與還原方式
https://blog.teatime.com.tw/1/post/9
ORACLE 的 RMAN (Recovery Manager) 是一個不錯的備份與還原工具. 使用 RMAN 來備份資料庫時, 比以前使用的方式要快多了, 而且空間也節省了不少.<p>不過, 通常 ORACLE 在使用 RMAN 的時候, 都建議使用另一個 catalog 資料庫來存放備份的相關訊息. 對於這一點, 我一直無法認同.... 用另一個資料庫來存備份資訊, 那麼... 那一個 catalog 資料庫要怎麼備份呢? 因為在真的做資料回復的時候, 所能用的東西是越簡單越好, 如果還要依賴另一個資料庫, 那萬一那個資料庫也出事了, 要如何回復呢?<br /> <br /> 所以, 我習慣使用 RMAN 在沒有 catalog 資料庫的情形下做備份與還原的動作. 這樣的話, 我只要確定備份下來的檔案正常無誤, 就一定可以還原.<br /> <br /> 當不使用 catalog 資料庫時, 這些備份的資料也要有地方可以存放, 此時, 存放的位置就是 ORACLE 本身的 control 檔案. 使用這個方式備份時, 你的 controlfile 會因為存放這些資料而變的比較大 (可能會上數百 MB), 而且你要在你的參數檔案中指定這些資料的保存日數, 如:</p><pre>CONTROL_FILE_RECORD_KEEP_TIME = 14 <br /></pre><p>上面的參數會存放 14 天的資料. 你可以依據你的需求而決定這個數字. </p><ul> <li> 備份</li> </ul> <blockquote> <p>在備份的時候, 由於備份的資訊是存放在 controlfile 中, 所以我們必須在備份資料庫之後, 另外將 controlfile 備份出來, 如:</p></blockquote><pre>rman target / nocatalog <<EOF<br /> run {<br /> allocate channel t1 type disk;<br /> backup<br /> incremental level 0<br /> format '/backup/${TODAY}/%d_t%t_s%s_p%p'<br /> database<br /> maxsetsize 2G<br /> include current controlfile for standby;<br /> backup current controlfile tag='database backup';<br /> sql 'alter system archive log current';<br /> release channel t1;<br />}<br />exit<br />EOF <br /></pre><blockquote> </blockquote><blockquote>在原本的 backup database 指令後面, 多一行指令備份 controlfile, 備份出來的檔案會存放在 $ORACLE_HOME/dbs 的目錄下面. 只要你有保存這些備份出來的所有檔案,還有之後的 archivelog 檔案, 就可以將資料庫還原到最後一個 archivelog 的時間.<br /></blockquote><blockquote>另外, 也可以使用下面的指令備份 controlfile 來使用:</blockquote><pre>sqlplus "/ as sysdba" <<EOF<br />alter system archive log current;<br />alter database backup controlfile to '/backup/${TODAY}/control01.ctl';<br />exit<br />EOF <br /></pre><ul><li>還原</li></ul><blockquote><p>還原的時候, 先安裝一份 ORACLE, 之後將之前備份的檔案, 放回原本備份時的相關路徑內 (如果忘了... 做到後面會有錯誤, 就會知道該放那兒了).<br /><br />首先, 因為 ORACLE 要在 mount 的狀態下才能讀取 controlfile, 所以我們先將備份的 controlfile 找出來, 所以強迫將資料庫啟動在 mount 的狀態下, 如:</p></blockquote><pre>rman target / nocatalog <<EOF<br />startup force mount<br />run {<br /> allocate channel ch1 type disk;<br /> restore controlfile to '/tmp/cf.tmp' from tag='database backup'; <br />} <br />exit<br />EOF <br /></pre><blockquote><p>上述的指令要將 controlfile 由原本備份到 $ORACLE_HOME/dbs 中的檔案還原到/tmp/cf.tmp 這個檔案.<br /><br />這時將資料庫關閉, 再將還原的 controlfile 放回正確的路徑, 然後重新將資料庫啟動在 mount 的狀態下:</p></blockquote><pre>sqlplus / as sysdba <<EOF<br />shutdown abort;<br />exit<br />EOF<br /><br />cp /tmp/cf.tmp $ORACLE_DATA/control01.ctl<br /><br />sqlplus / as sysdba <<EOF<br />startup mount;<br />exit<br />EOF <br /></pre><blockquote><p>如果你的 controlfile 是另外備份出來的檔案, 也可以直接拿來使用, 就不須要上述的動作, 只要使用那些 controlfile 將資料庫啟動在 mount 狀態就可以了.</p><p>這時就可以使用 RMAN 來還原資料庫, 如:</p></blockquote><pre>rman target / nocatalog <<EOF<br />run {<br /> allocate channel ch1 type disk;<br /> restore database;<br />}<br />exit<br />EOF <br /></pre><blockquote><p>如果沒有其他的 archivelog 檔案, 可以在 restore database 之後加上下面的兩行指令:</p></blockquote><pre>recover database noredo;<br />sql 'alter database open resetlogs'; <br /></pre><blockquote><p>如果還有 archivelog 檔案, 在上述的 RMAN 指令結束之後, 再執行 recover 的動作, 如:</p></blockquote><pre>sqlplus / as sysdba <<EOF<br />recover database using backup controlfile until cancel;<br />alter database open resetlogs;<br />exit<br />EOF <br /></pre><blockquote><p>這樣整個資料庫就還原回來了.</p></blockquote>
Oracle
2002-11-22T21:05:36Z
tommy
-
你的系統有多少的隱藏參數 ?
https://blog.teatime.com.tw/1/post/8
ORACLE 的文件應該算是做的很詳細了, 在 OTN (http://otn.oracle.com) 中可以看到幾乎所有的文件, 如果不想線上查看, 也可以抓 PDF 格式的檔案回來慢慢看.<p>但是有一些參數是在文件上面查不到的, 通常這些參數一般使用上都用不到, 如果使用可能會造成 ORACLE 拒絕支援, 所以如果非必要, 不要使用這些參數. (我們通常只有在做某些回復作業時, 才會使用一些參數)</p> <p>下面的指令可以把你使用的 ORACLE 中所有的隱藏參數列出:</p><pre>select x.ksppinm name,<br /> decode(bitand(ksppiflg/256,1),1,'TRUE','FALSE') sesmod,<br /> decode(bitand(ksppiflg/65536,3),<br /> 1,'IMMEDIATE',<br /> 2,'DEFERRED',<br /> 3,'IMMEDIATE',<br /> 'FALSE') sysmod,<br /> ksppdesc description<br />from sys.x_$ksppi x<br />where x.inst_id = userenv('Instance')<br />and translate(ksppinm,'_','#') like '#%'<br />order by 1 <br /></pre><br />
Oracle
2002-07-15T20:55:33Z
tommy
-
這事是誰做的? 快點過來自首吧!
https://blog.teatime.com.tw/1/post/10
我想各位都應該有那種資料被改了或被砍了, 但是沒有人要承認是他做的, 或者是那個程式設計師不小心寫錯程式造成的, 這時, 老闆就會問你, 這到底是誰做的?<p>以前, 為了這個問題, 我們可能會在程式中加上一堆稽核的記錄, 記下一堆又臭又長的資料, 但是真的發生問題時, 找起來又不一定找的到罪魁禍首... 我記得每次用到最後, 都會把這部份的功能關掉, 因為實在是沒什麼作用.<br /><br />現在, 利用 ORACLE 所提供的 LOGMNR 的功能, 我們可以輕易的找到兇嫌了. <br /><br />ORACLE 為了要做到 crash 時, 能夠由備份資料回復到之前的狀態, 所以對於每一筆交易, 都會有記錄. 這些會存放在所謂的 archived log 之中, 在以前, 這個 log 的檔案, 只能用來做為 recovery 使用. 但是現在, 我們也可以透過 ORACLE 所提供的功能來查詢裡面的內容, 這個功能在 ORACLE 中叫做 LOGMNR.<br /><br />要做這件事, 我們需要保留兩種檔案, 第一種當然是 archived log, 因為所有的交易記錄都放在這類的檔案中. 另一種就是字典檔, 因為在 log 中並不存放物件的名稱, 為了要讓產生的資料容易讀取, 必須要有字典檔來做對應.<br /><br />Archived log 會隨著系統的交易而增加, 所以你必須決定要保留多久, 這個視你的需求而定, 以我們這兒為例, 原本保留一個月, 現在改成兩個月, 當然, 只要你的硬碟空間足夠, 要留多久就可以留多久.<br /><br />字典檔就必須自己產生, 有兩種方式, 一種是存到 ORACLE 的 control 檔案中, 一種是存放指定的檔案中. 為了日後的查詢方便, 我們採用的是存到另外的檔案. 每天會產生一個新的字典檔, 與 archived log 一樣, 保留下來, 以便於日後查詢使用.<br /><br />產生字典檔的方法如下:</p><pre># 今天的日期<br />TODAY=`date +%Y%m%d`<br /><br />sqlplus "/ as sysdba" <<EOF<br />execute dbms_logmnr_d.build('${ORACLE_SID}_dictionary.ora', '/db/dictionary/${TODAY}', <br /> options => dbms_logmnr_d.store_in_flat_file);<br />exit<br />EOF <br /></pre><p>上面的指令會產生一個字典檔放在 /db/dictionary/20020101 之類的路徑之中. 請注意上面的 execute 指令, 與下面那行是同一行, 請勿換行.</p><p>有了交易記錄檔與字典檔之後, 我們就可以查詢交易的內容了. 不過... 每日的交易檔可能數量是很可觀的, 以我們這兒來說, 所定的每個交易檔的大小為 1MB, 每天約有 1000 個上下的交易檔產生, 要找起來實在不是一件小工程. :-(<br /><br />我們以下面的例子來說明:<br /><br />假定我們要查的交易是在 arch0000093355.arc 這個交易記錄檔中, 就在 sqlplus 中執行下面的指令:</p><pre>execute DBMS_LOGMNR.ADD_LOGFILE('/log/arch0000093335.arc', dbms_logmnr.NEW); <br /></pre><p>如果還有其他的交易記錄檔, 如 arch0000093336.arc, 可以用下面的指令加上:</p><pre>execute DBMS_LOGMNR.ADD_LOGFILE('/log/arch0000093336.arc', dbms_logmnr.ADDFILE); <br /></pre><p>依此類推, 你可以一次加上一堆記錄檔, 我通常習慣是每天的檔案都放在一起查...</p><p>把所有的交易記錄檔都加上之後, 就執行下面的指令啟動 LOGMNR 的功能: </p><pre>execute dbms_logmnr.start_logmnr(DictFileName =>'/log/ORCL_dictionary.ora'); <br /></pre><p>後面那個檔案就是你存下來的字典檔. 這個指令有另外的參數可以使用, 例如我們如果只要查詢有 commit 的交易時, 可以使用:</p><pre>execute dbms_logmnr.start_logmnr(DictFileName =>'/log/ORCL_dictionary.ora',<br /> options => dbms_logmnr.COMMITTED_DATA_ONLY); <br /></pre><p>請注意上面的 execute 指令, 與下面那行是同一行, 請勿換行. 其他的參數, 可以參考 ORACLE 的文件說明.</p><p>這個動作可能會很久, 等做完之後, 系統就會有一個 v$logmnr_contents 可以查詢. <br /><br />v$logmnr_contents 這個 view, 比較常用的欄位有:</p><ul><li>scn: 系統變更代碼</li><li>timestamp: 時間</li><li>username: 使用者名稱 (ORACLE 的使用者)</li><li>row_id: 指令所異動到的資料的 ROWID.</li><li>session#: 執行指令的 session 號碼.</li><li>serial#: 執行指令的 serial 號碼.</li><li>sql_redo: 執行的指令.</li><li>sql_undo: 回復的指令.</li><li>session_info: 這個 session 的資料. (可能是空的, 或許要查更早之前的 log, 看看這個 session 什麼時候登入的, 在登入後的那幾筆交易可以由這個看出那一個機器連上來的, 使用那個 OS 的使用者. <br /></li></ul><p>直接使用 select 指令查詢相關的內容, 就可以得知在何時誰做了什麼事情... 例如, 有人下了 delete 指令, 我們可以查詢:</p><pre>select session_info, sql_redo from v$logmnr_contents<br />where sql_redo like 'delete%'; <br /></pre><p>這個查詢會把這些交易記錄中所有 delete 開頭的指令取出來.</p><p>查詢後執行下面的指令, 結束 LOGMNR 的運作:</p><pre>execute dbms_logmnr_end_logmnr();</pre><p>查詢的技巧... 自己多試試就知道了, 你也可以 create 另一個 table, 把這個 view 的資料先存過去, 再來查詢, 當資料多的時候, 可能會比較方便一些.</p><p>最後... 要提的就是, 雖然可以知道那一個使用者在那一台機器, 那個時間做了這件事, 但是實際上... 還是有人要說不是他做的... 說可能有人用他的密碼, 在他的機器上做, 或者他開機後離開位子, 不曉得誰過來用他的電腦... 這些事情, 已經不是電腦可以處理的了, 應該歸於行政管理上面的要求.<br /><br />請所有的使用者, 不要用太簡單的密碼, 也不要讓別人知道你的密碼, 在離開位子的時候, 也請將電腦的畫面鎖住... 否則, 這事就算在你的頭上.<br /><br />另外, 在 ORACLE 9.0.1.x 的版本中 (到 9.0.1.3 為止), 這個功能有點問題, 可能會造成你在 select 這個 view 的時候, 造成 ORACLE hang 住, 或產生 core dump. 這個問題據說已經被修正, 但無法提供單一的 patch, 所以到等到 9.0.1.4 版本才可以使用, 或者是使用 9.2.0.1 這個版本也可以.<br /><br />我們這兒的解決方法就是裝一套 ORACLE 9.2.0.1 專門來處理這個問題.<br /><br />PS. 在 ORACLE 9.0.1.4 推出後, 在 LOGMNR 的查詢時, 仍然會有問題. 且... 9.0.1 的版本在 9.0.1.4 之後就不會有新的版本推出了, 所以如果要使用 LOGMNR, 就必須使用 9.2 的版本才可以.</p><p> </p>
Oracle
2002-07-05T21:29:59Z
tommy
-
是誰鎖住了我的資料 ?
https://blog.teatime.com.tw/1/post/7
雖然我們都會要求程式設計師在處理資料時, 不能造成資料鎖定過長的時間, 也要求一定不能忘了要做 commit 的動作. 但是在實務上, 仍然有許多時候會發現, 他們真的會忘了 commit 這件事.... 這時候, 如果一不小心, 可能你下個指令要去異動這筆資料時, 就會發現你的程式不動了, 被鎖住等待對方做 commit 或 rollback...<p> 如果發生資料鎖定的情形... 要如何得知是誰造成的, 就很重要了...<br /> <br /> ORACLE 有一些 view 可以查詢 lock 的情形, 如 v$lock, v$locked_object 等等, 我們可以透過這些 view 來查詢.<br /> <br /> 下面這個方法是很直覺的一個方法, 我以前就是用這個方法查詢:</p><pre>select b.object_name obj_name,<br /> d.ctime time,<br /> to_char(d.lmode) l,<br /> to_char(d.request) r,<br /> a.os_user_name os_user,<br /> c.machine machine,<br /> c.program program,<br /> a.session_id s_id,<br /> c.serial# s_serial,<br /> a.oracle_username ora_user,<br /> a.object_id obj_id,<br /> a.process pid<br />from v$locked_object a, all_objects b, v$session c, v$lock d<br />where a.object_id=b.object_id<br />and a.session_id=c.sid<br />and a.session_id=d.sid<br />and d.type='TX'<br />order by b.object_name, d.ctime desc, a.session_id<br /></pre><p>但是, 後來發現, 這個動作實在是太慢了, 在系統忙碌的時候, 做一次查詢會很慢, 也會影響到線上的使用者, 所以上網查了一下, 目前使用下面的指令, 可以很快的查詢到需要的結果, 也不會造成系統資源的過度使用:</p><pre>select /*+ ordered */<br /> --b.kaddr,<br /> c.sid,<br /> c.serial#,<br /> b.ctime,<br /> lock_waiter.waiting_session,<br /> lock_blocker.holding_session,<br /> c.program,<br /> c.osuser,<br /> c.machine,<br /> c.process,<br /> decode(u.name,<br /> null,'',<br /> u.name||'.'||o.name<br /> ) object,<br /> c.username,<br /> decode<br /> (<br /> b.type,<br /> 'BL', 'Buffer hash table instance lock',<br /> 'CF', 'Control file schema global enqueue lock',<br /> 'CI', 'Cross-instance function invocation instance lock',<br /> 'CU', 'Cursor bind lock',<br /> 'DF', 'Data file instance lock',<br /> 'DL', 'direct loader parallel index create lock',<br /> 'DM', 'Mount/startup db primary/secondary instance lock',<br /> 'DR', 'Distributed recovery process lock',<br /> 'DX', 'Distributed transaction entry lock',<br /> 'FS', 'File set lock',<br /> 'IN', 'Instance number lock',<br /> 'IR', 'Instance recovery serialization global enqueue lock',<br /> 'IS', 'Instance state lock',<br /> 'IV', 'Library cache invalidation instance lock',<br /> 'JQ', 'Job queue lock',<br /> 'KK', 'Thread kick lock',<br /> 'LA','Library cache lock instance lock (A..P=namespace);',<br /> 'LB','Library cache lock instance lock (A..P=namespace);',<br /> 'LC','Library cache lock instance lock (A..P=namespace);',<br /> 'LD','Library cache lock instance lock (A..P=namespace);',<br /> 'LE','Library cache lock instance lock (A..P=namespace);',<br /> 'LF','Library cache lock instance lock (A..P=namespace);',<br /> 'LG','Library cache lock instance lock (A..P=namespace);',<br /> 'LH','Library cache lock instance lock (A..P=namespace);',<br /> 'LI','Library cache lock instance lock (A..P=namespace);',<br /> 'LJ','Library cache lock instance lock (A..P=namespace);',<br /> 'LK','Library cache lock instance lock (A..P=namespace);',<br /> 'LL','Library cache lock instance lock (A..P=namespace);',<br /> 'LM','Library cache lock instance lock (A..P=namespace);',<br /> 'LN','Library cache lock instance lock (A..P=namespace);',<br /> 'LO','Library cache lock instance lock (A..P=namespace);',<br /> 'LP','Library cache lock instance lock (A..P=namespace);',<br /> 'MM', 'Mount definition global enqueue lock',<br /> 'MR', 'Media recovery lock',<br /> 'NA', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NB', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NC', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'ND', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NE', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NF', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NG', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NH', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NI', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NJ', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NK', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NL', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NM', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NN', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NO', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NP', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NQ', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NR', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NS', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NT', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NU', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NV', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NW', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NX', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NY', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'NZ', 'Library cache pin instance lock (A..Z=namespace)',<br /> 'PF', 'Password File lock',<br /> 'PI', 'Parallel operation locks',<br /> 'PS', 'Parallel operation locks',<br /> 'PR', 'Process startup lock',<br /> 'QA','Row cache instance lock (A..Z=cache)',<br /> 'QB','Row cache instance lock (A..Z=cache)',<br /> 'QC','Row cache instance lock (A..Z=cache)',<br /> 'QD','Row cache instance lock (A..Z=cache)',<br /> 'QE','Row cache instance lock (A..Z=cache)',<br /> 'QF','Row cache instance lock (A..Z=cache)',<br /> 'QG','Row cache instance lock (A..Z=cache)',<br /> 'QH','Row cache instance lock (A..Z=cache)',<br /> 'QI','Row cache instance lock (A..Z=cache)',<br /> 'QJ','Row cache instance lock (A..Z=cache)',<br /> 'QK','Row cache instance lock (A..Z=cache)',<br /> 'QL','Row cache instance lock (A..Z=cache)',<br /> 'QM','Row cache instance lock (A..Z=cache)',<br /> 'QN','Row cache instance lock (A..Z=cache)',<br /> 'QP','Row cache instance lock (A..Z=cache)',<br /> 'QQ','Row cache instance lock (A..Z=cache)',<br /> 'QR','Row cache instance lock (A..Z=cache)',<br /> 'QS','Row cache instance lock (A..Z=cache)',<br /> 'QT','Row cache instance lock (A..Z=cache)',<br /> 'QU','Row cache instance lock (A..Z=cache)',<br /> 'QV','Row cache instance lock (A..Z=cache)',<br /> 'QW','Row cache instance lock (A..Z=cache)',<br /> 'QX','Row cache instance lock (A..Z=cache)',<br /> 'QY','Row cache instance lock (A..Z=cache)',<br /> 'QZ','Row cache instance lock (A..Z=cache)',<br /> 'RT', 'Redo thread global enqueue lock',<br /> 'SC', 'System commit number instance lock',<br /> 'SM', 'SMON lock',<br /> 'SN', 'Sequence number instance lock',<br /> 'SQ', 'Sequence number enqueue lock',<br /> 'SS', 'Sort segment locks',<br /> 'ST', 'Space transaction enqueue lock',<br /> 'SV', 'Sequence number value lock',<br /> 'TA', 'Generic enqueue lock',<br /> 'TS', 'Temporary segment enqueue lock (ID2=0)',<br /> 'TS', 'New block allocation enqueue lock (ID2=1)',<br /> 'TT', 'Temporary table enqueue lock',<br /> 'UN', 'User name lock',<br /> 'US', 'Undo segment DDL lock',<br /> 'WL', 'Being-written redo log instance lock',<br /> b.type<br /> ) lock_type,<br /> decode<br /> (<br /> b.lmode,<br /> 0, 'None', /* Mon Lock equivalent */<br /> 1, 'Null', /* N */<br /> 2, 'Row-S (SS)', /* L */<br /> 3, 'Row-X (SX)', /* R */<br /> 4, 'Share', /* S */<br /> 5, 'S/Row-X (SRX)', /* C */<br /> 6, 'Exclusive', /* X */<br /> to_char(b.lmode)<br /> ) mode_held,<br /> decode<br /> (<br /> b.request,<br /> 0, 'None', /* Mon Lock equivalent */<br /> 1, 'Null', /* N */<br /> 2, 'Row-S (SS)', /* L */<br /> 3, 'Row-X (SX)', /* R */<br /> 4, 'Share', /* S */<br /> 5, 'S/Row-X (SSX)', /* C */<br /> 6, 'Exclusive', /* X */<br /> to_char(b.request)<br /> ) mode_requested<br />from v$lock b,<br /> v$session c,<br /> sys.user$ u,<br /> sys.obj$ o,<br /> (select * from sys.dba_waiters) lock_blocker,<br /> (select * from sys.dba_waiters) lock_waiter<br />where b.sid = c.sid<br />and u.user# = c.user#<br />and o.obj#(+) = b.id1<br />and lock_blocker.waiting_session(+) = c.sid<br />and lock_waiter.holding_session(+) = c.sid<br />and c.username != 'SYS'<br />order by ctime desc, object, kaddr, lockwait<br /></pre><br /><p> </p>
Oracle
2002-07-04T20:49:53Z
tommy
-
使用 RMAN 建立 STANDBY DATABASE 的方式
https://blog.teatime.com.tw/1/post/6
由於硬體成本下降的關係, 對於一些公司來說, 另外裝設一個 STANDY DATABASE 來說, 所花費的硬體成本與得到的好處相比, 這個費用實在不算什麼, 畢竟如果原本的資料庫上面的硬體有了問題, 導致資料檔案無法使用, 或者連作業系統都無法開機時, 可以很輕鬆的在一分鐘之內, 就轉由 STANDBY DATABASE 來取代.<p>如果只是做一般的備份, 真的要回復時, 安裝加上回復的時間, 對於一些公司來說, 這個損失可能更大.<br /> <br /> 所以... 如果可能, 我建議你使用 STANDBY DATABASE.<br /> <br /> 如果你的資料庫很小的時候, 製作一個 STANDBY DATABASE 可以說是十分容易, 因為只要將資料庫停下來, 把檔案複製一份就可以做到. 但是如果你的資料庫很大時, 這個動作就不是一件容易的事情.<br /> <br /> 舉例來說, 我們目前線上的資料庫, 檔案超過 100G, 如果是要傳到另一台機器, 可能要一個小時以上. 問題是... 有這麼大的資料庫的系統, 通常不能允許停機這麼久, 所以傳統的方式很難產生出另一個 STANDBY DATABASE.<br /> <br /> 現在, 我們可以利用 RMAN 來產生另一個 STANDBY DATABASE 所需要的檔案, 又不用將資料庫停下, 可以在線上作業. (當然, 做這個動作時, 可能資料庫的反應會因為 I/O 的關係變的較慢, 但至少不用停機來處理)<br /> <br /> 下面就是使用的方式:</p> <ul> <li>使用 RMAN 將原本資料庫備份.</li> </ul><pre>rman target / nocatalog <<EOF<br />run {<br /> allocate channel d1 type disk;<br /> backup incremental level 0 format '/misdb/backup/df_%U' database<br /> maxsetsize 2000M include current controlfile for standby;<br /> sql "alter system archive log current";<br />}<br />exit<br />EOF</pre><ul><li>使用 SQLPLUS 建立一個 STANDBY 使用的 CONTROL FILE.</li></ul><pre>sqlplus "/ as sysdba" <<EOF<br />alter database create standby controlfile as '/misdb/backup/standby.ctl';<br />exit<br />EOF</pre><ul> </ul> <ul><li>將產生的檔案複製到 STANDBY 的機器上. 使用相同的路徑結構.</li></ul><ul> </ul> <ul> <li>設定 STANDBY DATABASE 的 init.ora, tnsnames.ora, orapwd... 之類的檔案. (可以由原資料庫中複製過來使用)</li> </ul> <ul> <li>使用 SQLPLUS 將 STANDBY DATABASE 啟動在 nomount 狀態.</li> </ul><pre>sqlplus "/ as sysdba" <<EOF<br />startup nomount pfile=<init.ora><br />exit<br />EOF</pre> <ul><li>執行 RMAN 產生 STANDBY DATABASE.</li></ul><pre>rman target sys/sys_pwd@prod_db auxiliary / nocatalog <<EOF<br />run {<br /> allocate auxiliary channel dup1 type disk;<br /> allocate auxiliary channel dup2 type disk;<br /> duplicate target database for standby<br /> nofilenamecheck<br /> dorecover;<br />}<br />exit<br />EOF</pre><ul> </ul>整個作業大致完成.
Oracle
2002-07-04T20:22:34Z
tommy