在内存不足时,LightDB会报告out of memory错误。处理方法如下
overcommit参数配置
首先确定系统当前overcommit参数配置vm.overcommit_memory
。
[root@master1 ~]# sysctl -a | grep overcommit
vm.nr_overcommit_hugepages = 0
vm.overcommit_kbytes = 0
vm.overcommit_memory = 1
vm.overcommit_ratio = 50
overcommit机制原理是操作系统在实际内存不足的情况下,允许应用程序超量申请内存。寄希望于应用程序实际不会使用这么多内存。
当vm.overcommit_memory=0
时,操作系统是允许overcommit,但是如果应用程序一次申请太多,就会被拒绝。
当vm.overcommit_memory=1
, 操作系统允许overcommit,应用程序申请多少内存都可以。
当vm.overcommit_memory=2
时,操作系统禁止overcommit, 操作系统有个阈值CommitLimit,已使用内存超过这个阈值,申请内存就会被拒绝(out of memeory).
可以通过以下命令查看系统情况,当已分配内存Committed_AS
接近 CommitLimit
就会发生out of memeory错误。
# grep -i commit /proc/meminfo
CommitLimit: 5967744 kB
Committed_AS: 5363236 kB
CommitLimit 的数值大体上等于 (Physical RAM * vm.overcommit_ratio / 100) + Swap
根据以上公式,在vm.overcommit_memory=2
的情况下,可以适当调高 vm.overcommit_ratio
来提升CommitLimit
进而改善out of memory的问题
当然也可以修改vm.overcommit_memory=1
来允许overcommit
。允许overcommit可以解决out of memeory
问题,但会引入另外一个风险:在内存确实不够用的情况下,操作系统会挑选一些进程来杀死(OOM killer),以释放内存。 程序被杀死后可能会让人误以为程序发生了异常。
OOM杀死进程后,会在/var/log/messages
文件中留下日志,可以查看此日志文件确认是否确实发生了OOM。
调整shared_buffers参数
在数据库服务器上,应先尝试排查是否有其他应用程序过多占用内存,并尝试通过修改配置或者把程序移到其他机器上等方式释放内存。
数据库服务器自身内存占用中共享内存占用较多,共享内存被数据库用于缓存数据,以提升数据库性能。在数据库启动时就会分配全部共享内存。所以可以适当调低数据库共享内存配置,释放一些内存出来。
修改方法为: 编辑$LTDATA/lightdb.conf
中的shared_buffers
参数,然后重启数据库 ,修改此参数后需要重启数据库才能生效。
清理WAL日志缓存
数据库在运行过程中,会不断生成WAL日志文件,写入文件后,操作系统默认会在内存中保留文件的缓存,
但是WAL日志正常情况下不需要被读取,所以可以清理WAL日志文件缓存,避免不必要的占用内存。
LightDB提供了清理脚本 pagecache_manager.sh
,可以通过如下命令启动
nohup pagecache_manager.sh $LTDATA/lt_wal \
true 999999999999 > pageclear`date +"%Y-%m-%d\"`.log &
减少数据库连接
LightDB数据库会为每个数据库连接创建一个进程,每个进程会占用一定的内存空间,可以通过
select count(*) from pg_stat_activity
或者 EM管理平台查看当前活跃会话数,关闭一些不必要的应用,降低会话数量,减少内存使用。