centos caplock capslock中文是什么意思
Linux系统的OOM Killer处理机制
最近有位 VPS客户抱怨 MySQL无缘无故挂掉,还有位客户抱怨 VPS经常死机,登陆到终端看了一下,都是常见的 Out of memory问题。这通常是因为某时刻应用程序大量请求内存导致系统内存不足造成的,这通常会触发 Linux内核里的 Out of Memory(OOM) killer,OOM killer会杀掉某个进程以腾出内存留给系统用,不致于让系统立刻崩溃。如果检查相关的日志文件(/var/log/messages)就会看到下面类似的 Out of memory: Kill process信息:
...
Out of memory: Kill process 9682(mysqld) score 9 or sacrifice child
Killed process 9682, UID 27,(mysqld) total-vm:47388kB, anon-rss:3744kB, file-rss:80kB
httpd invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
httpd cpuset=/ mems_allowed=0
Pid: 8911, comm: httpd Not tainted 2.6.32-279.1.1.el6.i686#1
...
21556 total pagecache pages
21049 pages in swap cache
Swap cache stats: add 12819103, delete 12798054, find 3188096/4634617
Free swap= 0kB
Total swap= 524280kB
131071 pages RAM
0 pages HighMem
3673 pages reserved
67960 pages shared
124940 pages non-shared
Linux内核根据应用程序的要求分配内存,通常来说应用程序分配了内存但是并没有实际全部使用,为了提高性能,这部分没用的内存可以留作它用,这部分内存是属于每个进程的,内核直接回收利用的话比较麻烦,所以内核采用一种过度分配内存(over-commit memory)的办法来间接利用这部分“空闲”的内存,提高整体内存的使用效率。一般来说这样做没有问题,但当大多数应用程序都消耗完自己的内存的时候麻烦就来了,因为这些应用程序的内存需求加起来超出了物理内存(包括 swap)的容量,内核(OOM killer)必须杀掉一些进程才能腾出空间保障系统正常运行。用银行的例子来讲可能更容易懂一些,部分人取钱的时候银行不怕,银行有足够的存款应付,当全国人民(或者绝大多数)都取钱而且每个人都想把自己钱取完的时候银行的麻烦就来了,银行实际上是没有这么多钱给大家取的。
内核检测到系统内存不足、挑选并杀掉某个进程的过程可以参考内核源代码 linux/mm/oom_kill.c,当系统内存不足的时候,out_of_memory()被触发,然后调用 select_bad_process()选择一个“bad”进程杀掉,如何判断和选择一个“bad”进程呢,总不能随机选吧?挑选的过程由 oom_badness()决定,挑选的算法和想法都很简单很朴实:最 bad的那个进程就是那个最占用内存的进程。
/**
* oom_badness- heuristic function to determine which candidate task to kill
*@p: task struct of which task we should calculate
*@totalpages: total present RAM allowed for page allocation
*
* The heuristic for determining which task to kill is made to be as simple and
* predictable as possible. The goal is to return the highest value for the
* task consuming the most memory to avoid subsequent oom failures.
*/
unsigned long oom_badness(struct task_struct*p, struct mem_cgroup*memcg,
const nodemask_t*nodemask, unsigned long totalpages)
{
long points;
long adj;
if(oom_unkillable_task(p, memcg, nodemask))
return 0;
p= find_lock_task_mm(p);
if(!p)
return 0;
adj=(long)p-signal-oom_score_adj;
if(adj== OOM_SCORE_ADJ_MIN){
task_unlock(p);
return 0;
}
/*
* The baseline for the badness score is the proportion of RAM that each
* task's rss, pagetable and swap space use.
*/
points= get_mm_rss(p-mm)+ p-mm-nr_ptes+
get_mm_counter(p-mm, MM_SWAPENTS);
task_unlock(p);
/*
* Root processes get 3% bonus, just like the __vm_enough_memory()
* implementation used by LSMs.
*/
if(has_capability_noaudit(p, CAP_SYS_ADMIN))
adj-= 30;
/* Normalize to oom_score_adj units*/
adj*= totalpages/ 1000;
points+= adj;
/*
* Never return 0 for an eligible task regardless of the root bonus and
* oom_score_adj(oom_score_adj can't be OOM_SCORE_ADJ_MIN here).
*/
return points 0? points: 1;
}
上面代码里的注释写的很明白,理解了这个算法我们就理解了为啥 MySQL躺着也能中枪了,因为它的体积总是最大(一般来说它在系统上占用内存最多),所以如果 Out of Memeory(OOM)的话总是不幸第一个被 kill掉。解决这个问题最简单的办法就是增加内存,或者想办法优化 MySQL使其占用更少的内存,除了优化 MySQL外还可以优化系统(优化 Debian 5,优化 CentOS 5.x),让系统尽可能使用少的内存以便应用程序(如 MySQL)能使用更多的内存,还有一个临时的办法就是调整内核参数,让 MySQL进程不容易被 OOM killer发现。
我们可以通过一些内核参数来调整 OOM killer的行为,避免系统在那里不停的杀进程。比如我们可以在触发 OOM后立刻触发 kernel panic,kernel panic 10秒后自动重启系统。
# sysctl-w vm.panic_on_oom=1
vm.panic_on_oom= 1
# sysctl-w kernel.panic=10
kernel.panic= 10
# echo"vm.panic_on_oom=1"/etc/sysctl.conf
# echo"kernel.panic=10"/etc/sysctl.conf
从上面的 oom_kill.c代码里可以看到 oom_badness()给每个进程打分,根据 points的高低来决定杀哪个进程,这个 points可以根据 adj调节,root权限的进程通常被认为很重要,不应该被轻易杀掉,所以打分的时候可以得到 3%的优惠(adj-= 30;分数越低越不容易被杀掉)。我们可以在用户空间通过操作每个进程的 oom_adj内核参数来决定哪些进程不这么容易被 OOM killer选中杀掉。比如,如果不想 MySQL进程被轻易杀掉的话可以找到 MySQL运行的进程号后,调整 oom_score_adj为-15(注意 points越小越不容易被杀):
# ps aux| grep mysqld
mysql 2196 1.6 2.1 623800 44876? Ssl 09:42 0:00/usr/sbin/mysqld
# cat/proc/2196/oom_score_adj
0
# echo-15/proc/2196/oom_score_adj
当然,如果需要的话可以完全关闭 OOM killer(不推荐用在生产环境):
# sysctl-w vm.overcommit_memory=2
# echo"vm.overcommit_memory=2"/etc/sysctl.conf
我们知道了在用户空间可以通过操作每个进程的 oom_adj内核参数来调整进程的分数,这个分数也可以通过 oom_score这个内核参数看到,比如查看进程号为981的 omm_score,这个分数被上面提到的 omm_score_adj参数调整后(-15),就变成了3:
# cat/proc/981/oom_score
18
# echo-15/proc/981/oom_score_adj
# cat/proc/981/oom_score
3
下面这个 bash脚本可用来打印当前系统上 oom_score分数最高(最容易被 OOM Killer杀掉)的进程:
# vi oomscore.sh
#!/bin/bash
for proc in$(find/proc-maxdepth 1-regex'/proc/[0-9]+'); do
printf"%2d%5d%sn"
"$(cat$proc/oom_score)"
"$(basename$proc)"
"$(cat$proc/cmdline| tr''''| head-c 50)"
done 2/dev/null| sort-nr| head-n 10
# chmod+x oomscore.sh
#./oomscore.sh
18 981/usr/sbin/mysqld
4 31359-bash
4 31056-bash
1 31358 sshd: root@pts/6
1 31244 sshd: vpsee [priv]
1 31159-bash
1 31158 sudo-i
1 31055 sshd: root@pts/3
1 30912 sshd: vpsee [priv]
1 29547/usr/sbin/sshd-D
mysql pxc程序要做哪些修改
PXC简介
Percona XtraDB Cluster(简称PXC集群)提供了MySQL高可用的一种实现方法。
1.集群是有节点组成的,推荐配置至少3个节点,但是也可以运行在2个节点上。
2.每个节点都是普通的mysql/percona服务器,可以将现有的数据库服务器组成集群,反之,也可以将集群拆分成单独的服务器。
3.每个节点都包含完整的数据副本。
PXC集群主要由两部分组成:Percona Server with XtraDB和Write Set Replication patches(使用了Galera library,一个通用的用于事务型应用的同步、多主复制插件)。
PXC特性:
1,同步复制,事务要么在所有节点提交或不提交。
2,多主复制,可以在任意节点进行写操作。
3,在从服务器上并行应用事件,真正意义上的并行复制。
4,节点自动配置,数据一致性,不再是异步复制。
PXC劣势:
1、当前版本(5.6.20)的复制只支持InnoDB引擎,其他存储引擎的更改不复制。然而,DDL(Data Definition Language)语句在statement级别被复制,并且,对mysql.*表的更改会基于此被复制。例如CREATE USER...语句会被复制,但是 INSERT INTO mysql.user...语句则不会。(也可以通过wsrep_replicate_myisam参数开启myisam引擎的复制,但这是一个实验性的参数)。
2、PXC集群一致性控制机制,事有可能被终止,原因如下:集群允许在两个节点上同时执行操作同一行的两个事务,但是只有一个能执行成功,另一个会被终止,集群会给被终止的客户端返回死锁错误(Error: 1213 SQLSTATE: 40001(ER_LOCK_DEADLOCK)).
3、写入效率取决于节点中最弱的一台,因为PXC集群采用的是强一致性原则,一个更改操作在所有节点都成功才算执行成功。
原理描述
分布式系统的CAP理论:
C一致性,所有的节点数据一致
A可用性,一个或者多个节点失效,不影响服务请求P分区容忍性,节点间的连接失效,仍然可以处理请求任何一个分布式系统,需要满足这三个中的两个安装部署
环境描述
三个node节点
node#1
hostname: percona1
IP: 192.168.100.7
node#2
hostname: percona2
IP: 192.168.100.8
node#3
hostname: percona3
IP: 192.168.100.9
基础环境包
可以选择源码或者yum,在此使用yum安装。
三个node节点都要执行以下操作。
基础环境
yum-y groupinstall Base Compatibility libraries Debugging Tools Dial-up Networking suppport Hardware monitoring utilities Performance Tools Development tools组件安装
yum install install Percona-XtraDB-Cluster-55-y
数据库配置
选择一个node作为名义上的master,咱们以node1为master,以下操作只在node1上执行。
只需要修改mysql的配置文件--/etc/my.cnf
说明:这里的IP地址是内网地址。
[root@i-kysyolko~]# cat/etc/my.cnf
# Template my.cnf for PXC
# Edit to your requirements.
[mysqld]
datadir=/var/lib/mysql
user=mysql
# Path to Galera library
wsrep_provider=/usr/lib64/libgalera_smm.so# Cluster connection URL contains the IPs of node#1, node#2 and node#3wsrep_cluster_address=gcomm://192.168.100.7,192.168.100.8,192.168.100.9# In order for Galera to work correctly binlog format should be ROWbinlog_format=ROW
# MyISAM storage engine has only experimental supportdefault_storage_engine=InnoDB
# This changes how InnoDB autoincrement locks are managed and is a requirement for Galerainnodb_autoinc_lock_mode=2
# Node#1 address
wsrep_node_address=192.168.100.7
# SST method
wsrep_sst_method=xtrabackup-v2
# Cluster name
wsrep_cluster_name=my_centos_cluster
# Authentication for SST method
wsrep_sst_auth="sstuser:s3cret"
[mysqld_safe]
pid-file=/run/mysqld/mysql.pid
syslog
!includedir/etc/my.cnf.d
启动数据库
CentOS6:/etc/init.d/mysql bootstrap-pxc
CentOS7:systemctl start mysql@bootstrap.service配置数据库
mysql> show status like'wsrep%';
+----------------------------+--------------------------------------+| Variable_name| Value|
+----------------------------+--------------------------------------+| wsrep_local_state_uuid| c2883338-834d-11e2-0800-03c9c68e41ec|...
| wsrep_local_state| 4|
| wsrep_local_state_comment| Synced|
...
| wsrep_cluster_size| 1#主要看这里|
| wsrep_cluster_status| Primary|
| wsrep_connected| ON|
...
| wsrep_ready| ON|
+----------------------------+--------------------------------------+40 rows in set(0.01 sec)
#数据库用户名密码的设置
mysql@percona1> UPDATE mysql.user SET password=PASSWORD("Passw0rd") where user='root';#创建、授权、同步账号
mysql@percona1> CREATE USER'sstuser'@'localhost' IDENTIFIED BY's3cret';mysql@percona1> GRANT RELOAD, LOCK TABLES, REPLICATION CLIENT ON*.* TO'sstuser'@'localhost';mysql@percona1> FLUSH PRIVILEGES;
node2、node3节点配置
接下来进行其它节点的配置,上面的组件都已经安装完成。现在直接进行数据库的配置。
只需要修改第26行,当前node的IP地址。两个node都是只是修改这个地址即可。
wsrep_node_address=192.168.100.8
[root@i-kysyolko~]# cat/etc/my.cnf
# Template my.cnf for PXC
# Edit to your requirements.
[mysqld]
datadir=/var/lib/mysql
user=mysql
# Path to Galera library
wsrep_provider=/usr/lib64/libgalera_smm.so# Cluster connection URL contains the IPs of node#1, node#2 and node#3wsrep_cluster_address=gcomm://192.168.100.7,192.168.100.8,192.168.100.9# In order for Galera to work correctly binlog format should be ROWbinlog_format=ROW
# MyISAM storage engine has only experimental supportdefault_storage_engine=InnoDB
# This changes how InnoDB autoincrement locks are managed and is a requirement for Galerainnodb_autoinc_lock_mode=2
# Node#1 address
wsrep_node_address=192.168.100.8
# SST method
wsrep_sst_method=xtrabackup-v2
# Cluster name
wsrep_cluster_name=my_centos_cluster
# Authentication for SST method
wsrep_sst_auth="sstuser:s3cret"
[mysqld_safe]
pid-file=/run/mysqld/mysql.pid
syslog
!includedir/etc/my.cnf.d
启动数据库
CentOS6:/etc/init.d/mysql start
CentOS7:systemctl start mysql.service
说明:
1、除了名义上的master之外,其它的node节点只需要启动mysql即可。
2、节点的数据库的登陆和master节点的用户名密码一致,自动同步。所以其它的节点数据库用户名密码无须重新设置。
测试
在任意一个node上,进行操作,然后去其它的节点上看是否取得相同的结果