Linux 核心引數優化(for oracle)

us_yunleiwang發表於2013-12-05

  Oracle 不同平臺的資料庫安裝指導為我們部署Oracle提供了一些系統引數設定的建議值,然而建議值是在通用的情況下得出的結論,並非能完全滿足不同的需求。使用不同的作業系統核心引數將使得資料庫效能相差甚遠。本文描述了linux下幾個主要核心引數的設定,供參考。


1、Linux共享記憶體
  共享記憶體是在系統核心分配的一塊緩衝區,多個程式都可以訪問該緩衝區。
  由於程式可以直接讀寫記憶體,避免了在核心空間與使用者空間的切換,所以共享記憶體讀寫效率很高。
  當一個程式改變了這塊地址中的內容的時候,其它程式都會察覺到這個更改。共享記憶體類似與windows環境程式設計中的記憶體映像檔案。

  Linux的IPC(Interprocess Communication)通訊機制:是指多個程式之間相互通訊,交換資訊的方法。
  通過使用共享記憶體允許兩個或多個程式共享一定的儲存區,因為不需要拷貝資料。
  Oracle SGA即是基於此方式來實現Oracle程式之間資料共享。因此SGA的合理設定對Oracle效能有重大的影響。
  可以通過ipcs -lm來檢視所有的共享記憶體設定。

 

2、引數修改的方式
  由於Linux的核心引數資訊都存在記憶體中,因此可以通過命令直接修改,並且修改後直接生效。
    但是,當系統重新啟動後,原來設定的引數值就會丟失,而系統每次啟動時都會自動去/etc/sysctl.conf檔案中讀取核心引數。
  如果是臨時修改,則可以採用echo或sysctl -w方式,如果永久修改,建議修改sysctl.conf檔案
  下面是幾種引數修改方式的描述
  a、echo 方式
    echo >    
    將值輸出到檔案,該方式使得核心引數修改立即生效,無需重啟系統,但重啟後失效(以sysctl.conf永久配置檔案為準)
  b、sysctl 命令方式    
    sysctl -w =
    使用sysctl 命令列方式是修改的執行時的核心引數,引數值當重啟後失效,同上
  c、永久性更改
    vi /etc/sysctl.conf  #直接修改對應引數的值,然後執行命令使更改立即生效# sysctl -p
    echo "kernel.shmmax=2147483648" >> /etc/sysctl.conf  #不太建議該方式,這樣子同一引數會有多個值出現在sysctl.conf

 

3、sysctl.conf配置檔案
  幾乎所有的重要引數都保持在sysctl.conf配置檔案中,因此對於永久性修改,直接修改該檔案是最簡單不過的方式了
  下面是基於x86_64 RHEL5 下Oracle 給出的引數建議值

  Oracle10gR2 On RHEL 5/OEL 5 (x86_64) [ID 421308.1]
    kernel.shmall = physical RAM size / pagesize 
      For most systems, this will be the value 2097152. See Note 301830.1 for more information. 
    kernel.shmmax = 1/2 of physical RAM. 
      This would be the value 2147483648 for a system with 4Gb of physical RAM. See Note 567506.1 for more information.
    kernel.shmmni = 4096 
    kernel.sem = 250 32000 100 128 
    fs.file-max = 512 x processes (for example 65536 for 128 processes) 
    Development recommends a minimum of 327679 for active systems. 
    net.ipv4.ip_local_port_range = 9000 65500 
    (The runInstaller (OUI) checks may expect this to be the old guidance of 1024 65000. 
    The new guidance from Oracle development is 9000 65500. 
    Please allow the runInstaller (OUI) to proceed with the new guidance from Oracle development.) 
    net.core.rmem_default = 262144 
    net.core.rmem_max = 2097152 
    net.core.wmem_default = 262144 
    net.core.wmem_max = 1048576 
  
  Oralce 11g R2 on RHEL (and OEL) 5 on AMD64/EM64T [ID 880989.1]    
    kernel.shmall = physical RAM size / pagesize 
      For most systems, this will be the value 2097152. See Note 301830.1 for more information. 
      kernel.shmmax = 1/2 of physical RAM. 
        This would be the value 2147483648 for a system with 4Gb of physical RAM. 
      kernel.shmmni = 4096 
      kernel.sem = 250 32000 100 128 
      fs.file-max = 512 x processes (for example 6815744 for 13312 processes)
      fs.aio-max-nr = 1048576
      net.ipv4.ip_local_port_range = 9000 65500 
      net.core.rmem_default = 262144 
      net.core.rmem_max = 4194304 
      net.core.wmem_default = 262144 
      net.core.wmem_max = 1048576
  
  對於Oracle 11g,Oracle建議如果系統當前設定的值大於上述列出的值,則無需修改,保留原值。
  從上面可知,sysctl.conf包含了所有的核心引數檔案,且以kernel開頭,下面對這幾個重要引數進行逐一描述。
    
4、引數SHMMAX

  a、引數描述(From meatlink [ID 15566.1])
   Shared memory allocation
   ========================
   
     Oracle has 3 different possible models for the SGA - one-segment,
     contiguous multi-segment, and non-contiguous multi-segment.
     When attempting to allocate and attach shared memory for the SGA, it
     will attempt each one, in the above order, until one succeeds or raises
     an ORA error.  On other, non-fatal, errors, Oracle simply cleans up and
     tries again using the next memory model.  The entire SGA must fit into
     shared memory, so the total amount of shared memory allocated under any
     model will be equal to the size of the SGA.  This calculated value will
     be referred to below as SGASIZE.
   
     The one-segment model is the simplest and first model tried. In this
     model, the SGA resides in only one shared memory segment.  Oracle attempts
     to allocate and attach one shared memory segement of size equal to total
     size of the SGA.  However, if the SGASIZE is larger than the configured
     SHMMAX, this will obviously fail (with EINVAL).  In this case, the SGA will
     need to be placed in multiple shared memory segments, and Oracle proceeds
     to the next memory model for the SGA.  If an error other than EINVAL occurs
     when allocating the shared memory with shmget(), Oracle will raise an
     ORA-7306.  If the segment was received (i.e. if SHMMAX > SGASIZE), Oracle
     attempts to attach it at the start address defined in ksms.o.  An error
     on the attach will raise an ORA-7307.
   
     With multiple segments there are two possibilities.  The segments
     can be attached contiguously, so that it appears to be one large
     shared memory segment, or non-contiguously, with gaps between the
     segments.  The former wastes less space that could be used for the stack
     or heap, but depending on alignment requirements for shared memory
     (defined by SHMLBA in the kernel), it may not be possible.
   
     At this point, Oracle needs to determine SHMMAX so it can determine how many
     segments will be required.  This is done via a binary search
     algorithm over the range [1...SGASIZE] (since Oracle is trying this
     model and not the one segment model it must be that SHMMAX      The value of SHMMAX calculated will then be rounded to an even page size
     (on some machines, possibly to an even 2 or 4 page block).
   
     In the contiguous segment model, Oracle simply divides the SGA into
     SGASIZE/SHMMAX (rounded down) segments of size SHMMAX plus another segment
     of size SGASIZE modulo SHMMAX.  If more than SS_SEG_MAX segments are
     required total, an ORA-7329 is raised.  It then allocates and attaches
     one segment at a time, attaching the first segment at the start address
     defined in "ksms.o".  Subsequent segments are attached at an address equal
     to the previous segment's attach address plus the size of the previous
     segment so that they are contiguous in memory.  
   
     For example, if SHMMAX is 2M, SGASIZE is 5M, and the start address is 
     0xd0000000, there would be 3 segments, 2 of 2M and 1 of 1M.  They would be 
     attached at 0xd0000000, 0xd0000800 (0xd0000000+2M), and 0xd0001000 
     (0xd0000800+2M).  If Oracle receives an error allocating a shared memory 
     segment, an ORA-7336 is raised.
   
     If an error is raised on attaching a shared memory segement, Oracle checks
     the system error returned.  If it is EINVAL, the attach address used is most
     likely badly aligned (not a mulitple of SHMLBA).  In this case, Oracle tries
     the next model for SGA allocation, non-contiguous segments.  Otherwise, an
     ORA-7337 is raised.
   
     The last model Oracle will try is the non-contiguous model.  Here,
     things become a bit more complicated.  After calculating SHMMAX, Oracle
     first checks to see if it can put the fixed and variable portion into
     one shared memory segment just large enough to hold the two portions
     If it can, it allocates a segment just big enough to hold both portions.
     If it cannot, it will put them each into their own seperate segment just
     large enough to hold each portion.  If the fixed portion is larger than
     SHMMAX, an ORA-7330 will be raised.  If the variable portion is larger
     than SHMMAX, an ORA-7331 will be raised.  Then Oracle computes the number
     of redo block buffers it can fit in a segment (rounded down to an
     integral number of buffers - buffers cannot overlap segments).  An ORA-7332
     is raised is SHMMAX is smaller than the size of a redo block.  
   
     Similarly, the number of db block buffers per segment is calculated, with an 
     ORA-7333 raised if SHMMAX is too small to hold one db block.  Then Oracle can 
     compute the total number of segments required for both the redo and database 
     block buffers. This will be buffers/buffers per segment (rounded down) segments
     and one (if necessary) of buffers modulo buffers per segment size, calculated
     seperately for both the redo and db block buffers.  These segments will be
     of a size just large enough to hold the buffers (so no space is wasted).
   
     The total number of segments allocated will then be the number needed for
     the fixed and variable portions (1 or 2) plus the number needed for the
     redo block buffers plus the number of segments needed for the database block
     buffers.  If this requires more than SS_SEG_MAX segments, an ORA-7334 is
     raised. 
   
     Once the number of segments and their sizes is determined, Oracle
     then allocates and attaches the segments one at a time; first the fixed
     and variable portion segment(s), then the redo block buffer segment(s),
     then the db block buffer segment(s).  They will be attached non-contiguously,
     with the first segment attached at the start address in "ksms.o" and following
     segments being attached at the address equal to the attach address of the
     previous segment plus the size of the previous segment, rounded up to a
     mulitple of SHMBLA.  
   
     If Oracle receives an error allocating a shared memory segment, an ORA-7336 is 
     raised.  If an error is raised on attaching a shared memory segement, Oracle 
     checks the system error returned.  If it is EINVAL, normally another model 
     would be tried, but as there are no more models to try, an ORA-7310 is raised. 
     Other attach errors raise an ORA-7337.
   
     At this point, we have either attached the entire SGA or returned an
     ORA error.  The total size of segments attached is exactly SGASIZE;
     no space is wasted.  Once Oracle has the shared memory attached, Oracle
     proceeds to allocating the semaphores it requires.
    
    該引數定義了一個linux程式能分配虛擬地址空間的單個共享記憶體段的大小(位元組為單位)。
    從上面的描述可知對於Oracle而言,SHMMAX主要用於控制和分配sga,且使用3種不同的模式可供選擇來分配sga size
      SHMMAX > SGASIZE : 分配一個單獨的共享記憶體段給sga(首選方式)
      SHMMAX < SGASIZE : 分配多個連續或不連續的共享記憶體段給sga
    由上可知應當設定為大於當前伺服器上執行例項的最大的SGA的大小。
    如該值設定太小或者小於最大sga的大小,則sga無法在一個單獨的共享記憶體段hold住整個sga,而需要分配多個不同的共享記憶體段來完成。
    對於32-bit作業系統,通常設定為4GB-1byte,而64-bit,則可以設定為大於4GB

  b、檢視引數檔案值
    # cat /proc/sys/kernel/shmmax
    2147483648

  c、修改引數值
    如果當前最大sga的大小為3g,則至少為shmmax設定下面的值
    # echo 3221225472 > /proc/sys/kernel/shmmax
    
    # sysctl -w kernel.shmmax=3221225472
    
    # echo "kernel.shmmax=3221225472" >> /etc/sysctl.conf

 

5、引數SHMMNI
  a、引數描述
    該引數用於設定共享記憶體段的總個數。也就是說在記憶體中總共可以開闢多少個共享記憶體段。
    對於Oracle 10g,Oracle的對該引數的建議值至少為4096。一般情況下夠用。
  
  b、檢視shmmni引數檔案的值 
    # cat /proc/sys/kernel/shmmni
    4096
  
  c、修改shmmni引數
    # echo 4096 > /proc/sys/kernel/shmmni
    
    # sysctl -w kernel.shmmni=4096
    
    # echo "kernel.shmmni=4096" >> /etc/sysctl.conf

 

6、引數SHMALL 
  a、引數描述
    該引數用於配置系統一次能夠使用的最大的共享頁面數,該引數的值總是基於ceil(shmmax/PAGE_SIZE)
     Oracle 9i,10g的x86以及x86-64平臺推薦以及預設的大小通常為2097152
     在大多數情況下,該引數是夠用的。按照上述計算方式頁面記憶體總大小可以達到8GB(2097152*4096 bytes (shmall*PAGE_SIZE))
     通常情況下,PAGE_SIZE 的大小為4096byte,除非使用了Big Pages 或 Huge Pages 
     對於超出8GB系統記憶體,如共享記憶體段(shmmax)的最大大小是16G,則所需要共享記憶體頁數(shmall)為:
       16GB/4KB=16777216KB/4KB=4194304(頁) 對於32GB,64GB可以依上述方式類推。

  b、檢視系統當前的page size大小與SHMALL 引數的值 
    $ getconf PAGE_SIZE
    4096
    
    # cat /proc/sys/kernel/shmall
    2097152

  c、修改SHMALL 引數
    下面是按照16G所需的頁面數進行設定
    # echo 4194304 > /proc/sys/kernel/shmall
    
    # sysctl -w kernel.shmall=4194304
    
    # echo "kernel.shmall=4194304" >> /etc/sysctl.conf

 

7、設定訊號量
  Semaphore allocation(From meatlink [ID 15566.1])
  ====================
  
    Semaphore allocation is much simpler than shared memory.  Oracle just
    needs to allocate a number of semaphores equal to the processes parameter
    in "init.ora".  PROCESSES will be used to refer to this value.  Note on
    machines with a post-wait kernel extension, Oracle does not need to allocate
    semaphores (because it doesn't need to implement its own post-wait mechanism).
  
    Oracle uses semaphores to control concurrency between all the  
    background processes (pmon, smon, dbwr, lgwr, and oracle shadows).  
    Semaphores are also used to control two-task communication between  
    the user process and shadow process if the fast (shared memory)  
    driver is used.  And in the Unix ports based on MIPS RISC  
    processors, Oracle uses a special semaphore to perform basic  
    test & set functions that are not provided by the processor
    
  訊號量,有時候也被稱為訊號燈,是一個非負整數計數器。通常用來協調對資源的訪問。
  訊號量用於提供程式間的同步或者一個程式內的多個執行緒來共享資源,比如共享記憶體。其中訊號計數會初始化為可用資源的數目。
  當執行緒在資源增加時會增加計數,在刪除資源時會減小計數,這些操作都以原子方式執行。如果訊號計數變為零,則表明已無可用資源。
  計數為零時,嘗試減小訊號的執行緒會被阻塞,直到計數大於零為止。
  訊號量的數量可以通過系統核心引數SEMMSL來設定。

  a、引數SEMMSL 
    該引數定義了每個訊號集的最大訊號數量
    Oracle 建議將 SEMMSL 設定為Oracle引數檔案(用於Linux系統中的所有資料庫)中的最大PROCESS例項引數的設定值再加上10 。
    此外, Oracle建議將 SEMMSL 的值設定為不少於100。
  
  b、引數SEMMNS
    該引數控制整個 Linux 系統中訊號(而不是訊號集)的最大數。
    Oracle 建議將 SEMMNS 設定為:
      系統中所有資料庫例項的PROCESSES引數設定值的總和,加上最大PROCESSES值的兩倍,最後根據系統中Oracle資料庫的數量,每個加10
    使用計算式來確定在 Linux 系統中可以分配的訊號的最大數量。取兩者中較小的一個值:SEMMNS 或(SEMMSL * SEMMNI) 
  
    在Oracle 10g和Oracle 11g中,該值被建議設定為SEMMSL * SEMMNI (250*128=32000)
  
  c、引數SEMOPM  
    SEMOPM: 該核心引數用於控制一次semop系統呼叫可以執行的訊號操作的數量semopm。semop 系統呼叫(函式)提供了利用一個 semop 
    系統呼叫完成多項訊號操作的功能。一個訊號集能夠擁有每個訊號集中最大數量的SEMMSL 訊號,因此建議設定 SEMOPM 等於SEMMSL 。
    Oracle 建議將 SEMOPM 的值設定為不少於 100 
  
  d、引數SEMMNI  
    該引數定義整個Linux系統中訊號集的最大數量。Oracle 建議將 SEMMNI 的值設定為至少為128 。
  
  e、檢視當前的訊號量設定
    # cat /proc/sys/kernel/sem
    250     32000   32      128  (這幾個值分別是:SEMMSL, SEMMNS, SEMOPM, and SEMMNI)
    
    簡要描述這四個引數
    SEMMSL: 每個訊號集的最大訊號數量
    SEMMNS: 系統訊號量(非訊號集)最大數量
    SEMOPM: 每次semop系統呼叫可執行的訊號運算元
    SEMMNI:系統訊號量集最大數量
  
    也可以通過ipcs -ls來檢視當前的訊號量設定
    # ipcs -ls
  
  f、修改訊號量相關引數
    # echo 250 32000 100 128 > /proc/sys/kernel/sem
    
    sysctl -w kernel.sem="250 32000 100 128"
    
    echo "kernel.sem=250 32000 100 128" >> /etc/sysctl.conf
    
    -- Author : Robinson
    -- Blog   : 
http://blog.csdn.net/robinson_0612
    
  h、訊號量設定示例
    SEMMSL應該設定為伺服器中例項中具有最大的PROCESSES引數+10,例如,當最大的PROCESSES引數為5000時,SEMMSL應設定為5010。
    SEMMNS引數應設定為SEMMSL*SEMMNI,接上例SEMMSL為5010,SEMMNI的值一般為128,則SEMMNS引數應為(5010*128)=641280。
    SEMOPM引數應設定與SEMMSL引數相同,接上例此處應設定為5010
    因此對於訊號量建議做如下設定
    sysctl -w kernel.sem="5010 641280 5010 128"

 

8、引數fs.file-max 
  a、引數描述
    該引數指定了當前系統下可開啟的最大檔案控制程式碼數。也就是可以開啟的最大檔案數。
    無論何時當一個檔案控制程式碼被應用程式請求時,linux核心將動態的分配檔案控制程式碼。但是當應用程式釋放後,核心並不釋放這些檔案控制程式碼。
    Linux核心採用迴圈利用這些控制程式碼方式來取代釋放。有點類似於預設情況下Oracle被刪除記錄的空閒空間並不釋放,下次可繼續使用。
    因此係統中已分配的控制程式碼數的值可能很高,而實際真正使用的控制程式碼數值很低。
    注意,該值是一個系統級別的限制,因此該引數的值建議大於等於Oracle使用者的limit限制nofile的值
  
    對於Oracle 9i以及10g,Oracle建議該值至少設定為65536。
  
  b、檢視當前設定的可開啟的檔案控制程式碼數
    $ cat /proc/sys/fs/file-max
  
    這裡的"fs.file-max = 65536"其實是由"fs.file-max = 512 * PROCESSES"得到的
    我們指定PROCESSES的值為128,即為"fs.file-max =512 *128"。
    6815744 512 x processes (for example 6815744 for 13312 processes)
  
  c、檢視當前檔案控制程式碼數的使用情況
    $ cat /proc/sys/fs/file-nr
  
    The file-nr file displays three parameters:
      - Total allocated file handles
      - Currently number of used file handles (2.4 kernel); Currently number of unused file handles (2.6 kernel)
      - Maximum file handles that can be allocated (see also /proc/sys/fs/file-max)

   在kernel 2.6之前的版本中,file-nr 中的值由三部分組成,分別為:
   1).已經分配的檔案控制程式碼數,2).已經分配單沒有使用的檔案控制程式碼數,3).最大檔案控制程式碼數。
   但在kernel 2.6版本中第二項的值總為0,這並不是一個錯誤,它實際上意味著已經分配的檔案控制程式碼無一浪費的都已經被使用了  
   
  d、修改最大檔案控制程式碼數
    下面是process為1000個時的設定
    # echo 512000 > /proc/sys/fs/file-max
    
    # sysctl -w fs.file-max=512000
     
    # echo "fs.file-max=512000" >> /etc/sysctl.conf

 

9、網路引數
  a、引數描述
    在Linux下,Oracle使用UDP作為預設協議用於程式之間的互動以及例項間cache fusion buffer傳輸。
    Oracle 建議預設的最大傳送以及接收緩衝的大小為256KB。接收緩衝區用於TCP/UDP傳輸時hold住應用程式接收到的資料直到被讀取。
    net.core.rmem_default:表示接收套接字緩衝區大小的預設值(以位元組為單位)。
    net.core.rmem_max :表示接收套接字緩衝區大小的最大值(以位元組為單位)
    net.core.wmem_default:表示傳送套接字緩衝區大小的預設值(以位元組為單位)。
    net.core.wmem_max:表示傳送套接字緩衝區大小的最大值(以位元組為單位)。
  
  b、設定網路引數
    # sysctl -w net.core.rmem_default=262144  
    # sysctl -w net.core.wmem_default=262144  
    # sysctl -w net.core.rmem_max=4194304      
    # sysctl -w net.core.wmem_max=1048576      
  
    永久修改方式,直接修改sysctl.conf檔案
    net.core.rmem_default=262144
    net.core.wmem_default=262144
    net.core.rmem_max=4194304
    net.core.wmem_max=1048576
  
  c、埠號的設定
    Oracle建議的埠號值為1024 65000
    # sysctl -w net.ipv4.ip_local_port_range="1024 65000"
    
    net.ipv4.ip_local_port_range=1024 65000
    The first number is the first local port allowed for TCP and UDP traffic, and the second number is the last port number.
  
  d、其他引數
    對於Oracle rac環境,考慮修改修改下列ip核心引數以提高failover效能
    net.ipv4.tcp_keepalive_time
    net.ipv4.tcp_keepalive_intvl
    net.ipv4.tcp_retries2
    net.ipv4.tcp_syn_retries
    see Metalink Note:249213.1 and Note:265194.1.

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

相關文章