青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

tbwshc

tbw

  C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
  95 Posts :: 8 Stories :: 3 Comments :: 0 Trackbacks

常用鏈接

留言簿(4)

我參與的團隊

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

#

摘要:本文主要講述了使用DBGird等ActiveX控件來顯示Access數據庫記錄數據的一般方法。
 
  關鍵字:DBGird控件、ActiveX、Access數據庫

  一、 引言

  隨著數據庫技術的進一步發展,我們在生活、辦公時越來越多地同各式各樣的數據庫前臺程序打著交道,這就要求數據庫前臺程序必須擁有良好的人機界面,使用戶能有一種好的心情方便的同程序進行交互。Microsoft 的Office系列產品之所以能得到廣泛的認同,也是與其良好的人機界面分不開的。數據庫最基本的單位--表包含有若干條數據記錄,而每一條記錄又包含有許多的字段,如何能方便、美觀的將這些數據記錄顯示給用戶,并能方便實用的同用戶進行交互操作便成為一個程序能否為人接受的重要因素了。Microsoft的Access 97/2000在這方面就做的相當不錯,用一個網格式表單容納了表中所有的數據,顯得清晰簡潔。而我們在用Visual C++開發的數據庫前臺程序中如要實現類似的表格就不得不借助于提供的ActiveX控件--DBGrid Control來實現,因為自己重新開發類似的功能無疑是比較困難而又煩瑣的。本文著重對該控件的使用做了介紹。

  二、 程序的設計實現

  本程序采用ODBC接口同Access 2000數據源相連,并將數據庫中的記錄數據通過網格的形式顯示給用戶,并能完成同Access表單類似的諸如添加記錄、刪除記錄等功能。

  在開始編制程序之前首先要通過控制面板的32位ODBC數據源設置我們待操作的后臺Access數據源,建立名稱為"雇員"的系統DSN,并將其指向Employee.mdb。為簡單計,數據庫中有一個"雇員表",內含5個字段:"雇員ID","tb雇員姓名"、"所在部門","職務","備注"等,并預先填充幾條記錄備用。

  在用VC創建工程時,需要在第二步確認提供了對ActiveX控件的支持。需要有后臺數據庫的支持,并通過"DataSource"按扭選擇剛才注冊過的ODBC數據源。此時編譯運行程序,通過工具條上的數據庫導航條可以移動數據庫的記錄指針,說明此時已經同數據庫建立了連接,但由于沒有控件(編輯框或其他)同數據庫的字段相棒定,此時還無法顯示數據庫中的記錄。我們先插入網格控件DBGrid Control,方法如下:

  1)選擇菜單->Project->Add to Project->Components and Controls Gallery

  2)在部件選擇對話框中進入Registered ActiveX Controls

  3)選擇DBGrid Control,單擊Insert按鈕,確認后對類進行配置(可以按默認),我們不做任何修改單擊OK按鈕,插入完成。

  在VC工作區的ResourceView中可以如同使用標準控件一樣將剛添加來的DBGird網格控件拖入到對話框中,并對其屬性進行設置。下面將主要的屬性列表如下:

屬性名稱 說明
Caption 雇員表 設定DBGird控件的網格標題
AllowAddNew True 是否允許添加記錄
AllowDelete True 是否允許刪除記錄
AllowDelete True 是否允許更新記錄
ColumnHeaders True 是否顯示每列的標題
DefColWidth 100 設定每列的寬度
RowHeight 11 設定每行高度
DataSource <Not bound to a DataSource> 設定綁定的數據源
BackColor 0x8000000E 設定網格的背景色

  再次運行程序,可以看到類似Access表格風格的DBGird控件以按我們的屬性設定顯示了出來,但并沒有數據庫記錄的顯示,而且我們注意到剛才設定數據源屬性DataSource時,下拉選項只有<Not bound to a DataSource>一項,而并沒有我們所希望的ODBC數據源"雇員"的存在。所以我們還要繼續添加一些輔助的控件來完成同數據庫源的綁定。用同插入DBGird控件一樣的步驟,插入Microsoft RemoteData Control控件,同樣也要對其屬性進行設置:

屬性名稱 說明
ID IDC_REMOTEDATACTL1 控件ID
Caption 人事管理系統--雇員表 設定導航條的標題
UserName   由于沒有指定用戶及密碼,設為空
Password   同上
SQL SELECT * FROM "雇員表" 待執行的SQL結構化查詢語言

  在RemoteData控件里用SQL語言將ODBC數據源的"雇員表"打開并選取里面的所有字段,也即顯示表里的所有記錄信息。這時再打開DBGird控件的DataSource屬性就會發現下拉條里多了一個"IDC_REMOTEDATACTL1",正是RemoteData的ID號。此次編譯運行程序就在網格控件內顯示了數據源指定表的所有記錄信息,而且可以方便的添加、刪除記錄以及調整字段尺寸等。具體如圖所示:


  運行結果表明,在RemoteData控件的中介作用下實現了DBGird控件同ODBC數據源之間的交互。該程序設計實現過程是可靠、實用的。

  小結

  DBGrid數據網格控件以其短小精悍而深受大家的喜愛,,本文將在VC下使用DBGrid的具體步驟和方法作了簡要地介紹。其它類似的表格控件也可以大致參考這個過程,希望本文能有所啟迪與幫助。在Windows 2000 Professional下,由Microsoft Visual C++ 6.0編譯測試通過。后臺數據源為Microsoft Access 2000。
posted @ 2012-08-05 14:29 tbwshc| 編輯 收藏

前言

在許多視窗應用軟件中,通常要在屏幕上同時顯示若干個子視窗,以顯示同一個文檔的不同部分,或者是在每個視窗中分別顯示不同文檔的內容。為了實現多視窗界面,可以采用MDI(Multiple Document Interface)的多文檔模式進行處理,但是多文檔的應用程序設計與維護相對于單文檔的應用程序而言比較復雜。而且,如果要在屏幕上同時顯示多個子視窗,通常要利用視窗重疊函數進行管理,每個子視窗的位置往往需要用鼠標人為設定,過多的人為干預降低了程序使用的效率。因此,如果能對單文檔視窗做適當的分裂,無疑程序使用者將可以得到更易于操作的接口,數據的顯示也更加直觀和方便。本文通過對單文檔視窗的靜態分裂原理進行分析,實現上述要求。

二分裂視窗的類型

視窗的分裂可分為兩種類型,一是動態分裂,二是靜態分裂。動態分裂可以讓使用者通過拖曳分裂方塊的使用,將視窗分裂。但是,動態分裂最多只可以將視窗分裂為2×2個子視窗,不能進行混合分裂視窗,所有子視窗的屬性和父視窗都是一樣的,而且子視窗的數據通常來源于同一處。而靜態分裂,使用者除了可以調整子視窗的大小和進行混合分裂視窗外,最多可將視窗分裂為16×16個子視窗,每個子視窗可以有各自不同的視圖類(CView),各個子視窗顯示的數據可以來自于不同的數據源。不論是要創建動態分裂視窗還是靜態分裂視窗,都必須要利用MFC的CSplitterWnd類別來完成視窗的分裂。

混合靜態分裂視窗的實現

混合分裂視窗是指在子視窗中進行視窗的再分裂。在MFC的框架下,混合分裂視窗必須完成三件工作:

⑴在視窗框架類別中定義CSplitterWnd控件為其屬性(數據成員)。

⑵重載視窗框架類別中的OnCreateClient函數(CFrameWnd::OnCreateClient),建立靜態分裂子視窗,為靜態分裂子視窗填充視圖。

⑶建立維持各子視窗同步更新的機制。

首先,利用MFC AppWizard生成一個單文檔應用程序,在應用程序的CMainFrame類別中聲明CSplitterWnd類別的數據成員。

其次,重載CMainFrame類別中的OnCreateClient(LPCREATESTRUCT,CCreateContext* pContext)函數。在該函數中利用CsplitterWnd類別的構造函數Create Static(CWnd *pParentWnd,int nRows,int nCols,DWORD dwstyle,UINT nID) 創建混合靜態分裂子視窗,即在Create Static分裂出的子視窗中利用CsplitterWnd類別的控件再一次分裂視窗。

Create Static函數的參數含義為:

·pParentWnd是準備建立靜態分裂視窗的視窗框架控件的指針;

·nRows和nCols是準備建立靜態分裂視窗行數(nRows)與列數(nCols)

因此,創建的靜態分裂子視窗個數為nRows × nCols個,這兩個參數最小不得小于0,最大不可超過16;dwstyle是設定子視窗的形式;nID靜態分裂的代號(ID),此代號預設為AFX_IDW_PANE_FIRST,若靜態分裂視窗位于另一個分裂視窗內時,不可以使用默認值,可以利用CsplitterWnd類別的成員函數IdFromRowCol(int row,int col)獲得。利用CsplitterWnd類別的成員函數Create View (int row,int col,CruntimeClass* pViewClass,SIZE sizeinit,CcreateContext* pContext) 為靜態分裂子視窗填充視圖,在將視圖與子視窗關聯時必須先完成子視窗的創建。

Create View函數的參數含義為:

·row和col是指定準備建立View控件的子視窗,其指定的方式是以表示該子視窗所在的行列位置;

·pViewClass是指定用于建立子視窗View控件的View類別,該類別需要被聲明為Run-Time類別;

·Sizeini是View控件的起始大小;pContext是一個指向記錄應用程序所使用的視窗框架控件、Document控件,以及View控件之變量的指針,此參數在CMainFrame::OnCreateClient函數被調用時傳入,再由該tb函數傳遞給此函數。

·CsplitterWnd類別的成員函數SetColumnInfo(int col,int cxIdeal,int cxMin)和SetRowInfo(int row,int cyIdeal,cyMin)為設置子視窗的寬度和高度,參數cxIdeal和cxMin是指定子視窗的寬度和最小寬度,cyIdeal和cyMin是指定子視窗的高度和最小高度,在使用這兩個函數調整子視窗的大小后還應該使用該類別的成員函數RecalLayout()重新調整視窗框架的布局。如果要設定視窗框架里的活動子視窗,可以通過CsplitterWnd類別的成員函數SetActivePane(int row,int col,CWnd* pWnd=NULL)來完成,該函數指定子視窗的方式有兩種,一是指出子視窗所在的行列,二是傳入指向該子視窗的控件指針。

最后,將視窗分裂成多個子視窗后,整個視窗程序中將存在多個View控件。當在其中一個View控件執行更新操作時,如何讓其它View控件同步更新數據?可以通過文檔類別(CDocument)的UpdateAllViews(CView* pSender,LPARAM lHint,CObject* pHint)成員函數的調用,再由該函數分別調用目前存在于視窗程序中各View控件的On Update函數來完成數據的同步更新。

UpdateAllViews函數的參數含義為:

·pSender是指向引發更新操作的View控件指針,如果傳入NULL表示所有視圖都要執行更新操作;

·lHint是用于傳送更新視圖時,需要傳送的額外信息參數;

·pHint是指向記錄更新視圖所需額外信息的控件。在調用該函數時,將View控件的指針傳入的目的是要告訴該函數該子視圖已經完成數據更新,該函數不需要再調用該子視圖的On Update進行數據更新。


子視圖的動態切換

在多視圖應用程序中,可以通過改變CCreateContext對象的值,來創建更加靈活的視圖,實現多視圖的動態切換。CCreateContext是MFC框架所使用的一種數據結構,它將構成文檔/視圖結構的組件聯系起來。這個結構包括指向文檔的指針、視窗框架的指針、視圖的指針以及文檔模板的指針,它還包含一個指向CRuntimeClass結構的指針,以指明所創建的視圖的類型。

其數據成員如下:

·m_pNewViewClass是指向創建上下文的視圖的CRuntimeClass結構的指針;

·m_pNewDocTemplate是指向與視窗框架的創建相聯系的文檔模板的指針;

·m_pCurrentDoc是指向文檔對象的指針,以和新視圖tb聯系起來;

·m_pLastView是指向已存在的視圖的指針,它是新產生的視圖的模型;

·m_pCurrentFrame是指向已存在的視窗框架的指針,它是新產生的視窗框架的模型。

此外,任何一個從CObject類別繼承而來的子類別,在使用宏DECLARE_DYNAMIC、DECLARE_DYNCREATE、DECLARE_SERIAL三個中的任意一個時都會產生一個CRuntimeClass結構的靜態對象,RUNTIME_CLASS返回的就是這個對象的指針,這個對象包含了其基類和本身在運行時刻的信息。

在單文檔靜態分裂視窗的應用程序中,利用CsplitterWnd類別的成員函數Delete View(int row,int col)可以刪除子視窗的原有視圖,然后再通過該類別的成員函數Create View為子視窗創建新的視圖。但是,創建新視圖前必須初始化創建上下文相關指針,即對CCreateContext結構賦值。值得注意的是,使用Create View函數創建的新視圖不能自動調用視圖類別的成員函數OnInitialUpdate和自動顯示并且激活新視圖,需要人工調用OnInitialUpdate函數和ShowWindow(SW_SHOW) 函數,這些函數的調用都可以通過CsplitterWnd類別的成員函數Get Pane(int row,int col)獲得新視圖的指針來完成。

結束語

在MFC的框架下,混合分裂視窗有多種編程方法,本文只是從CsplitterWnd類別的角度去分析混合靜態分裂視窗的實現方法,希望能給讀者起到拋磚引玉的作用。

posted @ 2012-08-05 14:26 tbwshc| 編輯 收藏

應用程序:一個異步的HTTP服務器的設計

  假設我們要設計一個HTTP服務器,它的設計目標包括:高并發性、精簡(部分支持HTTP/1.1)、支持plug-in結構。在不少場合可能都有這個需求。總體上來說,HTTP服務器可以類比成一個基于多線程的操作系統:OS調度每個工作線程在適當的時候獲得執行,而工作線程提供服務(也就是處理HTTP請求)。在這個基礎上,主要的考慮就是調度粒度的大小,粒度太大的時候并發性會降低,而粒度太小又可能因為任務切換(考慮OS的Context Switching)而導致效率降低,所以這又是一個折衷的結果。類似于Apache(以及其他的HTTP服務器),我們可以把一個HTTP處理過程分為若干個狀態,基于這些狀態可以構造出一個HTTP處理的狀態機。這種情況下,我們就可以把每個狀態的處理作為調度的粒度。一個調度過程就是:一個工作線程從全局的任務隊列里取出一個HTTP_Context結構;根據當前的狀態完成相應處理;然后根據狀態機設置下一個狀態;再放回到全局的任務隊列里。這樣子,若干個HTTP狀態就可以通過這個調度策略構成一個完整HTTP處理過程。顯而易見,一個狀態對于下一個狀態處理的調用都可以認為是異步的。一個HTTP狀態機的設計如下圖所示。

  工作線程的函數其實就是兩個操作:從狀態隊列里取出一個HTTP_Context,調用HTTP_Context的service()函數,周而復此。在這個架構上,就很容易引入異步I/O和Plug-in的機制了。事實上我們也可以使用基于事件(例如select/poll)的I/O策略來模擬異步I/O,實現中使用一個tb用戶線程就可以了。

  對于異步I/O和Plug-in的調用,我們也是采用類似于Linux 2.6里面aio的重試方案,而異步完成的時候采用回調函數。在某個狀態上,如果系統需要I/O操作(recv或者send),則會請求一個異步I/O(操作系統提供的異步I/O或者由用戶線程模擬的異步I/O),這時候相應的HTTP_Context不會重新回到狀態隊列里,而在I/O完成的回調函數里面才會重新放回到狀態隊列,得到重新調度的機會。HTTP_Context得到重新調度的時候會檢查I/O狀態(這個可以通過一些標志位來完成),如果已經完成,則處理然后設置下一狀態,重新調度,否則可以重新請求一個新的I/O請求。Plug-in也可以使用類似的方案,比如說一個Plug-in要跟外部的一個服務器通信,這時候就可以在通信完成的時候才把HTTP_Context重新放回到狀態隊列。顯然,Plug-in跟HTTP狀態是多對多的關系,一個Plug-in可以在若干個關心的狀態注冊自身,同時還可以設置一些short-path來提高處理的效率。

  結論

  總的來說,異步調用的設計和應用歸根結底就是對多個主動對象的管理問題:如何提供執行的動力以及如何保證執行的順序邏輯。主要考慮的問題是主動對象的粒度以及執行方式,同步或者回調來完成順序的調度,或者使用近似的調度而加一些魯棒的錯誤處理機制來保證語義的正確。后者可以考慮在使用基于事件的socket的時候,readable事件的通知可以是冗余的,或者說可以比實際中發生的readable事件更多,這個時候使用非阻塞的socket,有些read()(或者recv())會直接返回EWOULDBLOCK,系統只要考慮處理這種情況(使用non blocking socket而不是blocking socket),當例外的情況不多的時候是可以接受的。這時候可以說事件的報告就只是近似的。
posted @ 2012-08-05 12:47 tbwshc| 編輯 收藏

創建外鍵約束時如果使用Oracle默認的創建方式,在刪除被參照的數據時,將無法被刪除,這一點在Oracle9i中給了我們更多靈活的選擇,我們可是使用on delete cascade和 on delete set null關鍵字來決定刪除被參照數據時是否要將參照這個數據的那些數據一并刪除,還是將那些參照這條數據的數據的對應值賦空。

例如下面這兩個表中分別存的時員工的基本信息和公司的部門信息。我們為

create table dept
(deptno number(10) not null,
deptname varchar2(30) not null,
constraint pk_dept primary key(deptno));

create table emp
( empno number(10) not null,
fname varchar2(20) ,
lname varchar2(20) ,
dept number(10) ,
constraint pk_emp primary key(empno));

然后我們現在分別使用這兩個關鍵字來增加外鍵試一下,首先我們來試一下on deletbe cascade

alter table emp
add constraint fk_emp_dept foreign key(dept) references dept(deptno) on delete cascade;

先增加外鍵。然后插入數據。

insert into dept values(1,’銷售部’);
insert into dept values(2,’財務部’);
insert into emp values (2,’Mary’,'Song’,1);
insert into emp values (3,’Linda’,'Liu’,2);
insert into emp values (4,’Linlin’,'Zhang’,1);

然后現在我要刪除銷售部,會有什么后果呢?

delete from dept where deptno = 1;

我們發現除了dept中的一條數據被刪除了,emp中兩條數據也被刪除了,其中emp中的兩條數據是參照了銷售部的這條數據的,這就很容易理解on delete cascade了。

 

創建外鍵約束時如果使用Oracle默認的創建方式,在刪除被參照的數據時,將無法被刪除,這一點在Oracle9i中給了我們更多靈活的選擇,我們可是使用on delete cascade和 on delete set null關鍵字來決定刪除被參照數據時是否要將參照這個數據的那些數據一并刪除,還是將那些參照這條數據的數據的對應值賦空。

按照上文中介紹的就能夠實現在oracle數據庫中用非默認方式創建外鍵的目的,希望對大家能夠有所幫助。

posted @ 2012-08-04 13:26 tbwshc| 編輯 收藏

現在某家企業的Oracle數據庫中有一張產品信息表。這張表中的記錄已經超過了500萬條。其中成品信息大概30萬條。零件記錄有300萬條左右。剩余的都是包裝信息。數據庫工程師通過相關的分析與監測,用戶訪問這張表的時候,會有嚴重的等待現象。這主要是因為這張表中的數據存放在同一塊硬盤上。當不同的用戶并發訪問這張表時,會因為磁盤I/O性能的瓶頸,而導致等待。如下圖所示。當各位讀者遇到這種情況,該如何采取措施來優化性能呢?筆者這里的建議是采用Oracle分區表減少磁盤的I/O沖突,改善數據庫的性能。

一、分區表的原理與優勢。

分區表對于提高大表的訪問性能會有很大的幫助。如上圖所示,可以將一張產品信息表分按產品類別分為三個部分,分別為成品信息、零件信息和原材料信息。然后將這三部分對應一個單獨的分區,并將它們存放在不同的硬盤上。此時當不同的用戶訪問不同的信息時,就可以有效的降低磁盤的I/O沖突。即使是同一個用戶,需要同時訪問這三部分信息,如產品的物料清單時,由于其分別從不同的硬盤中讀取數據,為此也可以明顯的降低磁盤I/O沖突。

所以分區的基本原理就是通過訪問一個表或者索引的較小片斷,而不是訪問整個表和索引,以提高數據庫的性能。當然這有一個前提條件,需要將一個表的不同分區放置在不同的磁盤上,此時磁盤整體的吞吐量就會成倍上升。

采取分區,不僅可以提高用戶訪問時的性能,而且還可以提高備份時的靈活性。如上面這個例子,將產品信息根據其類別分為不同的區,并將它們保存在不同的硬盤上。此時就可以對各自的分區進行單獨的備份。如最近因為國家環保的要求,tb原材料信息進行了大規模的調整。此時就可以對原材料信息所在的分區數據進行單獨的備份。這不僅可以減少備份的時間,而且可以降低備份作業過程中出現的I/O沖突問題。

一般來說,分區表的優勢有一個前提,就是需要將分區數據放置在不同的磁盤上。如果不這么做的話,那么分區往往很難起到降低磁盤I/O的效果。所以為了最大程度的降低一個大表的磁盤I/O(特別是經常會有并發行的訪問),此時應該將表分割到多個分區上。然后再將這些分區存放在不同的磁盤上。

二、分區表模式的選擇。

那么該如何對表進行分區呢?這又是一個比較關鍵的問題。根據經驗,筆者認為要讓分區取得更好的效果,分區表模式的選擇至關重要。也就是說,按什么內容對表進行分區管理。有時候,先同的數據,采取不同的分區表模式,往往會有不同的效果。在下面的內容中,筆者會結合企業實際應用的情景,對分區表模式的選擇進行舉例。希望這些內容能夠幫助各位讀者,更好的維護分區表。

第一種模式:按行來進行分區。

上面這個例子中,筆者談到有一張產品信息表,其包括成品信息、零件信息和原材料信息。當這張表的記錄比較多,并且當用戶訪問這張表時已經出現了嚴重的I/O沖突的時候,則就可以根據行記錄來進行分區。如在產品信息表中有一個產品類別的字段。數據庫管理員就可以根據這個字段對標進行分區。具體的分區方法也比較簡單。在建立表的時候,在產品類別字段后加上Partion關鍵字,然后指定按字段的內容進行分區。這個操作比較簡單,筆者就不過多展開了。筆者這里需要強調的是,分區完之后一定要將數據存放在不同的磁盤上,即不同的表空間。否則的話,不能夠起到改善磁盤I/O的效果。

第二種模式:按列來進行分區。

在實際工作中,還有這么一種情況。如現在有一張員工信息表。這這張表中除了包含員工的基本信息,如身份證號碼、姓名、籍貫等內容,還包括員工的身份證復印件或者照片等圖片信息。大家都知道,圖片信息的數據流量是很大的。有可能一張身份證復印件的數據流量相當于幾千條的員工基本信息。而且,當用戶訪問員工信息表的時候,并不是每個時候都需要查看身份證復印件。大部分時候他們可能只是查詢員工的聯系方式或者住址等等。另外,一般身份證復印件等照片不會隨意更改,而員工的聯系方式或這住址等等,則更改比較頻繁。此時如果需要更改員工信息,卻將不需要更改的員工身份證復印件也查詢出來,顯然那這會加重磁盤的I/O沖突。

當企業存在這種情況時,也可以對這個表進行分區。此時分區并不是對行進行分區,而是對列進行分區。如可以將身份證復印件信息或者照片信息分為一個獨立的分區,并將其保存在另外一個硬盤上。這么做,能夠帶來如下的好處。

一是在數據訪問時,可以指定是否需要查詢身份證信息所在的分區。在查詢員工信息的時候,在語句中可以指定從哪個分區中查詢信息。當用戶平時只是查詢員工的聯系方式或者住址時,就不需要訪問身份證復印件所在的分區。如可以使用如下語句查詢:

Select * from ad_user partition(uinfo) –假設員工的基本信息存放在分區Unifo中。

在查詢語句中,使用Partition關鍵字可以指定其查詢的是哪個分區。如果不特指的話,則系統會查詢這個表所對應的全部分區。而指定的話,就只訪問某個特定分區的內容。上面這條語句,就只讀取Uinfo分區中的信息。而不會讀取身份證復印件等相關信息。如此的話,就可以降低磁盤的I/O沖突,減少不必要的數據流量,提高查詢的性能。

二是方便對數據的備份。根據使用習慣,一般身份證復印件或者員工照片等信息不怎么會更改。為此對這些數據的備份頻率可以比較低一點。況且這些信息的容量往往會很大。如果經常對其進行備份,顯然會增加磁盤的I/O負擔。而對于員工的聯系信息或者住址等等,其變化的頻率就會高許多。對這些信息就需要進行經常性的備份。對大表進行分區管理,還有一個很大的優勢就在于可以對各個分區中的數據采取獨立的備份。為此就可以對身份證復印件所在的分區進行單獨的備份,如一個月或者有大的變動時進行備份。而對于其他的信息則可以每天進行備份。這就可以實現在性能與安全方面的均衡。一般來說,在訪問某個表時,如果經常需要訪問的信息只是特定的幾列,而不需要訪問的信息容量比較大,此時就可以采用按列分區的模式。在這種情況下,用戶就可以在查看某個分區內容的時候避免訪問其他分區。同時還可以在不妨礙其它分區的情況下對某個分區的數據進行獨立的備份。

第三種分區模式:散列分區。

有時候某個表可能沒有明顯的分區特征,即不符合上面提到的這些情況。但是表中的記錄又非常的多。在這種情況下,也有必要進行分區。不過此時我們可以讓系統進行隨機的分區。這種分區模式就叫做散列分區。通常情況下,為了提高散列分區的效果,即得到一個比較均勻的分布,往往可以將2的N次方指定為散列分區數。一般來說,N越大,其分布的越均勻。

也就是說,當數據庫管理員不知道該如何對表進行分區時,但確實有分區的必要時,可以使用散列分區。不過筆者需要提醒的是,散列分區其有一個重大的限制。在使用散列分區的時候,僅僅支持本地索引,而不支持其他的索引方式。這一點需要特別的注意。在實際工作中不能夠因為采取了散列分區,而降低或者取消了索引。這往往是得不償失的,不可行。

希望通過上文的學習,大家能夠掌握好利用Oracle分區表來減少磁盤I/O沖突的知識,便于大家在以后的工作中靈活運用。

posted @ 2012-08-04 13:25 tbwshc| 編輯 收藏

下面就介紹一下Oracle手動創建數據庫的步驟:

1、確定新建數據庫名稱和實例名稱;

2、確定數據庫管理員的認證方式;

3、創建初始化參數文件;

4、創建實例;

5、連接并啟動實例;

6、使用create database語句Oracle創建數據庫;

7、創建附加的表空間;

8、運行腳本創建數據字典視圖;

下面以創建一個名為“MYNEWDB”的數據庫為例

1、確定數據庫名稱與實例名稱;

1.DB_NAME=MYNEWDB

2.SID=MYNEWDB

2、確定數據庫管理員的認證方式;

管理員的認證方式包括操作系統認證和口令認證兩種,本例采用操作系統認證

3、創建初始化參數文件;

Oracle提供的初始化參數樣本文件位于$ORACLE_HOME\admin\tbsample\pfile目錄中的initsmpl.ora

我們采用修改樣本的方式,創建參數文件名為:initMYNEWDB.ora,存放在D:\oracle\ora92

1.\database\initMYNEWDB.ora,

主要內容設置如下:

共享服務器設置

1.dispatchers="(PROTOCOL=TCP)(SERVICE=MYNEWDBXDB)

數據庫實例名設置

1.instance=MYNEWDB

安全與審計設置

1.remote_login_passwordfile=EXCLUSIVE

排序區大小設置

1.pga_aggregate_target=25165824

2.sort_area_size=524288

全局數據庫名設置

1.db_domain=""

2.db_name=MYNEWDB

控制文件設置

1.control_files=("D:\oracle\oradata\MYNEWDB\CONTROL01.CTL",

2."D:\oracle\oradata\MYNEWDB\CONTROL02.CTL",

3."D:\oracle\oradata\MYNEWDB\CONTROL03.CTL")

SGA區設置

1.java_pool_size =33554432

2.large_pool_size=8388608

3.shared_pool_size=50331648

以上的相關內容就是對Oracle創建數據庫的步驟的介紹,望你能有所收獲。

按照上文中介紹的步驟,就能夠實現Oracle手動創建數據庫,希望上文中介紹的內容對大家能夠有所幫助。

posted @ 2012-08-04 13:24 tbwshc 閱讀(753) | 評論 (0)編輯 收藏

Oracle數據庫以其高可靠性、安全性、可兼容性,得到越來越多的企業的青睞。如何使Oracle數據庫保持優良性能,這是許多數據庫管理員關心的問題,根據筆者經驗建議不妨針對以下幾個方面加以考慮。

一、分區

根據實際經驗,在一個大數據庫中,數據空間的絕大多數是被少量的表所占有。為了簡化大型數據庫的管理,改善應用的查詢性能,一般可以使用分區這種手段。所謂分區就是動態表中的記錄分離到若干不同的表空間上,使數據在物理上被分割開來,便于維護、備份、恢復、事務及查詢性能。當使用的時候可建立一個連接所有分區的視圖,使其在邏輯上仍以一個整體出現。

1.建立分區表
Create table Employee(
EmpNo varchar2(10) primary key,
Name varchar2(30),
DeptNo Number(2)

Partition by range(DeptNo)
(partition PART1 values less than (11)
tablespace PART1_TS,
partition PART2 values less than(21)
tablespace PART2_TS,
partition PART3 valuse less than(31)
tablespace PART3_TS
partition PART4 values less than(MAXVALUE)
tablespace PART4_TS
);

表Employee依據DeptNo列進行分區。

2.分區索引
Create index Employee_DeptNo on Employee (DeptNo)local(
partition PART1 tablespace PART1_NDX_TS,
partition PART2 tablespace PART2_NDX_TS,
partition PART3 tablespace PART3_NDX_TS,
partition PART4 tablespace PART4_NDX_TS,
);

當分區中出現許多事務并且要保證所有分區中的數據記錄的惟一性時采用全局索引,在建立全局索引時,Global子句允許指定索引的范圍值,這個范圍值可以不同于表分區的范圍值。只有建立局部索引才會使索引分區與表分區間建立起一一對應關系。因此,在大多數情況下,應該使用局部索引分區。若使用了此索引,分區就能夠很容易地將索引分區與表分區建立關聯,局部索引比全局索引更易于管理。

3.分區管理
根據實際需要,還可以使用Alter table命令來增加、刪除、交換、移動、修改、重命名、劃分、截短一個已存在分區的結構。

二、重建索引

如果表中記錄頻繁地被刪除或插入,盡管表中的記錄總量保持不變,索引空間的使用量會不斷增加。雖然記錄從索引中被刪除,但是該記錄索引項的使用空間不能被重新使用。因此,如果表變化不定,索引空間量會不斷增加,不論表中記錄數量是否增加,只是因為索引中無效空間會增加。
要回收那些曾被刪除記錄使用的空間,需要使用Alter index rebuild命令。可以做一個定期運行的批處理程序,來重建最活動表的索引。這個批處理程序可以在空閑時運行,以避免該程序與其他應用程序沖突。若能堅持索引的這一程序規劃,便可以及時回收那些未使用空間,提高空間利用率。

三、段的碎片整理

當生成一個數據庫對象時(一個表或一個索引),通過用戶缺省值或指定值來為它指定表空間。一個在表空間中生成的段,用于存儲對象的相關數據。在段被關閉、收縮、截斷之前,段所分配的空間將不被釋放。

一個段是由范圍組成,而范圍是由相鄰的Oracle塊組成。一旦存在的范圍不能再存儲新的數據,這個段就會去獲得新的范圍,但并不要求這些范圍是彼此相鄰的。這樣的擴展會一直繼續下去,直到表空間中的數據文件不能提供更多的自由空間,或者范圍數量已達到極限。

因此,一個碎片太多的數據段,不僅會影響運行,也會引發表空間中的空間管理問題。所以,每個數據段只含有一個范圍是十分有益的。借助監控系統,可以通過檢查DBA_SEGMENTS數據字典視圖來了解哪些數據庫對象含有10個或更多范圍的段,確定其數據段碎片。

若一個段的碎片過多,可用兩種方法解決:
1. 用正確的存儲參數建立一個新表,將舊表的數據插入到新表中,在刪除舊表;
2. 利用Export/Import工具。

如:exp system/manager file=exp.dmpcompress=Y grants=Y indexes=Y
tables=(T1,T2)
若輸出成功,進入Oracle,刪除上述表。
注:compress=Y表示將在輸出過程中修改它們的存儲參數。
imp system/manager file=exp.dmp commit=Y buffer=64000 full=Y

四、自由范圍的碎片整理

表空間中的一個自由范圍是表空間中相連的自由(空間)塊的集合。當一個段關閉時tb,它的范圍將被釋放,并被標記為自由范圍。然而,這些自由范圍再也不能與相鄰的自由范圍合并,它們之間的界線始終存在。但是當表空間的缺省值pctincrease設置不是0時,SMON后臺進程會定期將這些相鄰的自由范圍合作。若pctincrease設置為0,那么相鄰自由范圍不會被數據庫自動合并。但可以使用Alter table命令"coalesce"選項,來強迫進行相鄰自由范圍的合并。

不進行自由范圍合并,在日后的空間請求中,會影響到表空間中的空間分配。當需要一個足夠大的范圍時,數據庫并不會合并相鄰的自由范圍,除非沒有其他選擇。這樣,當表空間中前面較小的自由范圍已被使用時,將使用表空間中后面部分最大的一個自由范圍。結果,會因為沒有足夠多的使用空間,從而導致表空間需求的矛盾。由于這樣的情況出現,使數據庫的空間分配距理想越來越遠。自由空間碎片常會出現在那些經常關閉又重新生成的數據庫表和索引中。

在理想的Oracle表空間中,每一個數據庫對象存儲在一個單獨的范圍中,并且所有有效自由空間集中在一個巨大而連續的范圍中。這樣,在一個對象需要附加存儲空間時,可以在增加獲取足夠大自由空間的可能性的同時,最小化空間中的循環調用,提高自由空間使用率。


posted @ 2012-08-04 13:23 tbwshc| 編輯 收藏

1、DB2 訪問前10行數據與Oracle區別

DB2 :    
select * from test fetch first 10 rows only
Oracle :   
select * from test where rownum<=10
 
查詢語句
Db2:不提供隱形轉換
select * from employee where empno=1010;
oracle:提供隱形轉換
select * from employee where empno='1010';
 
2、DB2 Insert into 與Oracle區別
DB2 允許有類似這樣多行插入:
insert into staff values(1212,'cemy',20,'sales',3,90000,30000);
(1212,'cemy',20,'sales',3,90000,30000); 
oracle:
SQL>  insert into staff values(1212,'cemy',20,'sales',3,90000,30000),(1212,'cemy'
,20,'sales',3,90000,30000)
                                                    
3、DB2 Update 與Oracle Update
Db2
DB2 update staff set (salary,comm)=(80000,50000);
DB2 update staff set salary=80000,comm=50000;
Oracle:
SQL> update staff set salary=80000,comm=50000;
已更新 1 行。I
4、取得系統日期
Oracle:
Select sysdate from dual;
DB2:
Select current timestamp from sysibm.sysdummy1;
 
5、轉換日期時間到字符類型:
Oracle  
TO_CHAR(date_expression_r_r, 'YYYY-MM-DD')  
TO_CHAR(date_expression_r_r, 'HH24:MI:SS')  
DB2  
CHAR(date_expression_r_r,ISO)  
CHAR(time_expression_r_r,ISO) 
 
6、轉換日期時間字符串到日期時間類型:
Oracle  
TO_CHAR(date_expression_r_r, 'YYYY-MM-DD')  
TO_CHAR(date_expression_r_r, 'HH24:MI:SS')  
DB2  
DATE('2005-05-20')  
TIME('18:59:59')  
TIEMSTAMP('2007-2-1', '21:12:12')  
TIEMSTAMP('2007-2-1 21:12:12')
 
DB2也有TO_CHAR 和 TO_DATE函數,但只能提供固定的轉換格式,如下
TO_CHAR (timestamp_expression_r_r,'YYY-MM-DD HH24:MI:SS')  
TO_DATE (string_expression_r_r, 'YYY-MM-DD HH24:MI:SS') 
 
 
7、快速清空大表
Oracle:
truncate table TableName ;
DB2:
alter table TableName active not logged initially with empty table;
 
8、創建類似表
Oracle:
create table a as select * from b ;
DB2:
create table a like b ;
 
9、修改字段長度或類型:
ORACLE:
ALTER TABLE NODES MODIFY NODE_NAME varchar(32);
DB2:
alter table NODES ALTER NODE_NAME SET DATA TYPE varchar(32);
 
10、空值處理得到abc
Oracle:
SELECT 'abc' || c1 FROM t1 (c1 IS NULL)  
DB2 :
SELECT 'abc‘ || COALESCE(c1,'') FROM t1 
 
11、創建 indexes 
Oralce:
Create TABLE T1 .............IN DATA_TA
Create Index ........ ON T1  ...... IN INDX_TS
 
DB2:
Create TABLE T1 ........ IN DATA_TS INDEX IN INDX_TS
Create INDEX  .....ON T1
 
12、更改列名
oracle :
alter table test rename column mail to mail2;
db2  
不提供更改列名功能(解決辦法同刪除,或者通過建立一個新視圖解決)
13、更改列類型
oracle :alter table test modify column (mail2 integer);
db2    :alter table test alter mail varchar(256) 只可以加寬,不能更改類型
 
14 創建PROCEDURE的參數的區別
1)參數類型和參數名稱的位置不同
db2:
CREATE PROCEDURE PRO1 (IN OrgID int)
oracle:
CREATE PROCEDURE PRO1 (OrgID IN int)
2)同時作為輸入輸出參數的寫法不同
db2:   
CREATE PROCEDURE PRO1 (INOUT OrgID int)    INOUT連著寫
oracle:
CREATE PROCEDURE PRO1 (OrgID IN OUT int)    IN OUT中間空格隔開,而且必須IN在OUT之前
3)沒有輸入或輸出參數時
db2:  
CREATE PROCEDURE PRO1 ()    
oracle:
CREATE PROCEDURE PRO1 不能有空的括號
 
變量定義和BEGIN END體的位置不同
        db2中變量定義在BEGIN END體內,并且每個變量都要用DECLARE聲明;存儲過程結束時,END后跟P1,并且不需要分號
        oracle中變量定義必須在BEGIN END體外,變量都不需要用DECLARE聲明(有種說法是,第一個變量需要DECLARE,其他變量不需要);存儲過程結束時,END后跟存儲過程的名稱,并且需要分號        
 db2:
CREATE PROCEDURE PRO1()
 LANGUAGE SQL    
       P1: BEGIN
          --變量定義
           DECLARE INSERT_DATE TIMESTAMP; 
           DECLARE ALLDEPT_NO  VARCHAR(20);
           --具體操作
           SELECT a FROM TAB_1;
                          .........
            END P1
        
oracle:  
CREATE PROCEDURE PRO1
          IS
         --變量定義
         INSERT_DATE TIMESTAMP; 
         ALLDEPT_NO  VARCHAR(20);
          BEGIN
            --具體操作
         SELECT a FROM TAB_1;
                       .........
         END PRO1;
15、控制語句的不同
 db2:    
 IF …THEN ......ELSEIF THEN .... END IF;
 oracle: 
IF …THEN ......ELSIF  THEN .... END IF;
 
16、如何執行腳本SQL文件
Oracle: 
@$PATH/filename.sql; 
DB2:
db2 -tvf $PATH/filename.sql
 
17、查看當前用戶的表和視圖
DB2:
LIST   TABLES 
ORACLE:   
SELECT   *   FROM   TBAB;
 
DB2:DROP   TABLE刪除表和定義。LIST   TABLES發現表不存在了。 
ORACLE:DROP   TABLE刪除表的內容保留表的定義。可以看到表。
 
 
 
 
---------------------------------------------------------------
另外附上今天分享的東西:【快速復制表】
 
1.復制表結構及數據到新表 
CREATE TABLE 新表 SELECT * FROM 舊表 (DB2不適用)
 
2.只復制表結構到新表 
(1)oracle
CREATE TABLE 新表 SELECT * FROM 舊表 WHERE 1=2 
即:讓WHERE條件不成立. 
(2)DB2
CREATE TABLE 新表 LIKE 舊表 
 
3.復制舊表的數據到新表(假設兩個表結構一樣) 
INSERT INTO 新表 SELECT * FROM 舊表 
 
4.復制舊表的數據到新表(假設兩個表結構不一樣) 
INSERT INTO 新表(字段1,字段2,.......) SELECT 字段1,字段2,...... FROM 舊表
posted @ 2012-07-28 12:46 tbwshc 閱讀(956) | 評論 (0)編輯 收藏

java對象的初始化

小冬(珠海)11:02:48
我們知道一個對象可以有靜態變量、變量、靜態初始化塊、初始化塊,當我們創建一個對象時,它是怎么初始化的呢?按什么順序初始化的呢?
 
  1. public class Test { 
  2.  
  3.      
  4.     // 靜態變量 
  5.     public static String staticField = "靜態變量"; // 變量 
  6.     public String field = "變量"
  7.     // 靜態初始化塊 
  8.     static { 
  9.         System.out.println(staticField); 
  10.         System.out.println("靜態初始化塊"); 
  11.     } 
  12.     // 初始化塊 
  13.     { 
  14.         System.out.println(field); 
  15.         System.out.println("初始化塊"); 
  16.     } 
  17.     // 構造器 
  18.     public Test() { 
  19.         System.out.println("構造器"); 
  20.     } 
  21.     public static void main(String[] args) { 
  22.         Test test = new Testb(); 
  23.  
  24.     } 
 
運行下代碼,輸出結果是:
靜態變量
靜態初始化塊
變量
初始化塊
構造器
 
 
由此可以看到,當new一個對象時,它并不是就是調構造方法,而是先初始化屬性變量,我們把變量的定義先后順序換下,再執行,會發現,靜態的是先于非靜態進行實始化的,那么對于靜態變量和靜態初始化塊之間、變量和初始化塊之間的先后順序又是怎樣呢?是否靜態變量總是先于靜態初始化塊,變量總是先于初始化塊就被初始化了呢?
我們先改下代碼:
 
  1. public class Test { 
  2.  
  3.     public static TestA ta = new TestA(); 
  4.     // 靜態變量 
  5.     public static String staticField = "靜態變量"; // 變量 
  6.     public String field = "變量"
  7.     // 靜態初始化塊 
  8.     static { 
  9.         System.out.println(staticField); 
  10.         System.out.println("靜態初始化塊"); 
  11.     } 
  12.     // 初始化塊 
  13.     { 
  14.         System.out.println(field); 
  15.         System.out.println("初始化塊"); 
  16.     } 
  17.     // 構造器 
  18.     public Test() { 
  19.         System.out.println("構造器"); 
  20.     } 
  21.     public static void main(String[] args) { 
  22.         Test test = new Test(); 
  23.  
  24.     } 
  25.  
  26. class TestA { 
  27.     public TestA() { 
  28.         System.out.println("Test--A"); 
  29.     } 
 輸出是:
Test--A
靜態變量
靜態初始化塊
變量
初始化塊
構造器
 
 
靜態變量:static TestA ta = new TestA()在靜態初始化塊前,所以先輸出Test--A
再換下位置,把static TestA ta = new TestA()放到在靜態初始化塊后,我們發現輸出是:
靜態變量
靜態初始化塊
Test--A
變量
初始化塊
構造器
 
 
由此可見這是取決于它們在類中出現的先后順序,同理可得:變量和初始化塊之間也如此,總結可得:初始化優先級是(靜態變量/靜態初始化塊)>(變量/初始化塊)>構造器。
 
 
那繼承關系時的初始化又是怎樣的呢?如下:
大家應該知道,初始化子類時會先初始化父類,再看代碼:
 
  1. public class Test extends Parent{ 
  2.     // 靜態變量 
  3.     public static String staticField = "子類靜態變量"; // 變量 
  4.     public String field = "子類變量"
  5.     // 靜態初始化塊 
  6.     static { 
  7.         System.out.println(staticField); 
  8.         System.out.println("子類靜態初始化塊"); 
  9.     } 
  10.     //public static TestA ta = new TestA(); 
  11.     // 初始化塊 
  12.     { 
  13.         System.out.println(field); 
  14.         System.out.println("子類初始化塊"); 
  15.     } 
  16.     // 構造器 
  17.     public Test() { 
  18.         System.out.println("子類構造器"); 
  19.     } 
  20.     public static void main(String[] args) { 
  21.         Test test = new Test(); 
  22.     } 
  23.  
  24. class Parent{ 
  25.  
  26.     public String field = "父類變量";// 變量 
  27.     public static String staticField = "父類靜態變量"; // 靜態變量 
  28.     // 靜態初始化塊 
  29.     static { 
  30.         System.out.println(staticField); 
  31.         System.out.println("父類靜態初始化塊"); 
  32.     } 
  33.     // 初始化塊 
  34.     { 
  35.         System.out.println(field); 
  36.         System.out.println("父類初始化塊"); 
  37.     } 
  38.     // 構造器 
  39.     public Parent() { 
  40.         System.out.println("父類構造器"); 
  41.     }    
剛才結果應該是:
父類靜態變量
父類靜態初始化塊
子類靜態變量
子類靜態初始化塊
父類變量
父類初始化塊
父類構造器
子類變量
子類初始化塊
子類構造器
 
從結果看到,并不是父類完全初始化完后再進行子類的初始化,子類的靜態變量和靜態初始化塊的初始化是在父類的變量、初始化塊和構造器初始化之前就完成了。
 
我們在main方法再創建一個對象,Test test2 = new Test();
大家就test2的初始化又如何?
 
為了好看,我們子類構造器里加多行代碼System.out.println("***********");
輸出結果:
父類靜態變量
父類靜態初始化塊
子類靜態變量
子類靜態初始化塊
父類變量
父類初始化塊
父類構造器
子類變量
子類初始化塊
子類構造器
***********
父類變量
父類初始化塊
父類構造器
子類變量
子類初始化塊
子類構造器
***********


發現什么了?
靜態變量和靜態代碼塊只加載一次 。
 
 
總結:
一、初始化優先級:
1、靜態變量/靜態初始化塊)>(變量/初始化塊)>構造器
2、父類>子類

二、靜態變量和靜態代碼塊只加載一次,因為它們是全局共享的
 
posted @ 2012-07-28 12:45 tbwshc 閱讀(919) | 評論 (0)編輯 收藏

背景:先前在生產庫上配置了oracle監控,每5分鐘嘗試連接一次數據庫,若連接失敗則通過nagios+fetion自動報警,此配置參考文章:http://ylw6006.blog.51cto.com/470441/787496

早晨收到報警信息后,登陸數據庫執行ps -ef查看oracle的后臺進程都在,使用conn /as sysdba的方式登陸數據庫,提示連接到空閑的實例,使用easy connect 方式連接則報oracle實例無法分配內存,從報錯提示上看,就像oracle數據庫實例未打開的狀態!分析alert日志不斷出現如下錯誤信息:
Process J002 died, see its trace file
kkjcre1p: unable to spawn jobq slave process
Errors in file /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_cjq0_18577.trc:

trace文件摘要信息如下:
*** 2012-07-26 10:20:31.068
Process J002 is dead (pid=13857 req_ver=1136 cur_ver=1136 state=KSOSP_SPAWNED).

*** 2012-07-26 10:20:32.069
Process J002 is dead (pid=13876 req_ver=1594 cur_ver=1594 state=KSOSP_SPAWNED).

google查詢一番后,發現大部分描述和oracle的進程數設置有關,又或者是內存不足引起!于是在oracle 10g環境下測試,線上數據庫環境為11.2.0.3

一:設置processes初始化參數值為20,重啟數據庫后,已經占用19個進程

  1. SQL> select count(*) from v$process;  
  2.  
  3.   COUNT(*)  
  4. ----------  
  5.         19  
  6.  
  7. SQL> show parameter process;  
  8.  
  9. NAME                                 TYPE        VALUE  
  10. ------------------------------------ ----------- ------------------------------  
  11. aq_tm_processes                      integer     0  
  12. db_writer_processes                  integer     1  
  13. gcs_server_processes                 integer     0  
  14. job_queue_processes                  integer     10  
  15. log_archive_max_processes            integer     2  
  16. processes                            integer     20 

新的會話連接,則報連接到空閑的實例,alert日志則出現相應的報錯

  1. [root@db1 ~]# su - oracle  
  2. [oracle@db1 ~]$ sqlplus /nolog  
  3. SQL*Plus: Release 10.2.0.1.0 - Production on Wed Jul 4 13:50:22 2012  
  4. Copyright (c) 1982, 2005, Oracle.  All rights reserved.  
  5.  
  6. SQL> conn /as sysdba  
  7. Connected to an idle instance.  
  8.  
  9. [oracle@db1 dbs]$ tail -f /u01/app/oracle/admin/db1/bdump/alert_db1.log   
  10. Wed Jul  4 13:52:23 2012  
  11. ksvcreate: Process(q000) creation failed  
  12. Wed Jul  4 13:52:35 2012  
  13. Process q001 died, see its trace file  
  14. Wed Jul  4 13:52:35 2012  
  15. ksvcreate: Process(q001) creation failed  
  16. Wed Jul  4 13:52:37 2012  
  17. Process m000 died, see its trace file  
  18. Wed Jul  4 13:52:37 2012  
  19. ksvcreate: Process(m000) creation failed 

二:于是想到監控oracle的進程和會話數來進一步確定問題
1:首先要對用戶進行顯示授權,否則后面創建存儲過程編譯將會報錯

  1. SQL> grant select on V_$SESSION tbo hr;  
  2. Grant succeeded.  
  3.  
  4. SQL> grant select on V_$PROCESS to hr;  
  5. Grant succeeded. 

2:建表,用來存儲結果

  1. SQL> create table session_monitor(time timestamp,session_count number,process_count number);  
  2. Table created. 

3:創建存儲過程,將數據插入表

  1. SQL> create or replace procedure proc_session  
  2.   2  is  
  3.   3  v_session number(8);  
  4.   4  v_process number(8);  
  5.   5  begin  
  6.   6   select count(*) into v_session from v$session;  
  7.   7   select count(*) into v_process from v$process;  
  8.   8   insert into session_monitor values (sysdate,v_session,v_process);  
  9.   9   commit;  
  10.  10  end proc_session;  
  11. Procedure created. 

4:創建任務

  1. SQL> var job number;  
  2. SQL> begin  
  3.   2    sys.dbms_job.submit(job => :job,  
  4.   3                        what => 'proc_session();',  
  5.   4                        next_date => sysdate,  
  6.   5                        interval => 'sysdate+2/1440');  
  7.   6* end;  
  8. PL/SQL procedure successfully completed. 

5:測試效果

  1. SQL> exec proc_session;  
  2. PL/SQL procedure successfully completed.  
  3.  
  4. SQL> alter session set nls_date_format='YYYY-MM-DD-HH24:MI:SS';  
  5. Session altered.  
  6.  
  7. SQL>  select * from session_monitor;  
  8.  
  9. TIME                                     SESSION_COUNT PROCESS_COUNT  
  10. ---------------------------------------- ------------- -------------  
  11. 26-JUL-12 03.02.12.000000 PM                       140           155  
  12. 26-JUL-12 03.02.14.000000 PM                       141           157  
  13.  
  14. SQL> select job,next_date from user_jobs where what='proc_session();';  
  15.  
  16.        JOB NEXT_DATE  
  17. ---------- -------------------  
  18.        145 2012-07-26-15:04:14  
  19.  
  20. SQL> select * from session_monitor;  
  21.  
  22. TIME                                     SESSION_COUNT PROCESS_COUNT  
  23. ---------------------------------------- ------------- -------------  
  24. 26-JUL-12 03.04.14.000000 PM                        87            94  
  25. 26-JUL-12 03.02.12.000000 PM                       140           155  
  26. 26-JUL-12 03.02.14.000000 PM                       141           157 

6:如果要刪除任務,則運行下列的命令,145代表user_jobs視圖中的job列

  1. SQL> begin  
  2.   2  dbms_job.remove(145);  
  3.   3  end;  
  4. PL/SQL procedure successfully completed. 

三:使用nagios+fetion,定時去監控會話和進程數
1:創建監控腳本,該腳本放任務計劃中運行,每2分鐘自動執行

  1. [root@server240 libexec]# cat session_oracle.sh   
  2. #!/bin/sh  
  3. rm -rf /tmp/session_oracle.log  
  4. export ORACLE_HOME=/u01/app/oracle/product/11.2.0/db1  
  5. /u01/app/oracle/product/11.2.0/db1/bin/sqlplus hr/hr@192.168.1.240:1521/orcl <<EOF 
  6. set echo off  
  7. set feedback off  
  8. spool /tmp/session_oracle.log  
  9. alter session set nls_date_format='YYYY-MM-DD:HH24:MI:SS';  
  10. select session_count from (select * from session_monitor order by time desc ) where  rownum=1;  
  11. select process_count from (select * from session_monitor order by time desc ) where  rownum=1;  
  12. spool off  
  13. set echo on  
  14. set feedback on  EOF

2:創建第二腳本,用來處理前面監控腳本的日志輸出,將結果返回給監控服務器

  1. [root@server240 ~]# cat /tmp/session_oracle.log
    SQL> alter session set nls_date_format='YYYY-MM-DD:HH24:MI:SS';
    SQL> select session_count from (select * from session_monitor order by time desc ) where  rownum=1;
  2. SESSION_COUNT                                                                  
    -------------                                                                  
              138                                                                  
    SQL> select process_count from (select * from session_monitor order by time desc ) where  rownum=1;
  3. PROCESS_COUNT                                                                  
    -------------                                                                  
              153                                                                  
    SQL> spool off
  4.  
  5. [root@server240 libexec]# cat check_oracle_session.sh   
  6. #!/bin/sh  
  7. STATE_OK=0 
  8. STATE_CRITICAL=2 
  9.  
  10. if  [ -f /tmp/session_oracle.log  ];then  
  11.      SESSION=$(grep -A 2 'SESSION_COUNT'  /tmp/session_oracle.log |tail -1|sed 's/[ ][ ]*//g')  
  12.      PROCESS=$(grep -A 2 'PROCESS_COUNT'  /tmp/session_oracle.log |tail -1|sed 's/[ ][ ]*//g')  
  13.      else   
  14.      echo "something wrong,please check monitor script"  
  15.      exit $STATE_CRITICAL  
  16. fi  
  17.  
  18. if   [ $SESSION -gt 500 ] || [ $PROCESS -gt 500 ];then   
  19.      echo "Current session is $SESSION,process is $PROCESS "  
  20.      exit $STATE_CRITICAL  
  21.      else   
  22.        echo "Current session is $SESSION,process is $PROCESS "  
  23.        exit $STATE_OK  
  24. fi 

四:實際效果
[root@server198 ~]# /usr/local/nagios/libexec/check_nrpe -H 192.168.1.240 -c check_oracle_session
Current session is 138,process is 153

五:后期觀察結果,估計和內存問題相關
[oracle@server240 ~]$ sar -r |grep 10:20
10:20:02 AM   3481492  21195164     85.89    675584  13661448   3683012    413552     10.10     
[oracle@server240 ~]$ sar -r |grep 04:40
04:40:01 PM   2076748  22599908     91.58    734088  14581728   4048864     47700      1.16

posted @ 2012-07-28 12:43 tbwshc 閱讀(1064) | 評論 (0)編輯 收藏

僅列出標題
共10頁: First 2 3 4 5 6 7 8 9 10 
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久综合九色综合欧美就去吻| 欧美激情91| 亚洲第一天堂无码专区| 国产精品一区在线观看| 国产精品v欧美精品v日韩精品 | 久久五月激情| 久久久久国产精品午夜一区| 久久激情五月婷婷| 老司机午夜精品视频在线观看| 欧美91大片| 欧美午夜国产| 一区二区三区在线看| 亚洲精品日韩激情在线电影| 亚洲午夜精品一区二区| 久久久xxx| 91久久久亚洲精品| 9久草视频在线视频精品| 亚洲欧美日韩中文视频| 欧美成人伊人久久综合网| 国产精品国产三级国产普通话蜜臀| 国产亚洲精品久久久| 亚洲最新合集| 久久综合久久综合久久| 亚洲精品中文字幕在线观看| 香蕉av777xxx色综合一区| 免费日韩av| 国产日韩高清一区二区三区在线| 亚洲精品视频免费观看| 欧美主播一区二区三区| 亚洲国产精品ⅴa在线观看| 中日韩视频在线观看| 久久一区中文字幕| 国产伦精品一区二区三区高清版 | 欧美资源在线| 欧美日韩在线一区| 亚洲激情在线激情| 久久九九精品99国产精品| 亚洲日本中文字幕| 久久综合电影一区| 国产日韩视频| 小辣椒精品导航| 亚洲狼人综合| 久久久综合网| 亚洲一二三区视频在线观看| 欧美大片国产精品| 韩国美女久久| 久久精品30| 在线亚洲精品| 欧美日韩国产综合一区二区| 亚洲青涩在线| 欧美a级理论片| 久久久精品五月天| 国语自产精品视频在线看| 欧美在线影院| 欧美一区二区三区四区高清| 国产精品毛片a∨一区二区三区|国| 日韩视频不卡中文| 亚洲茄子视频| 欧美女同在线视频| 一区二区高清视频| 亚洲精品国产精品久久清纯直播| 欧美jizzhd精品欧美巨大免费| 国产精品久久久久久久午夜| 国产精品免费电影| 欧美国产一区二区| 久久久久免费| 欧美在线www| 狠狠色狠狠色综合日日小说| 久久精品夜色噜噜亚洲aⅴ| 午夜视黄欧洲亚洲| 国产亚洲制服色| 美女国内精品自产拍在线播放| 久久久精品动漫| 在线视频观看日韩| 欧美激情亚洲综合一区| 男女av一区三区二区色多| 亚洲美女av网站| 野花国产精品入口| 国产精品稀缺呦系列在线| 久久激情综合网| 久久综合九色综合欧美就去吻 | 亚洲欧美国产制服动漫| 国产日韩精品在线观看| 久久综合国产精品台湾中文娱乐网| 久久午夜av| 一区二区黄色| 久久www成人_看片免费不卡| 亚洲精品日日夜夜| 国产精品久久久久久久7电影| 欧美在线观看视频在线| 久久婷婷一区| 亚洲一区二区在线视频| 欧美一区二区三区视频在线| 亚洲日本欧美日韩高观看| 一区二区欧美日韩| 一色屋精品视频在线看| 亚洲裸体在线观看| 国产一区日韩二区欧美三区| 免费看亚洲片| 亚洲成人自拍视频| 欧美日韩亚洲91| 久久一区二区精品| 欧美日韩一区二区三区在线| 久久久亚洲一区| 欧美午夜精品理论片a级按摩| 久久嫩草精品久久久精品| 欧美日韩岛国| 欧美国产激情二区三区| 国产欧美日韩三级| 99精品欧美一区二区三区综合在线| 好看的日韩视频| 亚洲一区二区三区中文字幕 | 久久久久久噜噜噜久久久精品 | 午夜精品影院| 亚洲美女淫视频| 久久精品免费看| 欧美亚洲综合另类| 欧美精品一区在线播放| 男人天堂欧美日韩| 国产一区二区三区无遮挡| 亚洲深夜福利视频| 99re6热在线精品视频播放速度| 久久九九免费视频| 亚洲视频axxx| 欧美日韩精品三区| 亚洲欧洲一区二区三区在线观看| 在线观看的日韩av| 久久国产主播| 久久精品一区二区三区中文字幕| 国产精品久久中文| 一区二区三区**美女毛片| 一区二区三区.www| 欧美精选在线| 亚洲精品在线视频观看| 亚洲另类视频| 欧美成人国产一区二区| 欧美99在线视频观看| 合欧美一区二区三区| 久久久成人网| 韩日欧美一区| 久久精品麻豆| 欧美激情视频一区二区三区免费| 在线成人av| 欧美aaa级| 日韩视频在线一区二区三区| 亚洲老司机av| 欧美午夜在线| 亚洲午夜一区二区| 久久激情婷婷| 一区二区三区亚洲| 麻豆成人精品| 99精品国产一区二区青青牛奶 | 欧美一区二区成人| 国产精品专区h在线观看| 性欧美1819性猛交| 老鸭窝91久久精品色噜噜导演| 亚洲大片在线观看| 欧美日韩国产一中文字不卡| 99在线热播精品免费| 久久国产精品久久久久久电车| 国产亚洲精品激情久久| 老司机精品视频网站| 亚洲人成网站在线播| 国产区二精品视| 久久国内精品自在自线400部| 欧美jizzhd精品欧美巨大免费| 99在线精品视频在线观看| 欧美香蕉视频| 久久在线免费| 99国产精品视频免费观看| 欧美一区二区三区精品电影| 亚洲午夜视频| 欧美日韩在线不卡一区| 久久乐国产精品| 亚洲欧洲在线看| 国产精品黄视频| 久久久亚洲国产美女国产盗摄| 99国产一区| 久久中文在线| 亚洲一区二区不卡免费| 一区视频在线播放| 国产精品久久久久久久久免费樱桃| 久久国产加勒比精品无码| 亚洲欧洲日本mm| 你懂的网址国产 欧美| 欧美在线亚洲| 一区二区日韩免费看| 激情欧美日韩| 国产精品入口麻豆原神| 欧美久色视频| 美女免费视频一区| 午夜久久久久久| 一区二区冒白浆视频| 欧美激情按摩| 另类春色校园亚洲| 久久九九有精品国产23| 午夜精品在线| 亚洲男人的天堂在线| 99精品欧美| 亚洲精品视频在线观看免费|