熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Oracle >> 正文

32bitoracle擴展SGA原理

2013-11-13 12:46:50  來源: Oracle 

  bit oracle由於位數限制使得oracle進程只能訪問g(次方)以下的虛擬內存地址在很多時候這是一個很讓人頭疼的問題因為空著許多內存而不能使用而默認情況下SGA不能超過g比如我們的linux下有g內存卻有部分空著不能用干著急這個時候我們就要考慮怎樣擴展oracle的SGA那麼首先如何識別bit的oracle呢?我們可以通過如下查詢得到

  sys@OCN> select * from v$version;

  BANNER
   
    Oraclei Enterprise Edition Release Production
    PL/SQL Release Production
    CORE Production
    TNS for Linux: Version Production
    NLSRTL Version Production

  如果是bit oracle在查詢結果中一定會顯示 bit 字樣沒有出現則一定是bit oracle 當然在os上通過file oracle 也能看到

  [oracle@ocn bin]$ cd $ORACLE_HOME/bin
    [oracle@ocn bin]$ file oracle
    oracle: setuid setgid ELF bit LSB executable Intel version dynamically linked (uses shared libs) not stripped
    [oracle@ocn bin]$

  在某些os上比如AIX上bit oracle 會正常顯示信息bit則不正常顯示

  在確認了bit oracle之後我們要明白通常情況下我們的OS進程只能訪問g以下的空間redhat linux AS 或者AS版本例外他們可以提供VLM(Very large memory)功能支持使得通過轉換可以使用bit來標志內存地址那麼就是次方理論上最大可支持g內存訪問在oracle中則是通過將內存當作文件來訪問的虛擬一個 /dev/shm 的文件系統這個文件系統是完全由內存組成的這樣將突破g的限制那回過來我們看看既然進程可以訪問g以下內存為何通常SGA又是g呢

  在OS中規定了一個進程在應用程序中能訪問的虛擬內存空間為ggg這段虛擬地址空間是保留給kernel使用的要注意我們這裡強調的是虛擬地址空間並沒有說物理地址空間也就是說假設有g的內存g的虛擬地址空間可能出現在g內存的gg部分內存段並不是說是物理內存的g段而在這g的虛擬地址中oracle又是如何來使用的呢這是固定好了地址的

  +++++++++++++++ g
    + +
    + +
    + +
    +++++++++++++++ g: kernel
    + +
    + +
    + +
    +++++++++++++++ g: process stack
    + +
    + +
    +++++++++++++++ g: SGA起點
    +++++++++++++++ g: oracle 共享庫裝載起點
    + +
    + +
    + +
    +++++++++++++++ g: oracle program(可執行代碼)裝載起點

  在這段虛擬地址的分配中g是sga的起點而進程的私有空間的分配(stack部分)卻是從靠近g處開始的也就是實際上SGA和進程私有空間是共用了gg這部分的由於進程私有空間特別小通常我們習慣性地認為SGA可以達到g進程私有空間有g足夠了從oracle一啟動開始或者從任何一用戶進程登陸開始所有虛擬地址的分配都已經固定好了只有用戶私有空間還可以擴展我們來看一下數據庫啟動後pmon進程(實際上任何一個進程都是一樣的)的虛擬地址分配情況由於我一台機器上跑著個數據庫所以我們看其中一個先看看數據庫SGA相關信息

  [root@ocnsb root]# su oracle
    [oracle@ocnsb oracle]$ sqlplus / as sysdba

  SQL*Plus: Release Production on Mon Jul ::

  Copyright (c) Oracle Corporation All rights reserved

  Connected to:
    Oraclei Enterprise Edition Release Production
    With the Partitioning Real Application Clusters OLAP and Oracle Data Mining options
    JServer Release Production

  select>sys@OCN>select INSTANCE_NAME from v$instance ;

  INSTANCE_NAME
   
    roocn

  show>sys@OCN>show sga

  Total System Global Area bytes
    Fixed Size bytes
    Variable Size bytes
    Database Buffers bytes
    Redo Buffers bytes
    sys@OCN>

  exit>sys@OCN>exit
    Disconnected from Oraclei Enterprise Edition Release Production
    With the Partitioning Real Application Clusters OLAP and Oracle Data Mining options
    JServer Release Production
    [oracle@ocnsb oracle]$ ipcs

   Shared Memory Segments
    key shmid owner perms bytes nattch status
    xabdc oracle
    xccac oracle

   Semaphore Arrays
    key semid owner perms nsems status
    xdf oracle
    xd oracle

   Message Queues
    key msqid owner perms usedbytes messages

  [oracle@ocnsb oracle]$

  我這裡的共享內存段只有一個並且就是SGA的大小(shmid為)這是因為shnmax設置太大的緣故

  [oracle@ocn kernel]$ more /proc/sys/kernel/shmmax
   
    [oracle@ocn kernel]$

  接下來我們看看PMON信息首先要找到pmon進程號然後去 /proc/pid/maps 中看該進程的虛擬地址分配信息

  [oracle@ocnsb oracle]$ ps ef|grep pmon
    oracle Jul ? :: ora_pmon_roocn
    oracle Jul ? :: ora_pmon_ocn
    oracle : pts/ :: grep pmon
    [oracle@ocnsb oracle]$

  [oracle@ocnsb oracle]$ more /proc//maps
    aba rxp : /opt/oracle/products//bin/oracle
    abaad rwp : /opt/oracle/products//bin/oracle
    adae rwxp :

  這部分是oracle program裝載信息我們可以看到空間使用了ae 這部分大小不足MB

   rxp : /lib/ldso

  這是oracle 共享庫裝載的起點x 正好是g

   rwp : /lib/ldso
    rwp :
    rxp : /opt/oracle/products//lib/libodmdso
    a rwp : /opt/oracle/products//lib/libodmdso
    a rxp : /opt/oracle/products//lib/libskgxpso
    a rwp b : /opt/oracle/products//lib/libskgxpso
    a rxp : /opt/oracle/products//lib/libskgxnso
    rwp d : /opt/oracle/products//lib/libskgxnso
    d rwp :
    dc rxp : /opt/oracle/products//lib/libjoxso
    cc rwp de : /opt/oracle/products//lib/libjoxso
    ce rwp :
    e rxp : /lib/libdlso
    rwp : /lib/libdlso
    rwp :
    rxp : /lib/libmso
    rwp : /lib/libmso
    rxp : /lib/libpthreadso
    d rwp e : /lib/libpthreadso
    d rxp : /lib/libnslso
    rwp : /lib/libnslso
    rwp :
    rxp : /usr/lib/libaioso
    rwp : /usr/lib/libaioso
    ca rxp : /lib/libcso
    cacf rwp : /lib/libcso
    cfd rwp :
    dd rxp : /lib/libredhatkernelso
    dd rwp : /lib/libredhatkernelso
    df rwp :
    fa rxp : /lib/libnss_filesso
    rwp : /lib/libnss_filesso
    rwp : /dev/zero
    c rwp :

  共享庫消耗了不到MB的空間

  b rws : /SYSVabdc (deleted)

  這是SGA的起點x 表示g

  bb rs b : /SYSVabdc (deleted)
    bba rws b : /SYSVabdc (deleted)
    baba rs ba : /SYSVabdc (deleted)
    bab rws ba : /SYSVabdc (deleted)

  sga虛擬空間分配到這裡通過計算進制數正好和我們的SGA大小吻合就是我們在ipcs查看的時候的 shmid

  bffebffee rwxp ffff :
    bfffbfff rxs : /dev/vsys

  由於xc正好是g(進制數c=*=x表示g)則這裡表示進程私有空間的分配的起點查看oracle任何一個用戶登陸進程也將發現這樣的虛擬地址分配在這裡我們很容易看出來oracle program 和共享內存庫所占用的空間很小沒有必要給那麼大實際上oracle program 給M足夠安全而共享庫給M也足夠安全了也就是從理論上來講我們可以把oracle program所需要壓縮在x以下共享庫所需要內存壓縮在x以下這樣SGA的起點就可以提升到x(g)而原來是從x(g)開始的只有大約g分配給SGA現在從g開始分配SGA則可以接近g比如分配g內存給SGA要實現這個功能我們需要重新編譯oracle program降低共享庫虛擬內存分配的地址和SGA的分配起點位置x這個共享庫裝載的起點是由進程的mapped_base來決定的

  [oracle@ocnsb oracle]$ more /proc//mapped_base
   

  這個大小是G則意味著共享庫的裝載從虛擬地址的g位置開始如果要降低這個地址需要在oracle啟動之前也就是用root用戶把將啟動oracle的進程的mapped_base降低到M這樣oracle啟動之後的產生的進程都將繼承這個值

  su root echo > /proc//mapped_base

  當然我們也可以通過一些shell來實現oracle用戶登陸之後自動降低mapped_base的功能這個在google上就能找到了或者參考

  中文章內容如下

  Giving Oracle Users the Privilege to Change the Base Address for Oracles Shared Libraries Without Giving them root Access

  As shown above only root can change the base address mapped base for shared libraries Using sudo we can give Oracle users the privilege to change mapped base for their own shells without giving them full root access Here is the procedure:

  su root

  # Eg create a script called /usr/local/bin/ChangeMappedBase

  # which changes the mapped base for the parent process

  # the shell used by the Oracle user where the sudo program # is executed (forked) Here is an example:

  #/bin/sh

  # Lowering mapped base to x echo > /proc/$PPID/mapped_base

  # Make sure that owernship and permissions are correct chown rootroot /usr/local/bin/ChangeMappedBase

  chmod /usr/local/bin/ChangeMappedBase

  # Allow the Oracle user to execute /usr/local/bin/ChangeMappedBase via sudo echo oracle ALL=/usr/local/bin/ChangeMappedBase >> /etc/sudoers
    Now the Oracle user can run /usr/local/bin/ChangeMappedBase to change mapped base for its own shell:

  $ su oracle

  $ cat /proc/$$/mapped_base; echo

  $ sudo /usr/local/bin/ChangeMappedBase Password:

  # type in the password for the Oracle user account

  $ cat /proc/$$/mapped_base; echo $
    When /usr/local/bin/ChangeMappedBase is executed the first time after an Oracle login sudo will ask for a password The password that needs to be entered is the password of the Oracle user account

  Changing the Base Address for Oracles Shared Libraries Automatically During an Oracle Login

  The procedure in the previous section asks for a password each time /usr/local/bin/ChangeMappedBase is executed the first time after an Oracle login To have mapped base changed automatically during an Oracle login without a password the following can be done:

  Edit the /etc/sudoers file with visudo:

  su root visudo
    Change the entry in /etc/sudoers from:

  oracle ALL=/usr/local/bin/ChangeMappedBase
    to read:

  oracle ALL=NOPASSWD: /usr/local/bin/ChangeMappedBase
    Make sure bash executes /usr/local/bin/ChangeMappedBase during the login process You can use eg ~oracle/bash_profile:

  su oracle echo sudo /usr/local/bin/ChangeMappedBase >> ~/bash_profile
    The next time you login to Oracle the base address for shared libraries will bet set automatically

  $ ssh oracle@localhost

  oracle@localhosts password: Last login: Sun Apr :: from localhost

  $ cat /proc/$$/mapped_base; echo $

  SGA起點從g降低到g則需要重新編譯oracle program必須要強調的是SGA的起點是和共享庫的起點mapped_ase相關的SGA的起點至少得大於共享庫的起點g以上才是安全的否則數據庫將不能啟動或者崩潰

  關閉oracle
    su oracle
    cd $ORACLE_HOME/rdbms/lib

  修改共享庫裝載地址的文件定義

  genksms s x > ksmss

  編譯好目標文件

  make f ins_rdbmsmk ksmso

  重新編譯oracle可執行文件
    make f ins_rdbmsmk ioracle

  至於 redhat linux AS 以上版本 oracle的VLM的使用則也是比較簡單的了參考
   
   

  當然internet上還有更多文章可以供參考

  在這裡我要指出一個問題也是我們在實踐中遇到的一個問題那就是若SGA分配的很大但沒有使用VLM幾乎很靠近g的時候大約只留下m左右這樣當一個進程進行hash join由於我們的pga_aggregate_target設置為goracle默認單個進程使用PGA可以達到pga_aggregate_target * % = M則使得在進行hash join的時候出錯

  ORA: out of process memory when trying to allocate bytes (hashjoin subhkllcqas:kllsltba)

  我們調整pga_aggregate_target減小到M則該查詢執行成功因為沒有使用VLM的情況下單個進程的內存分配空間必須在g以下而PGA的分配也屬於這個范疇如果使用VLM則PGA已經被分配到g以上部分的虛擬地址不再有這個問題在此不再對VLM進行過多的闡述因為使用也比較簡單從原理上來講就是通過os擴展bit 到bitoracle使用文件來管理內存並支持進程訪問g以上部分的虛擬內存linux上這種用法得到推廣的根本原因是因為其bit oracle很少被使用其他如sunOS/hp unix/AIX 等都廣泛使用bit oracle了這些方法也就失去價值了


From:http://tw.wingwit.com/Article/program/Oracle/201311/16567.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.