首页 > 数据库 > MySQL > 正文

LINUX系统编程 SWAP原理以及和数据库 MYSQL ORACLE联系

2024-07-24 12:31:39
字体:
来源:转载
供稿:网友
       作为一位DBA长期以来一直受到一些关于SWAP使用的问题,比如如下问题:
      1、为了我 free 中buffer/cache明明还有空间为什么SWAP使用了?
      2、哪个(些)进程使用了最多的SWAP?
      3、如果在ORACLE或者MYSQL避免使用SWAP?
      4、为什么要使用直接路径绕过操作系统缓冲(O_DIRECT)?
      5、ORACLE 11G使用tmpfs虚拟文件系统,内存可能被SWAP出吗?
      6、设置/proc/sys/vm/swappiness为0后有什么风险?
 
       或者有误的地方,望指出共同讨论。如果特别有兴趣请自行参考<<深入理解liunx内核>>类似书籍。
 
1、LINUX 高速页面缓冲与数据库BUFFER的关系
为了阐明这些问题,不得不从LINUX页高速缓冲说起,在数据库中我们都知道有
一块非常大的缓冲区用于存放最近访问的数据,如ORACLE的BUFFER_CACHE、INNODB
的innodb_buffer_pool_size,这片区域至关重要,直接影响到数据库物理读取的可能性。
所以一般数据库指导意见都为系统物理内存的60%以上(当然ORACLE 还有share_pool
一般ORACLE建议memory_target包含SGA+PGA为系统内存60%以上),而在LINUX OS看来
数据软件只是用户态的匿名页空间,既然如此重要LINUX OS当然也是如此,他也
有这样一部分内存为内核态页高速缓存,LINUX 采用一种比较粗狂的分配方式,只要
数据读取(还有预读-局部性原理)它就会进行缓存,它只受限于2个方面
--物理内存大小
--用户态空间占用内存大小
(LINUX系统编程13章)
这样做是因为这样能够大大加快READ(),WIRTE()调用的速度,如果用户态程序没有自己的
缓存的时候,那么热数据缓存在LINUX页高速缓冲中,那么下次读取的时候速度大大加快
那么就数据库而言数据块可能存在于:
DISK DATA PAGE-->KERNAL BUFFER/CACHE PAGE--->USER(DATABASE) BUFFER PAGE
这样一个顺序,这里是我自己的理解,因为我编程的时候也时常自己分配一块内存区域
(malloc族函数)
如果这个时候稍加思考,我们可以看到数据页可能存在于2个地方一个是KERNEL一个是
USER(DATABASE) BUFFER,前者是LINUX OS级别的,后者是DATABASE级别的。在LINUX中
我们通过FREE可以查看到
[root@testmy ~]# free
             total       used       free     shared    buffers     cached
Mem:       4052856    2009000    2043856          0     146404    1327484
-/+ buffers/cache:     535112    3517744
Swap:      8388600          0    8388600
 
--其实如果要看内存剩余空间,这两个FREE都是只有部分参考价值。
另外如果要说buffers和cache的区别,这一点在深入LINUX内核 P607页有相关
的说明,实际上在内核2.4.10后就没有区别了,所以进行描述。
关于内核态、用户态可以参考:
http://blog.itpub.net/7728585/viewspace-2129073/
的部分观点和配图
 
2、为什么数据库可以采用O_DIRECT打开文件模式(linux open() api flag)
--数据库软件有自己的内存块的管理方法,不需要内核态高速缓冲区,这样有浪费内存
  空间的风险。如上:
DISK DATA PAGE-->KERNAL BUFFER/CACHE PAGE--->USER(DATABASE) BUFFER PAGE
我们去掉了>KERNAL BUFFER/CACHE PAGE,直接从DIS DATA PAGE--> USER BUFFER PAGE
--数据库软件有自己的内存块的管理方法,不需要内核态高速缓冲区,这样让READ(),
  WRITE()操作有KERNAL BUFFER/CACHE PAGE这一层额外的开销
  关于这一点可以参考
  http://blog.itpub.net/7728585/viewspace-2129558/
  的部分观点和配图加以理解
 
3、内存不足页回收
   我们知道LINUX内存分配使用伙伴算法,在LINUX这种粗狂的内存分配方式下,一般来说
这种情况下物理内存迟早会全部映射完。这个时候就需要一种制度或者说是算法来进行页
回收,这就是LINUX的PFRA算法
  关于那些页可以回收,还是看一下深入LINUX内核第17章:
  Swappable  Anonymous pages in User Mode address spaces
             Mapped pages of tmpfs filesystem (e.g.,pages of IPC sharedmemory)
 
  实际上这里我们明显看到一个重点用户态的匿名页,匿名页包含了进程了堆和栈空间,
那么数据库的自己分配的内存明显是堆内存,这些空间是可以被交换(swap)的,而内核
太高速缓存的页一般为可同步和可丢弃页。
  接下来释放内存的原则:
  1、首先释放没有任何进程使用的内核态高速缓存页
  2、用户态进程的所有页是可以回收和交换的
  3、回收共享页
  4、根据LRU算法回收内核态高速缓存中的页,优先换出干净页,因为不需要
     写磁盘。
  这里还透露一个ORACLE 11G中使用tmpfs虚拟文件系统也是会被SWAP到交换分区的。
4、交换(swap)和交换倾向
   交换分区用于扩充实际内存的大小,但是他是存在于物理磁盘,它速度可想而知,
也成了DBA非常关注的一个部分,因为一旦使用SWAP那么数据库的性能可想而知。
   前面我们已经描述了用户态内存空间都是可以交换的包括tmpfs虚拟文件系统,
相反内核态高速缓存页反而是不会进入SWAP空间的,他只是在内存不足的情况下
进行同步和回收。
 
  如果交换倾向大于等于100时,内存紧张的时候,页才从用户态内存进行交换出去,
然后释放,如果设置交换值(SWAPPINESS)=0,那么映射比率/2+负荷值不可能大于等于
100,这就不可能让用户态内存交换出去,对于数据库当然是各种buffer_cache,这是
对数据库有利的。
如何修改:
--永久修改
修改 /etc/sysctl.conf 加上:
  vm.swappiness=0
sysctl -p生效
--临时修改
echo 0 > /proc/sys/vm/swappiness
 
5、OOM(out of memory)
    如果交换区已经满了,并且没有内核态高速缓存可以回收和同步,那么就会启用OOM
来删除进程,输入LINUX内核一书用外科医生为病人截肢来比喻,非常恰当,虽然不
情况但是已经没有退路。
    那么如果我们设置了swappiness=0,那么用不了交换区满,因为用户态内存比如数据
占用内存不能使用交换区,感觉这个时候交换已经没用了。这就是一个潜在的风险,但是
对于数据库软件来说,频繁大量的使用SWAP换入换出和DOWN机没什么区别,我就遇到过
大量使用SWAP交换区换出换入页的ORACLE(10GR2)数据库基本动不了的,等待事件为
shared pool、libarycache,最后使用巨页进行解决。
 
   我们可以看到设置为swappiness=0确实加大了OOM的风险,它建议为1最小化swap
 
6、数据库服务器的交换设置
  
--设置O_DIRECT,依赖数据库自身内存,减少内存中数据的冗余浪费内存,减少SWAP使用的可能
 
--设置vm.swappiness=0(或者1),根据交换倾向让用户态内存不交换,如果如此作者认为如果未设置
  O_DIRECT那么应该保证有足够的内存,那么数据库内存最好不要超过物理内存的50%(请各位指点),
  避免出现OOM问题。

(编辑:武林网)

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表