数据库

位置:IT落伍者 >> 数据库 >> 浏览文章

32bitoracle扩展SGA原理


发布日期:2018年08月16日
 
32bitoracle扩展SGA原理

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了这些方法也就失去价值了

               

上一篇:Oracle体系结构中的各种名称

下一篇:如何查看数据文件所在的路径?