0
点赞
收藏
分享

微信扫一扫

MYSQL 主库操作大表DDL ,从库崩溃与系统参数错误设置

MYSQL  主库操作大表DDL ,从库崩溃与系统参数错误设置_mysql


事情是这样的,一个用户测试UAT库,从库无故的频繁的报错

MYSQL  主库操作大表DDL ,从库崩溃与系统参数错误设置_内存分配_02

MYSQL  主库操作大表DDL ,从库崩溃与系统参数错误设置_mysql_03

而内存本身是OK的。但为什么是这样的 MYSQL 的版本是官版的8.011

MYSQL  主库操作大表DDL ,从库崩溃与系统参数错误设置_应用程序_04


首先我这边在拿到这个问题,想通过PERCONA 的工具集中的pt-pmp 来进行分析,但是在启动pt-pmp 后发现无法运行,直接报 virtual memory exhausted


MYSQL  主库操作大表DDL ,从库崩溃与系统参数错误设置_mysql_05


但问题是内存没有用完,我们也有SWAP呀, 到底就怎么就无法分片内存了。这里突然想起之前看到过的一篇文章,是不是因为 overcommit_memory的配置有问题,导致这个明明有内存,但就是无法分配的问题。


首先我们再熟悉一下overcommit  的值为0 1 2 

默认大部分系统选择为 0 , 官方文档的描述为适用于典型的系统,对严重超出预期的内存的分配会拒绝,并且会尽量少的使用SWAP 的内存空间

 1  则是一个特别的列子,他并不关心系统的内存是否已经超分了,这样的配置仅仅适用于一些特别的应用程序。

2  则是和 1 的反例,他提供的内存分配仅仅会对整体的系统的50%进行分配, SWAP + 整体的内存的 50% 是他最多能分配的,当无法对应用程序分配内存,系统并不会OOM应用,但应用会接受到一个内存分配的错误。


下面我第一个反应是查询 /proc/sys/vm/overcommit_memory ,果然里面的状态是 2 . 

马上修改参数  sudo  vi /etc/sysctl.conf

然后在执行 sysctl -p  


再次启动PT-PMP 命令


pt-pmp --binary mysqld --iterations 2 --interval 1  --save-samples mysql.txt

MYSQL  主库操作大表DDL ,从库崩溃与系统参数错误设置_应用程序_06

在修改后

MYSQL  主库操作大表DDL ,从库崩溃与系统参数错误设置_内存分配_07


在查看MYSQL 的错误日志,,从修改后,系统目前也就没有错误了.  后来其他的DBA 想起来当初是为了测试这个参数对数据库的影响,而调整了参数. 忘记改回来了.不过也好,通过这个事情也彻彻底底的弄清楚 overcommit 参数如果在默认情况下设置成 2 ,MYSQL 可能会发生的问题.


相关的代码


  1. int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)
  2. {
  3. unsigned long free, allowed;

  4. vm_acct_memory(pages);

  5. /*
  6. * Sometimes we want to use more memory than we have
  7. */
  8. if (sysctl_overcommit_memory == OVERCOMMIT_ALWAYS) //overcommit_memory=1,直接返回成功,不做任何限制。
  9. return 0;

  10. if (sysctl_overcommit_memory == OVERCOMMIT_GUESS) { //overcommit_memory=0,启发式方式,根据当前系统中空闲内存状况来决定是否可以分配内存。
  11. unsigned long n;

  12. free= global_page_state(NR_FILE_PAGES);
  13. free+= nr_swap_pages;

  14. /*
  15. * Any slabs which are created with the
  16. * SLAB_RECLAIM_ACCOUNT flag claim to have contents
  17. * which are reclaimable, under pressure. The dentry
  18. * cache and most inode caches should fall into this
  19. */
  20. free+= global_page_state(NR_SLAB_RECLAIMABLE)

  21. /*
  22. * Leave the last 3% for root
  23. */
  24. if (!cap_sys_admin)
  25. free-= free / 32; //root用户可以在free更少(3%)的时候,分配内存。

  26. if (free > pages) // pages为需要分配的内存大小,free为根据一定规则算出来的“空闲内存大小”,第一次free仅为NR_FILE_PAGES+NR_SLAB_RECLAIMABLE,由于直接或者系统中“实际空闲”内存代价比较大,所以进行分阶判断,提高效率。
  27. return 0;

  28. /*
  29. * nr_free_pages() is very expensive on large systems,
  30. * only call if we're about to fail.
  31. */
  32. n = nr_free_pages(); //当第一次判断不满足内存分配条件时,再进行“实际空闲”内存的获取操作。

  33. /*
  34. * Leave reserved pages. The pages are not for anonymous pages.
  35. */
  36. if (n <= totalreserve_pages)
  37. goto error;
  38. else
  39. n -= totalreserve_pages;

  40. /*
  41. * Leave the last 3% for root
  42. */
  43. if (!cap_sys_admin)
  44. n -= n / 32;
  45. free += n;

  46. if (free > pages)
  47. return 0;

  48. goto error;
  49. }

  50. allowed = (totalram_pages - hugetlb_total_pages()) //当overcommit_memory=2时,根据系统中虚拟地址空间的总量来进行限制。
  51. * sysctl_overcommit_ratio / 100;
  52. /*
  53. * Leave the last 3% for root
  54. */
  55. if (!cap_sys_admin)
  56. allowed -= allowed / 32;
  57. allowed += total_swap_pages;

  58. /* Don't let a single process grow too big:
  59. leave 3% of the size of this process for other processes */
  60. if (mm)
  61. allowed-= mm->total_vm / 32;

  62. if (percpu_counter_read_positive(&vm_committed_as) < allowed)
  63. return 0;
  64. error:
  65. vm_unacct_memory(pages);

  66. return-ENOMEM;
  67. }


MYSQL  主库操作大表DDL ,从库崩溃与系统参数错误设置_内存分配_08


举报

相关推荐

0 条评论