Mysql 在备份转储期间内存不足(Docker 容器)

Had*_*ien 5 mysql memory containers mysqldump

我们有一个运行 MariaDB 的容器,以及主机上的一些其他小型容器。Mysql 容器被分配了 21G 内存(总共 32G),以及一些其他参数,在 docker-compose 中使用以下命令:

db:
command:
  - --innodb_buffer_pool_size=4294967296
  - --query_cache_size=268435456
  - --tmp_table_size=1073741824
  - --max_heap_table_size=1073741824
  - --table_open_cache=20000
  - --max_connections=1000
  - --performance_schema
mem_limit: 21g
Run Code Online (Sandbox Code Playgroud)

我们遇到的问题是,mysql 容器在某些例行备份操作(即命令)期间内存不足mysqldump,并且容器崩溃。

基本上,在大约一周的使用过程中,容器的内存使用量逐渐上升到 21G,我认为如果我们不启动任何“大”操作,就可以保持这个状态,但如果mysqldump启动命令,则在转储期间的某个时刻,它超过了分配的限制,并且崩溃了(当我们在本周早些时候没有达到约 95% 的内存使用量时,它就不会崩溃)。

我不明白为什么 MySQL 不能更好地管理其内存并释放其中一些内存来启动它需要执行的新命令?

我们尝试将mysqldump命令放在不同的容器中,试图“隔离”这个大操作,但这似乎没有改变任何东西,大部分工作仍然由 Mysql 容器完成,当其他容器执行时,它最终会崩溃倾倒。

我们应该研究什么?我们的设置是否完全不正常?我们在运行 mysqltuner.pl 后设置它们,如果您认为这就是问题所在,我可以重新运行。

我们有大约 700 个数据库,每个数据库大约有 40 个表,平均大约有 10 个并发 mysql 连接,峰值为 30 或 50 个。数据库运行大小在 10Mb 到 200Mb 之间。

任何帮助表示赞赏,谢谢!

Mic*_*ton 6

mysqldump使用该选项运行--quick

默认情况下,mysqldump 尝试一次转储整个表,这意味着它必须将整个表加载到内存中,并且当内存受限时mysqldump可能会失败。该--quick选项切换到按行转储,这会稍微慢一些,并且会生成稍大的转储文件,但使用的内存要少得多。

不,我不知道他们为什么命名该选项--quick


Evo*_*ary 0

Percona 的一篇文章可能会有所帮助:

\n\n

https://www.percona.com/blog/2016/05/03/best-practices-for-configuring-optimal-mysql-memory-usage/

\n\n

这段话似乎部分相关:

\n\n
\n

操作系统配置的下一件事是设置“内存不足”杀手。您可能在内核日志文件中看到过这样的消息:

\n\n

4 月 24 日 02:43:18 db01 内核:内存不足:杀死进程 22211\n (mysqld) 分数 986 或牺牲子进程

\n\n

当 MySQL 本身出现故障时,\xe2\x80\x99 是一件非常合理的事情。\n 然而,\xe2\x80\x99s 也可能真正的问题是你\xe2\x80 的一些批处理\n 活动\x99 正在运行:脚本、备份等。在这种情况下,如果系统没有足够的内存而不是 MySQL,您可能希望终止这些进程。

\n\n

为了使 MySQL 成为不太可能被 OOM Killer 杀死的候选者,您可以通过以下方式调整行为以使 MySQL 不太受欢迎:

\n\n

echo \'-800\' > /proc/$(pidof mysqld)/oom_score_adj

\n\n

这将使 Linux 内核更愿意首先杀死其他大量内存消耗者。

\n\n

=================================================== =====================

\n
\n\n

显然,您希望优先考虑 mysqldump 操作,但如果有其他进程使用内存,您可以终止任何您认为多余的进程,并以更高的优先级终止。

\n\n

我不确定你是如何编写转储脚本的。我认为这可能有助于将转储分成较小的批次组(表/数据库集),以帮助保持内存较高。只是对此的一些想法。

\n