修改系統時間對oracle的影響

531968912發表於2018-04-01
http://blog.csdn.net/dodola/article/details/223235


修改系統時間對於資料庫本身沒有什麼影響,資料庫是已scn號來記錄。



Oracle DB 伺服器 系統時間修改問題 與 SCN 關係的深入研究Oracle DB 伺服器 系統時間修改問題 與 SCN 關係的深入研究

            
 論壇裡一個朋友說將DB 伺服器系統時間往往後修改了3個月(從11年改成10年),啟動DB報600的錯誤。 

一. 先做個測試
1.1 關閉DB
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.

1.2 修改系統時間
1.2.1 現在時間
[root@singledb ~]# date
Tue Jan 25 11:05:32 EST 2011

1.2.2 修改時間
將時間往前調整一下:
[root@singledb ~]# date -s 1/1/2011 
Sat Jan 1 00:00:00 EST 2011
[root@singledb ~]# date
Sat Jan 1 00:00:22 EST 2011

1.3啟動DB
SQL> startup
ORACLE instance started.
Total System Global Area 360710144 bytes
Fixed Size 1219424 bytes
Variable Size 117441696 bytes
Database Buffers 239075328 bytes
Redo Buffers 2973696 bytes
Database mounted.
Database opened.

啟動並沒有問題,也沒有遇到網友的600錯誤。

二. SCN 
 在這裡先對SCN 的知識做下說明。之前的blog裡也有說明:
 RedoLog Checkpoint 和 SCN關係
 http://blog.csdn.net/tianlesoftware/archive/2010/01/24/5251916.aspx


 SCN是當Oracle資料更新後,由DBMS自動維護去累積遞增的一個數字。 當一個事務commit時,LGWR會將log buffer寫入redo log file,同時也會將該事務的 SCN同步寫入到redo log file內(wait-until-completed)。因此當你commit transaction時, 在成功的訊息返回之前,LGWR必須先完整的完成上述行為之後,否則你是看不到提交成功的響應訊息。

系統時間標記與scn 之間存在一張表,即SYS 下的SMON_SCN_TIME。

SQL> desc sys.smon_scn_time
名稱 是否為空? 型別
----------------------------------------- -------- ---------------------------
THREAD NUMBER
TIME_MP NUMBER
TIME_DP DATE
SCN_WRP NUMBER
SCN_BAS NUMBER
NUM_MAPPINGS NUMBER
TIM_SCN_MAP RAW(1200)
SCN NUMBER
ORIG_THREAD NUMBER

 每隔5 分鐘,系統產生一次系統時間標記與scn 的匹配並存入SYS.SMON_SCN_TIME 表(由SMON 程式來進行Update操作),該表中記錄了最近1440個系統時間標記與scn 的匹配記錄,由於該表只維護了最近的1440 條記錄,即最近5 天內的記錄。

 對 系統時間標記與scn 的每5 分鐘匹配一次 做個說明,比如:
 SCN:339988 對應 2011-01-25 17:00:00
 SCN:339989對應2011-01-25 17:05:00,
 當查詢2011-01-25 17:00:00 到2011-01-25 17:04:59 這段時間點內的SCN時,oracle 都會將其匹配為SCN:339988。


檢視SCN 和 timestamp 之間的對應關係:
select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss') from sys.smon_scn_time order by 2;


查詢目前系統最新的SCN:
 select dbms_flashback.get_system_change_number from dual;

timestamp 與 SCN 互換的2個方法:
select timestamp_to_scn(to_date('2011-01-25 12:10:00','yyyy-mm-dd hh24:mi:ss')) from dual;

select scn_to_timestamp(351277605) from dual;


在Metalink 搜到一篇Timestamp與SCN 之間對映關係的文章,原文參考:
 How to map SCN with Timestamp before 10g [ID 365536.1]
 http://blog.csdn.net/tianlesoftware/archive/2011/01/25/6163757.aspx

 However, in earlier releases, while there is a system object - SYS.SMON_SCN_TIME that will provide the SCN to TIME mapping information. There is no conversion facility provided. 

 SYS.SMON_SCN_TIME will have a maximum of 1440 rows and each record will be for a 5 minute period. Oracle maintains this information for maximum of 5 days after which the records will be recycled.

This means that data is stored 12 times per hour * 24 hours * 5 days=1440 rows. 

SCN value is stored internally as :
i. SCN_wrap
ii. SCN_base

 Whenever the SCN is incremented, the BASE component is incremented first unil it reaches it maximum. Once the BASE reaches the maximum value allowed, it is initialized to zero again after incrementing the WRAP by 1.
--開始時WRAP 為0,即SCN_WRP=0. 當BASE增長到最大值後,SCN_BAS變為0. 同時SCN_WRP 增長到1

Using this logic, we can calculate the timestamp of the SCN as follows:
(SCN_WRP * 4294967296) + SCN_BAS should give us the SCN in the number format
--SCN 的計算公式,這裡我們看出SCN 是根據SCN_BAS計算出來的。和系統時間是沒有關係的。 只是方便我們來進行操作,如閃回恢復,而將SCN 和 系統時間每隔5分鐘進行一次對映。 對映完後,由SMON程式將對映關係寫入SMON_SCN_TIME表。 可以把SCN 看成是Oracle 內部的時間。

To get the time/date for an SCN value in 9i, use the following example:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

-- (a) Get the current SCN base.
SQL>select max(scn_bas) SCN_BASE from smon_scn_time;

1603342197

--(b) Get the complete SCN and the timestamp.
SQL> alter session set NLS_DATE_FORMAT='DD-MON-YY HH:MI:SS';

SQL> select time_dp TIMESTAMP, scn_wrp*4294967296+SCN_bas SCN from smon_scn_time where scn_bas='1603342197';

TIMESTAMP SCN
------------------ ----------
28-JUL-06 05:31:08 8252235517813

這篇文章將的是10g之前的。 在metalink上搜了半天,只找到一條區別,就是11g下smon_scn_time 儲存的記錄可以超過1440條。

在這裡插一句,10g的g 表示Grid. 


三. 修改系統時間與SCN 關係
 透過前面2節的分析,可以看出修改系統時間和SCN沒有直接的關係。在第一節中也做了測試。 對於DB 伺服器如何修改時間:
 (1)停止應用
 (2)停止資料庫
 (3)修改時間
 不過,如果不是特殊情況,不建議修改。穩定第一。尤其是RAC 環境,對時間要求更嚴格。

 在這裡說了,修改系統時間和SCN 沒有直接影響,但我在測試中,發現他們是有聯絡的。

SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
Session altered.

SQL> select sysdate from dual;
SYSDATE
-------------------
2010-01-01 01:21:58

SQL> select * from ( select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss') time from sys.smon_scn_time order by 2 desc) where rownum<10;
 SCN TIME
---------- -------------------
 943223 2012-01-01 02:43:33
 943058 2012-01-01 02:38:14
 942811 2012-01-01 02:33:02
 922652 2012-01-01 00:01:52
 922182 2012-01-01 00:00:45
 920862 2011-01-25 11:46:21
 920717 2011-01-25 11:41:17
 920571 2011-01-25 11:36:38
 919996 2011-01-25 11:31:21
9 rows selected.

SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
 945394

從上面的幾個查詢結果我們發現二個問題:
(1)smon_scn_time表中的SCN(943223) 小於系統當前的SCN值(945394)。
(2)smon_scn_time表中最後更新時間(2012-01-01 02:43:33)大於系統當前時間(2010-01-01 01:21:58)。

 由此我們推出一個結論:當smon_scn_time最後更新時間大於系統時間時,SMON不會將SCN 與TIMESTAMP的對映結果寫入到sys.smon_scn_time表中。

 如果SCN 與TIMESTAMP的對映不能寫入到smon_scn_time表中,我們就不能進行SCN 與TIMESTAMP轉換,就不能利用timestamp進行相關的操作,如恢復。參考:
 Oracle 不同故障的恢復方案
 http://blog.csdn.net/tianlesoftware/archive/2010/12/30/6106178.aspx


為了驗證上面的結論,我們把系統改成大於smon_scn_time最後更新時間。

SQL> select sysdate from dual;
SYSDATE
-------------------
2012-02-01 00:00:16

SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
 946462

SQL> select * from ( select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss') time from sys.smon_scn_time order by 2 desc) where rownum<10;

 SCN TIME
---------- -------------------
 945872 2012-02-01 00:00:51 
 943223 2012-01-01 02:43:33
 943058 2012-01-01 02:38:14
 942811 2012-01-01 02:33:02
 922652 2012-01-01 00:01:52
 922182 2012-01-01 00:00:45
 920862 2011-01-25 11:46:21
 920717 2011-01-25 11:41:17
 920571 2011-01-25 11:36:38

這次成功寫入smon_scn_time表。由此可見:
(1)系統時間往後改(如從2011年改到2012年),對DB 沒有影響,可能某些應用可能會受影響。
(2)系統時間往前改(如從2011年改到2010年),那麼SMON 不會將SCN 與timestamp寫入smon_scn_time表。

 所以對於生產系統,在系統上線之前就應該校隊好系統時間,本著穩定第一的原則,上線之後就不建議在修改DB 伺服器的時間了。




 
 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25462274/viewspace-2152481/,如需轉載,請註明出處,否則將追究法律責任。

相關文章