合 Linux中的shm和tmpfs介绍以及ORA-00845 MEMORY_TARGET not supported on this system
Tags: LinuxOSMEMORY_TARGETORA-00845/dev/shmtmpfs共享内存
简介
linux中/dev
目录下一般都是一些设备文件,例如磁盘、内存、摄像头等。
使用redhat系列的操作系统,可以发现系统默认挂载了/dev/shm,挂载类型为tmpfs。tmpfs(temporary filesystem)是Linux特有的文件系统,标准挂载点是/dev/shm.
/dev/shm共享内存
/dev/shm
这个目录是linux下一个利用内存虚拟出来的一个目录,这个目录中的文件都是保存在内存中,而不是磁盘上。其大小是非固定的,即不是预先分配好的内存来存储的。(shm =shared memory)
默认的Linux发行版中的内核配置都会开启tmpfs,映射到了/dev/下的shm目录。可以通过df 命令查看结果.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | [root@docker35 ~]# free -h total used free shared buff/cache available Mem: 78G 4.3G 46G 2.0G 27G 71G Swap: 10G 0B 10G [root@docker35 ~]# df -h | grep tmpfs devtmpfs 40G 0 40G 0% /dev tmpfs 40G 0 40G 0% /dev/shm tmpfs 40G 123M 40G 1% /run tmpfs 40G 0 40G 0% /sys/fs/cgroup [root@lhrblog ~]# df -h | egrep -e "tmpfs|shm" tmpfs 64M 0 64M 0% /dev shm 64M 4.0K 64M 1% /dev/shm tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup tmpfs 1.9G 213M 1.7G 12% /run tmpfs 379M 0 379M 0% /run/user/0 |
其他的几个tmpfs
的挂载目录,其实质上于/dev/shm
是一致的。
/dev/shm/是linux下一个非常有用的目录,因为这个目录不在硬盘上,而是在内存里。因此在linux下,就不需要大费周折去建ramdisk,直接使用/dev/shm/就可达到很好的优化效果。
tmpfs临时文件系统
tmpfs(temporary filesystem)是Linux/Unix系统上的一种基于内存的虚拟文件系统。tmpfs可以使用您的内存或swap分区来存储文件(即它的存储空间在virtual memory 中, VM由real memory和swap组成)。tmpfs有些像虚拟磁盘(ramdisk),但不一样。像虚拟磁盘一样,tmpfs 可以使用您的 RAM,但它也可以使用您的交换分区来存储。而且传统的虚拟磁盘是个块设备,并需要一个 mkfs 之类的命令才能真正地使用它,tmpfs 是一个文件系统,而不是块设备;您只是安装它,它就可以使用了。
tmpfs有以下优势:
1、动态文件系统的大小,/dev/shm/需要注意的一个是容量问题,在linux下,它默认最大为内存的一半大小,在Docker容器中,/dev/shm/目录默认情况下是64MB,使用df -h命令可以看到。但它并不会真正的占用这块内存,如果/dev/shm/下没有任何文件,它占用的内存实际上就是0字节;如果它最大为1G,里头放有 100M文件,那剩余的900M仍然可为其它应用程序所使用,但它所占用的100M内存,是绝不会被系统回收重新划分的。
2、tmpfs 的另一个主要的好处是它闪电般的速度。因为典型的 tmpfs 文件系统会完全驻留在 RAM 中,读写几乎可以是瞬间的。
3、tmpfs 数据在重新启动之后不会保留,因为虚拟内存本质上就是易失的。所以有必要做一些脚本做诸如加载,绑定的操作。
修改/dev/shm大小
默认为最大一半内存大小在某些场合可能不够用,并且默认的inode数量很低一般都要调高些,这时可以用mount命令来管理它。
1 | mount -o size=1500M -o nr_inodes=1000000 -o noatime,nodiratime -o remount /dev/shm |
在2G的机器上,将最大容量调到1.5G,并且inode数量调到1000000,这意味着大致可存入最多一百万个小文件。
如果需要永久修改/dev/shm的值,需要修改/etc/fstab
1 2 3 | tmpfs /dev/shm tmpfs defaults,size=1.5G 0 0 mount -o remount /dev/shm |
/dev/shm应用
首先在/dev/shm建个tmp文件夹,然后与实际/tmp绑定:
1 2 3 | mkdir /dev/shm/tmp chmod 1777 /dev/shm/tmp mount –bind /dev/shm/tmp /tmp(–bind ) |
在使用mount –bind olderdir newerdir命令来挂载一个目录到另一个目录后,newerdir的权限和所有者等所有信息会发生变化。挂载后的目录继承了被挂载目录的所有属性,除了名称。
ORA-00845: MEMORY_TARGET not supported on this system
Oracle 11g的AMM(Automatic Memory Management)内存管理模式就是使用/dev/shm;若使用ASMM(Automatic Shared Memory Management),则不会使用/dev/shm,也就不会报错。
所以有时候修改MEMORY_MAX_TARGET会出现ORA-00845的错误。
简单来说就是 MEMORY_MAX_TARGET 的设置不能超过 /dev/shm 的大小。
永久修改,需要修改/etc/fstab:
1 | tmpfs /dev/shm tmpfs defaults,size=4G 0 0 |
临时修改,可以使用命令:
1 | mount -o remount,size=4G /dev/shm |
由于docker容器中没有/etc/fstab文件,所以我们只能每次重启容器后都修改一下/dev/shm大小。
1 2 3 | mount -o remount,size=4G /dev/shm echo "mount -o remount,size=4G /dev/shm" >> /etc/rc.local chmod +x /etc/rc.d/rc.local |
ORA-00845错误模拟
在Oracle 11g中如果采用AMM内存管理,那么当MEMORY_TARGET的值大于/dev/shm的时候,就会报ORA-00845: MEMORY_TARGET not supported on this system错误,解决办法增加/dev/shm大小,在redhat系列系统中,/dev/shm的默认值是系统总内存的一半
1、错误重现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | SQL>SELECT * FROM V$VERSION; BANNER ——————————————————————————– Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 – Production PL/SQL Release 11.2.0.3.0 – Production CORE 11.2.0.3.0 Production TNS for Linux: Version 11.2.0.3.0 – Production NLSRTL Version 11.2.0.3.0 – Production SQL>show parameter memory; NAME TYPE VALUE ———————————— ———– —————————— hi_shared_memory_address integer 0 memory_max_target big integer 500M memory_target big integer 500M shared_memory_address integer 0 SQL>alter system set memory_max_target=800m; alter system set memory_max_target=800m * ERROR at line 1: ORA-02095: specified initialization parameter cannot be modified SQL>alter system set memory_max_target=800m scope=spfile; System altered. SQL>alter system set memory_target=800m scope=spfile; System altered. SQL>shutdown immediate; Database closed. Database dismounted. ORACLE instance shut down. SQL>exit Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 – Production With the Partitioning, OLAP, Data Mining and Real Application Testing options [oracle@lhraxxt admin]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.3.0 Production on Sat Nov 5 19:01:18 2011 Copyright (c) 1982, 2011, Oracle. All rights reserved. Connected to an idle instance. SQL>startup ORA-00845: MEMORY_TARGET not supported on this system SQL>!oerr ora 845 00845, 00000, "MEMORY_TARGET not supported on this system" // *Cause: The MEMORY_TARGET parameter was not supported on this operating system or /dev/shm was not sized correctly on Linux. // *Action: Refer to documentation for a list of supported operating systems. Or, size /dev/shm to be at least the SGA_MAX_SIZE on each Oracle instance running on the system. |
2、修改/dev/shm大小
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | [root@lhraxxt ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg_lhraxxt-lv_root 17G 13G 3.9G 77% / tmpfs 590M 0 590M 0% /dev/shm /dev/sda1 485M 30M 430M 7% /boot [root@lhraxxt ~]# mount -o size=900M -o nr_inodes=1000000 -o noatime,nodiratime -o remount /dev/shm [root@lhraxxt ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg_lhraxxt-lv_root 17G 13G 3.9G 77% / tmpfs 900M 0 900M 0% /dev/shm /dev/sda1 485M 30M 430M 7% /boot [root@lhraxxt ~]# vi /etc/fstab \# \# /etc/fstab \# Created by anaconda on Sat Nov 5 02:49:30 2011 \# \# Accessible filesystems, by reference, are maintained under '/dev/disk' \# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info \# /dev/mapper/vg_lhraxxt-lv_root / ext4 defaults 1 1 UUID=7ace6c04-d232-43ac-9ef5-70ea92fe49bd /boot ext4 defaults 1 2 /dev/mapper/vg_lhraxxt-lv_swap swap swap defaults 0 0 tmpfs /dev/shm tmpfs defaults,size=900M 0 0 devpts /dev/pts devpts gid=5,mode=620 0 0 sysfs /sys sysfs defaults 0 0 proc /proc proc defaults 0 0 |
3、启动数据库验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | [oracle@lhraxxt admin]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.3.0 Production on Sat Nov 5 19:03:51 2011 Copyright (c) 1982, 2011, Oracle. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 – Production With the Partitioning, OLAP, Data Mining and Real Application Testing options sys@XFF>show parameter memory; NAME TYPE VALUE ———————————— ———– —————————— hi_shared_memory_address integer 0 memory_max_target big integer 800M memory_target big integer 800M shared_memory_address integer 0 |
4、官方解释
Starting with Oracle Database 11g, the Automatic Memory Management feature requires more shared memory (/dev/shm)and file descriptors. The size of the shared memory should be at least the greater of MEMORY_MAX_TARGET and MEMORY_TARGET for each Oracle instance on the computer. If MEMORY_MAX_TARGET or MEMORY_TARGET is set to a non zero value, and an incorrect size is assigned to the shared memory, it will result in an ORA-00845 error at startup.
5、解决问题建议
5.1. If you are installing Oracle 11g on a Linux system, note that Memory Size (SGA and PGA), which sets the initialization parameter MEMORY_TARGET or MEMORY_MAX_TARGET, cannot be greater than the shared memory filesystem (/dev/shm) on your operating system. To resolve the current error, increase the /dev/shm file size.
5.2. If configuring AMM is not possible due to lack of space on /dev/shm mount point, you can configure ASMM instead of AMM, i.e. set SGA_TARGET, SGA_MAX_SIZE and PGA_AGGREGATE_TARGET instead of MEMORY_TARGET.
在redhat6中,修改了fstab中修改后,不能生效,需要重新挂载
1 2 3 4 5 | vi /etc/fstab tmpfs /dev/shm tmpfs defaults,size=900M 0 0 vi /etc/rc.local mount -o remount /dev/shm |
ORA-00845: MEMORY_TARGET示例2
Linux操作系统,oracle 11.2.0.4 启动实例时出现如下错误:
1 2 | SQL> startup nomount pfile=/u03/app/oracle/11.2.0/db/dbs/initcssb.ora ORA-00845: MEMORY_TARGET not supported on this system |
查看错误帮助信息
1 2 3 4 | [oracle11@oracle11g dbs]$ oerr ora 845 00845, 00000, "MEMORY_TARGET not supported on this system" // *Cause: The MEMORY_TARGET parameter was not supported on this operating system or /dev/shm was not sized correctly on Linux. // *Action: Refer to documentation for a list of supported operating systems. Or, size /dev/shm to be at least the SGA_MAX_SIZE on each Oracle instance running on the system. |
错误原因是这个操作系统不支持MEMORY_TARGET参数或/dev/shm在Linux上的大小不正确造成的,这是该操作系统上的第二个实例,第一个实例设置了MEMORY_TARGET参数,所以并不是不支持这个参数,原因就只有/dev/shm大小不正确了,解决方法是要将/dev/shm的最小值设置为操作系统上运行实例SGA_MAX_SIZE所设置的大小。/dev/shm/是linux下一个目录,/dev/shm目录不在磁盘上,而是在内存里,因此使用linux /dev/shm/的效率非常高,直接写进内存。
tmpfs有以下特点:
1.tmpfs 是一个文件系统,而不是块设备;您只是安装它,它就可以使用了。
2.动态文件系统的大小。
3.tmpfs 的另一个主要的好处是它闪电般的速度。因为典型的 tmpfs 文件系统会完全驻留在 RAM 中,读写几乎可以是瞬间的。
4.tmpfs 数据在重新启动之后不会保留,因为虚拟内存本质上就是易失的。所以有必要做一些脚本做诸如加载、绑定的操作。
linux下/dev/shm的容量默认最大为内存的一半大小,使用df -h命令可以看到。但它并不会真正的占用这块内存,如果/dev/shm/下没有任何文件,它占用的内存实际上就是0字节;如果它最大为1G,里头放有100M文件,那剩余的900M仍然可为其它应用程序所使用,但它所占用的100M内存,是绝不会被系统回收重新划分的。
linux /dev/shm容量(大小)是可以调整,在有些情况下(如oracle数据库)默认的最大一半内存不够用,并且默认的inode数量很低一般都要调高些,这时可以用mount命令来管理它。
mount -o size=1500M -o nr_inodes=1000000 -o noatime,nodiratime -o remount /dev/shm
在2G的机器上,将最大容量调到1.5G,并且inode数量调到1000000,这意味着大致可存入最多一百万个小文件通过/etc/fstab文件来修改/dev/shm的容量(增加size选项即可),修改后,重新挂载即可。
这里该实例的SGA_MAX_SIZE为1G,下面的命令查看/dev/shm的大小。
1 2 3 4 5 | [root@oracle11g ~]# df -lh Filesystem Size Used Avail Use% Mounted on /dev/sda1 23G 20G 1.6G 93% / /dev/sdb1 9.9G 5.8G 3.6G 62% /u02 tmpfs 2G 1.3M 0.7G 65% /dev/shm |
从上面结果可以看到/dev/shm可用大小只有0.7G,执行下面的命令来进行修改。
1 2 3 4 5 6 7 8 9 10 | [root@oracle11g ~]# vi /etc/fstab LABEL=/ / ext3 defaults 1 1 /dev/sdb1 /u02 ext3 defaults 1 2 tmpfs /dev/shm tmpfs defaults,size=4G 0 0 devpts /dev/pts devpts gid=5,mode=620 0 0 sysfs /sys sysfs defaults 0 0 proc /proc proc defaults 0 0 LABEL=SWAP-sda2 swap swap defaults 0 0 "/etc/fstab" 7L, 540C written |
卸载/dev/shm,但/dev/shm正被访问
1 2 3 | [root@oracle11g ~]# umount /dev/shm umount: /dev/shm: device is busy umount: /dev/shm: device is busy |
用fuser处理,fuser命令,-k:kill processes accessing the named file(杀死所有正在访问指定文件的进程),-m 表示指定文件所在的文件系统或者块设备(处于 mount 状态)。所有访问该文件系统的进程都被列出。
1 2 3 4 5 6 7 8 9 | [root@oracle11g ~]# fuser -km /dev/shm /dev/shm: 3152m 3154m 3156m 3160m 3162m 3164m 3166m 3168m 3170m 3172m 3174m 3176m 3178m 3180m 3182m 3184m 3186m 3193m 3195m 3197m 3199m 3201m 3236m 3248m 3250m 3256m 3292m 4366m [root@oracle11g ~]# umount /dev/shm [root@oracle11g ~]# mount /dev/shm [root@oracle11g ~]# df -lh Filesystem Size Used Avail Use% Mounted on /dev/sda1 23G 20G 1.6G 93% / /dev/sdb1 9.9G 5.8G 3.6G 62% /u02 tmpfs 4.0G 0 4.0G 0% /dev/shm |
再重新启动实例
1 2 3 4 5 6 7 8 | SQL> startup nomount pfile=/u03/app/oracle/11.2.0/db/dbs/initcssb.ora ORACLE instance started. Total System Global Area 1334786560 bytes Fixed Size 1364480 bytes Variable Size 171970048 bytes Database Buffers 1155189248 bytes Redo Buffers 6262784 bytes |
小结:Oracle 11g的AMM内存管理模式就是使用/dev/shm,所以有时候修改MEMORY_TARGET或者MEMORY_MAX_TARGET会出现ORA-00845的错误,在安装配置实例内存时为了避免出现这个故障可以对Linux系统中的/dev/shm进行调整,让其可用大小至少等于实例的sga_max_size。
其它虚拟内核文件系统
虚拟内核文件系统(VirtualKernel File Systems),是指那些是由内核产生但不存在于硬盘上(存在于内存中)的文件系统。例如
1、proc
proc文件系统为操作系统本身和应用程序之间的通信提供了一个安全的接口。通过它里面的一些文件,可以获取系统状态信息并修改某些系统的配置信息。当我们在内核中添加了新功能或设备驱动时,经常需要得到一些系统状态的信息,一般这样的功能需要经过一些像ioctl()这样的系统调用来完成。
2、devfs
我们知道,/dev目录下的每一个文件都对应的是一个设备,devfs也是挂载于/dev目录下。在2.6内核以前使用devfs来提供一种类似于文件的方法来管理位于/dev目录下的所有设备。但是devfs文件系统有一些缺点,有时一个设备映射的设备文件可能不同。例如,我的U盘可能对应sda,也可能对应sdb,没有足够的主/辅设备号,当设备过多的时候,显然这会成为一个问题。
3、sysfs
为了克服devfs的上述问题,2.6内核引入了一个新的文件系统sysfs,它挂载于/sys目录下。sysfs文件系统把连接在系统上的设备和总线组织成为一个分级的文件,用户空间的程序同样可以利用这些信息,以实现和内核的交互。sysfs文件系统是当前系统上实际设备树的一个直观反映,它是通过kobject子系统来建立这个信息的,当一个kobject被创建的时候,对应的文件和目录也就被创建了。
4、tmpfs
tmpfs(temporary filesystem)是Linux特有的文件系统,标准挂载点是/dev/shm.