# [FAQ] Memory allocate failed 引起 TiKV 节点重启

## Key Words

TiKV 重启, vm.overcommit_memory

## Description

TiDB 执行 expensive query， 从 TiKV 内存使用监控看，内存使用率并没有达到系统内存峰值，但是 TiKV 服务触发重启。通过系统日志查询 TiKV 服务日志没有看到 OOM 记录。

通过 TiKV Stderr 日志看到系统内存分配不出来, 如下申请内存失败。

```text
memory allocation of 1536 bytes failed
memory allocation of 16 bytes failed
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
fatal runtime error: Rust cannot catch foreign exceptions
memory allocation of 589824 bytes failed
memory allocation of 74256 bytes failed
memory allocation of 262352 bytes failed
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
memory allocation of 148496 bytes failed
memory allocation of 768 bytes failed
memory allocation of 96035 bytes failed
memory allocation of 3072 bytes failed
memory allocation of 215056 bytes failed
memory allocation of 720132 bytes failed 
```

## Content

TiKV 的主机系统内存资源充足情况下，TiKV 服务在处理读写请求无法获取更多的内存分配导致重启，在系统日志 /var/log/dmsg 中提示 `OOM` 记录。此类情况优先排查系统内存的 `overcommit_memory` 配置限制，可以通过 `cat /proc/sys/vm/overcommit_memory` 查看配置情况。

Linux 的 `overcommit_memory` 功能，该配置决定操作系统在应对应用服务申请内存分配过量问题。一般分三种模式：

* 0 – `Heuristic overcommit handling`. 缺省值，它允许 `overcommit`，`Heuristic` 的意思是“试探式的”，内核利用某种算法猜测你的内存申请是否合理，它认为不合理就会拒绝 `overcommit`。如果设置为0，申请的内存无法满足时（根据内部算法），则会触发OOM。
* 1 – `Always overcommit. 允许overcommit`，对内存申请来者不拒。如果设置为1，申请的内存无法满足时（根据内部算法），部分会触发OOM，部分触发重启。
* 2 – `Don’t overcommit. 禁止overcommit`。如果设置为2，申请的内存无法满足时，则禁止分配。那阈值是多少，由内部算法决定。它是通过内核参数 `vm.overcommit_ratio`或 `vm.overcommit_kbytes` 间接设置的，公式如下： `CommitLimit = (Physical RAM * vm.overcommit_ratio / 100) + Swap`

   Tips: `overcommit_ratio` 默认为 50，如有特殊需求，可以自己修改。

TiDB 系统环境配置建议：

Linux 系统日志中没有出现 OOM 记录，因为 /proc/sys/vm/overcommit_memory 为设为 2 了,在内存不足的情况下，/proc/sys/vm/overcommit_memory = 2  会导致 malloc 直接失败，也就是 stderr 中看到的无法分配内存。所以建议将 overcommit_memory 设置为 1。

```yaml
vm.overcommit_memory = 1 # See Segment Host Memory
vm.overcommit_ratio = 50 # See Segment Host Memory
```

> **注意**
>
> - 如果是 overcommit_memory = 2 时，只要超过 overcommit_ratio = 50 （内存使用率超过 50% 以上），TiKV 会因为无法获取内存分配，可能会触发 Panic 或者服务重启。
> - 根据实际 SQL 查询内存使用情况，酌情开启 SWAP 内存参数配置，确保 SQL 正常获取到内存空间。

## Affected Versions

N/A