21

我有一个 LINUX 服务器运行一个内存占用很大的进程(某种数据库引擎)。此进程分配的内存非常大,需要将其中的一部分换出(分页)。

我想做的是将所有其他进程(或正在运行的进程的子集)的内存页面锁定在内存中,以便只有数据库进程的页面被换出。例如,我想确保我可以继续远程连接并监控机器,而不会受到交换的影响。即,我希望 sshd、X、top、vmstat 等所有页面都驻留在内存中。

在 linux 上有 mlock()、mlockall() 系统调用,它们似乎提供了正确的旋钮来进行固定。不幸的是,在我看来,我需要在每个进程中进行显式调用,并且不能从不同的进程或父进程调用 mlock()(mlock() 不是在 fork() 或 evecve() 之后继承的)。

任何帮助是极大的赞赏。提供虚拟披萨和啤酒:-)。

4

4 回答 4

14

自从我这样做以来已经有一段时间了,所以我可能错过了几个步骤。

制作一个包含如下内容的 GDB 命令文件:

call mlockall(3)
detach

然后在命令行中,找到你要mlock的进程的PID。类型:
gdb --pid [PID] --batch -x [command file]

如果你喜欢pgrep它可能是:
gdb --pid $(pgrep sshd) --batch -x [command file]

于 2012-09-20T20:42:12.047 回答
7

实际上锁定系统上大多数内容的页面似乎有点粗鲁/激烈,更不用说这种机制的滥用似乎必然会导致一些其他意想不到的问题。

理想情况下,您可能真正想要的是控制进程组的“交换性”,以便数据库首先被交换,而基本的系统管理工具是最后一个,并且有一种方法可以做到这一点

于 2012-09-20T20:58:21.837 回答
3

在搜索mlockall信息时,我遇到了这个工具。您也许可以为您的发行版找到它。我只找到了手册页。

http://linux.die.net/man/8/memlockd

于 2012-09-20T20:49:58.627 回答
1

如今,解决这个问题的简单而正确的方法是 cgroup。

只需限制数据库进程的内存使用:

1. create a memory cgroup
    sudo cgcreate -g memory:$test_db -t $User:$User -a $User:$User

2. limit the group's RAM usage to 1G. 
    echo 1000M > /sys/fs/cgroup/memory/$test_db/memory.limit_in_bytes
    or 
    echo 1000M > /sys/fs/cgroup/memory/$test_db/memory.soft_limit_in_bytes

3. run the database program in the $test_db cgroup
   cgexec -g memory:$test_db $db_program_name
于 2018-01-26T03:59:31.917 回答