process 30320 (mysqld) total-vm:91805504kB, anon-rss:55713500kB, file-rss:0kB, shmem-rss:0kB
Nov 27 14:56:00 itstyledb1 systemd: mysqld.service: main process exited, code=killed, status=9/KILL
Nov 27 14:56:00 itstyledb1 systemd: Unit mysqld.service entered failed state.
Nov 27 14:56:00 itstyledb1 systemd: mysqld.service failed.
Nov 27 14:56:00 itstyledb1 systemd: mysqld.service holdoff time over, scheduling restart.
Nov 27 14:56:01 itstyledb1 systemd: Starting MySQL Server...
当out of memory发生时,out_of_memory函数会选择一个内核认为犯有分配过多内存 “罪行”的进程,并杀死该进程。显然 Mysql 就是哪个“罪人”。
随后 MySql 会自动重启。重启以后,内存是下来了,但是临近下班的时候,差不多又又又占满了。
[root@itstyledb1 ~]# free -m
total used free shared buff/cache available
Mem: 55803 54976 241 10 585 349
Swap: 32064 25036 7028
找到MySql进程,执行以下top -p pid,内存使用52.4g
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
935 mysql 20 0 79.7g 52.4g 7336 S 0.3 96.1 255:44.76 mysqld
计算内存使用
1)查看MySQL全局占用多少内存
SELECT (@@innodb_buffer_pool_size
+@@innodb_log_buffer_size
+@@key_buffer_size) / 1024 /1024 AS MEMORY_MB;
查询结果为:
+----------------+
| MEMORY_MB |
+----------------+
| 20512.00000000 |
+----------------+
2)查看performance_schema占用多少内存
SELECT SUBSTRING_INDEX(event_name,'/',2) AS
code_area, sys.format_bytes(SUM(current_alloc))
AS current_alloc
FROM sys.x$memory_global_by_current_bytes
GROUP BY SUBSTRING_INDEX(event_name,'/',2)
ORDER BY SUM(current_alloc) DESC;
查询结果为:
+---------------------------+---------------+
| code_area | current_alloc |
+---------------------------+---------------+
| memory/performance_schema | 349.80 MiB |
+---------------------------+---------------+
3)查看每个线程占用多少内存
SELECT ( ( @@read_buffer_size
+ @@read_rnd_buffer_size
+ @@sort_buffer_size
+ @@join_buffer_size
+ @@binlog_cache_size
+ @@thread_stack
+ @@max_allowed_packet
+ @@net_buffer_length )
) / (1024*1024) AS MEMORY_MB;
查询结果为:
+-----------+
| MEMORY_MB |
+-----------+
| 87.5156 |
+-----------+
查看当前线程
show full processlist
最终结果为:
+-----------+
| MEMORY_MB |
+-----------+
| 87.5156*37|
+-----------+
4)查看 memory 存储引擎占用多少内存
SELECT SUM(max_data_length)/1024/1024 AS MEMORY_MB FROM information_schema.tables WHERE ENGINE='memory';
查询结果为:
+---------------+
| MEMORY_MB |
+---------------+
| 3857.37713909 |
+---------------+
以上四项加起来差不多也就27975MB,差不错28G的样子,但是 MySql 进程显示占用了52.4G,那么剩下24.4G去哪了?
线程池
此线程池非彼连接池,其实两者是有很大区别的,连接池一般在客户端设置,而线程池是在DB服务器上配置;另外连接池可以取到避免了连接频繁创建和销毁,但是无法取到控制MySQL活动线程数的目标,在高并发场景下,无法取到保护DB的作用。比较好的方式是将连接池和线程池结合起来使用。
关于线程池的一些参数:
mysql> show variables like 'thread%';
+-------------------------------+---------------------------+
| Variable_name | Value |
+-------------------------------+---------------------------+
| thread_handling | one-thread-per-connection |
| thread_pool_high_prio_mode | transactions |
| thread_pool_high_prio_tickets | 4294967295 |
| thread_pool_idle_timeout | 60 |
| thread_pool_max_threads | 100000 |
| thread_pool_oversubscribe | 3 |
| thread_pool_size | 12 |
| thread_pool_stall_limit | 500 |
+-------------------------------+---------------------------+
thread_handling:
该参数是配置线程模型,默认情况是one-thread-per-connection,也就是不启用线程池。将该参数设置为pool-of-threads即启用了线程池。
thread_pool_size:
该参数是设置线程池的Group的数量,默认为系统CPU的个数,充分利用CPU资源。
thread_pool_oversubscribe:
该参数设置group中的最大线