磨砺技术珠矶,践行数据之道,追求卓越价值

回到上一级页面:PostgreSQL内部结构与源代码研究索引页    回到顶级页面:PostgreSQL索引页

[作者 高健@博客园  luckyjackgao@gmail.com]

首先学习网上例子,进行体验性的试验:

首先不限制内存使用来进行下载:

[root@cent6 Desktop]# free -m
total used free shared buffers cached
Mem:
-/+ buffers/cache:
Swap:
[root@cent6 Desktop]#

然后,再下载约700M:

wget http://centos.arcticnetwork.ca/6.4/isos/x86_64/CentOS-6.4-x86_64-LiveCD.iso

然后看内存使用情况:

[root@cent6 Desktop]# free -m
total used free shared buffers cached
Mem:
-/+ buffers/cache:
Swap:
[root@cent6 Desktop]#

确实是用掉了700多M内存。

然后,重新启动,限制内存使用:

[root@cent6 Desktop]# service cgconfig status
Stopped #mount -t cgroup -o memory memcg /cgroup # mkdir /cgroup/GroupA
# echo 10M > /cgroup/GroupA/memory.limit_in_bytes
# echo $$ > /cgroup/GroupA/tasks

然后,再看内存状况:

[root@cent6 Desktop]# free -m
total used free shared buffers cached
Mem:
-/+ buffers/cache:
Swap:
[root@cent6 Desktop]#

再下载约700M:

wget http://centos.arcticnetwork.ca/6.4/isos/x86_64/CentOS-6.4-x86_64-LiveCD.iso

再看内存使用前后对比:

[root@cent6 Desktop]# free -m
total used free shared buffers cached
Mem:
-/+ buffers/cache:
Swap:
[root@cent6 Desktop]#

可以知道,大约的内存使用量为 1525-1494=31M。不过free命令观察到的结果是有误差的,程序执行时间长,free就是一个不断累减的值,由于当前shell被限制使用内存最大10M,那么基数很小的情况下,时间越长,误差越大。

下面,看看对PostgreSQL能否产生良好的限制:

再此之前,通过系统设定来看看对postgres用户进行wget操作时的内存的控制:

[postgres@cent6 Desktop]$ cat /etc/cgconfig.conf
#
# Copyright IBM Corporation. 2007
#
# Authors: Balbir Singh <balbir@linux.vnet.ibm.com>
# This program is free software; you can redistribute it and/or modify it
# under the terms of version 2.1 of the GNU Lesser General Public License
# as published by the Free Software Foundation.
#
# This program is distributed in the hope that it would be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# See man cgconfig.conf for further details.
#
# By default, mount all controllers to /cgroup/<controller> mount {
cpuset = /cgroup/cpuset;
cpu = /cgroup/cpu;
cpuacct = /cgroup/cpuacct;
memory = /cgroup/memory;
devices = /cgroup/devices;
freezer = /cgroup/freezer;
net_cls = /cgroup/net_cls;
blkio = /cgroup/blkio;
} group test1 {
perm {
task{
uid=postgres;
gid=postgres;
} admin{
uid=root;
gid=root;
} } memory {
memory.limit_in_bytes=30M;
}
} [postgres@cent6 Desktop]$

还有一个文件,cgrules.conf,也很重要:

[postgres@cent6 Desktop]$ cat /etc/cgrules.conf
# /etc/cgrules.conf
#
#Each line describes a rule for a user in the forms:
#
#<user> <controllers> <destination>
#<user>:<process name> <controllers> <destination>
#
#Where:
# <user> can be:
# - an user name
# - a group name, with @group syntax
# - the wildcard *, for any user or group.
# - The %, which is equivalent to "ditto". This is useful for
# multiline rules where different cgroups need to be specified
# for various hierarchies for a single user.
#
# <process name> is optional and it can be:
# - a process name
# - a full command path of a process
#
# <controller> can be:
# - comma separated controller names (no spaces)
# - * (for all mounted controllers)
#
# <destination> can be:
# - path with-in the controller hierarchy (ex. pgrp1/gid1/uid1)
#
# Note:
# - It currently has rules based on uids, gids and process name.
#
# - Don't put overlapping rules. First rule which matches the criteria
# will be executed.
#
# - Multiline rules can be specified for specifying different cgroups
# for multiple hierarchies. In the example below, user "peter" has
# specified 2 line rule. First line says put peter's task in test1/
# dir for "cpu" controller and second line says put peter's tasks in
# test2/ dir for memory controller. Make a note of "%" sign in second line.
# This is an indication that it is continuation of previous rule.
#
#
#<user> <controllers> <destination>
#
#john cpu usergroup/faculty/john/
#john:cp cpu usergroup/faculty/john/cp
#@student cpu,memory usergroup/student/
#peter cpu test1/
#% memory test2/
#@root * admingroup/
#* * default/
# End of file
postgres memory test1/
#
[postgres@cent6 Desktop]$

在root用户,设置如下两个服务随系统启动:

chkconfig cgconfig  on

chkconfig cgred on

然后重新启动系统后,用postgres用户进行登录,进行检验:

[postgres@cent6 Desktop]$ free -m
total used free shared buffers cached
Mem: 2006 381 1625 0 25 134
-/+ buffers/cache: 221 1785
[postgres@cent6 Desktop]$ wget http://centos.arcticnetwork.ca/6.4/isos/x86_64/CentOS-6.4-x86_64-LiveCD.iso

执行完毕后,看内存状况,成功。

[postgres@cent6 Desktop]$ free -m
total used free shared buffers cached
Mem: 2006 393 1613 0 28 141
-/+ buffers/cache: 224 1782
Swap: 4031 67 3964
[postgres@cent6 Desktop]$

下面看对postgresql中执行sql 的限制如何:

步骤1:   对/etc/cgconfig.conf 文件和 /etc/cgrules.conf 文件的设置如前所述。
步骤2:   运行前查看内存状况:
[postgres@cent6 Desktop]$ free -m
             total       used       free     shared    buffers     cached
Mem:          2006        384       1622          0         26        138
-/+ buffers/cache:        219       1787
Swap:         4031         87       3944
[postgres@cent6 Desktop]$ 
步骤3: 开始处理大量数据(约600MB)
postgres=# select count(*) from test01;
count
-------
0
(1 row) postgres=# insert into test01 values(generate_series(1,614400),repeat( chr(int4(random()*26)+65),1024));

运行刚刚开始,就出现了如下的错误:

The connection to the server was lost. Attempting reset: Failed.
!>

这和之前碰到的崩溃情形一致。

 
PostgreSQL的log本身是这样的: 
[postgres@cent6 pgsql]$ LOG:  database system was shut down at -- :: CST
LOG: database system is ready to accept connections
LOG: autovacuum launcher started
LOG: server process (PID ) was terminated by signal : Killed
DETAIL: Failed process was running: insert into test01 values(generate_series(,),repeat( chr(int4(random()*)+),));
LOG: terminating any other active server processes
WARNING: terminating connection because of crash of another server process
DETAIL: The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
HINT: In a moment you should be able to reconnect to the database and repeat your command.
FATAL: the database system is in recovery mode
LOG: all server processes terminated; reinitializing
LOG: database system was interrupted; last known up at -- :: CST
LOG: database system was not properly shut down; automatic recovery in progress
LOG: redo starts at /9E807C90
LOG: unexpected pageaddr /946BE000 in log file , segment , offset
LOG: redo done at /9F6BDB50
LOG: database system is ready to accept connections
LOG: autovacuum launcher started

通过dmesg命令,可以看到,发生了Out of Memory错误,这次是 cgroup out of memory

[postgres@cent6 Desktop]$ dmesg | grep post
[ ] postgres
[ ] postgres
[ ] postgres
[ ] postgres
[ ] postgres
[ ] postgres
[ ] postgres
[ ] postgres
[ ] postgres
[ ] postgres
[ ] postgres
[ ] postgres
[ ] postgres
[ ] postgres
[ ] postgres
[ ] postgres
[ ] postgres
[ ] postgres
[ ] postgres
[ ] postgres
[ ] postgres
Memory cgroup out of memory: Kill process (postgres) score or sacrifice child
Killed process , UID , (postgres) total-vm:292300kB, anon-rss:8432kB, file-rss:3712kB
[postgres@cent6 Desktop]$

我怀疑自己的内存开得过小了,影响到一些基本的运行。PostgreSQL本身也需要一些资源(shared_buffers、wal_buffers都需要用一些内存)

所以我调整了参数   memory.limit_in_bytes=300M ,再次运行:
前述的sql问处理1200MB数据,成功结束,内存没有过多增长。

[作者 高健@博客园  luckyjackgao@gmail.com]

回到上一级页面:PostgreSQL内部结构与源代码研究索引页    回到顶级页面:PostgreSQL索引页

磨砺技术珠矶,践行数据之道,追求卓越价值

使用cgroups来控制内存使用的更多相关文章

  1. 在浏览器中将表格导入到本地的EXCEL文件,注意控制内存

    if ($export_flag == 1) { $rr = $this->mdl->test($test); header("Content-Type: application ...

  2. [C++] 重载new和delete——控制内存分配

      1.new和delete表达式的工作机理      1)new表达式实际执行了三步 string *sp=new string("aaaa"); ];//string采用默认初 ...

  3. C++之控制内存分配

    一.内存分配方式 在C++中,内存分成5个区,他们分别是堆.栈.自由存储区.全局/静态存储区和常量存储区.栈:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释 ...

  4. c++控制内存分配

    为了满足应用程序对内存分配的特殊需求,C++允许重载new运算符和delete运算符控制内存分配,通过定位new表达式初始化对象(好处是可以在某些场景下避免重新内存分配的消耗) 1.operate n ...

  5. SQL Server sp_configure 控制内存使用

    背景知识: sp_configure   显示或更改当前服务器的全局配置设置(使用 sp_configure 可以显示或更改服务器级别的设置.) 查看 全局配置值 方法 1.execute sp_co ...

  6. C++ Primer 笔记——控制内存分配

    1.当我们使用一条new表达式时,实际执行了三步操作. new表达式调用一个名为operator new ( 或者operator new[] ) 的标准库函数.该函数分配一块足够大的,原始的,未命名 ...

  7. 【C++ Primer | 19】控制内存分配

    重载new和delete 1. 测试代码: #include<iostream> #include<new> using namespace std; class A { pu ...

  8. 使用cgroups来控制磁盘IO带宽

    磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面:PostgreSQL内部结构与源代码研究索引页    回到顶级页面:PostgreSQL索引页 [作者 高健@博客园  luckyjackga ...

  9. 使用Jprofiler分析Java项目的内存开销情况并利用强制回收控制内存

    一.问题背景 自己开发的Java项目中占用太多的Heap Space.即使在Eclipse的虚拟机参数中设置"-Xms128m -Xms2048m -XX:MetaspaceSize=512 ...

随机推荐

  1. PHP获取当前页面的URL地址

    本文出至:新太潮流网络博客 //获取域名或主机地址 blog.iinu.com.cn echo $_SERVER['HTTP_HOST']."<br>"; //获取网页 ...

  2. 对《SQL Server中tempdb的management》的一些更正和补充

    对<SQL Server中tempdb的management>的一些更正和补充 前几天看了这篇文章:SQL Server中tempdb的management 发现里面有些内容不是很准确 文 ...

  3. java笔记--线程的插队行为

    对线程的插队行为的理解 在编写多线程时,会遇到让一个线程优先于其他线程运行的情况, 此时除了可以设置其优先级高于其他线程外,更直接的方式是使用Thread类的join()方法 --如果朋友您想转载本文 ...

  4. 【gp数据库】OLTP和OLAP区别详解

    原来一直使用Oracle,新公司使用greenplum后发现系统的并发性差很多,后来才了解因为Oracle属于OLTP类型,而gp数据库属于OLAP类型的.具体了解如下: 数据库系统一般分为两种类型, ...

  5. win7下使用手动安装composer

    假设我们的php放置在D:\php 目录下, 1.添加环境变量,桌面--> 我的电脑右键---->属性 2.点击高级系统设置 3.点击环境变量 4.选择path,在变量值里面追加内容:  ...

  6. SpringBoot部署流程

    一.  项目介绍 a)     本项目为SpringBoot项目 b)     使用内置Tomcat容器 一.  操作步骤 a)     配置pom.xml文件,确定打包方式 b)     更改项目返 ...

  7. Linux--安全加固01

    Redhat是目前企业中用的最多的一类Linux,而目前针对Redhat攻击的黑客也越来越多了.我们要如何为这类服务器做好安全加固工作呢? 一. 账户安全 1.1 锁定系统中多余的自建帐号 检查方法: ...

  8. c++作业之圆面积

    代码传送门

  9. SQLException: Io 异常: Connection refused ERR=12514 ERR=1153异常处理过程

    solr更新索引连接数据库地址时发生的错误,数据库拒绝连接,经过调查是因为solr的data-config.xml 文件中配置数据库连接的地方,不应该配置数据库实例名而应该是数据库server_nam ...

  10. Install Weblogic12C

    1. 安装JDK软件 1.1)jdk版本选择 由于jdk编译出class文件是一个二进制文件,其中前四个字节是magic位,第五到第六个字节对应于minor和major.class文件的minor和m ...