释放内存:
sync
echo 3 > /proc/sys/vm/drop_caches
Linux查看Dell服务器型号
命令:
dmidecode | grep "Product Name"
启动nginx,php
/usr/local/webserver/php/sbin/php-fpm start
/usr/local/webserver/nginx/sbin/nginx
重启nginx
/usr/local/webserver/nginx/sbin/nginx –s reload
启动cgi
/usr/local/webserver/nginx/start_perl_cgi.sh restart
查看系统负载:
cat /proc/loadavg
0.0 0.00 0.00 1/283 10904
意思是:前三个是系统负载,1/283中,1代表此时运行队伍中的进程个数,而283是代表此时的进程总数
10904到此为止,最后创建的一个进程ID。
系统装好后,要做的事如下:
关闭防火墙Selinux:
vim /etc/selinux/config
把SELINUX=enforcing改成SELINUX=disabled
更改主机名:
vim /etc/sysconfig/network
修改主机名,不要用localhost
添加hosts主机记录
vim /etc/hosts中,在127.0.0.1后面,添加自己的主机名
创建0-9 a-z目录
for i in `seq 0 9` {a..z};do mkdir -p $i;done:
测试硬盘性能工具:iozone
监视服务器每少上下文切换数次工具:Nmon(很不错的性能监视工具)
#占用内存大小前10的进程
ps -eo comm,size --sort -size | head -10
#占用cpu使用前10的进程
ps -eo comm,pcpu --sort -pcpu | head -10
一、Apache服务优化: 2
1.配置cronolog进行日志轮询 2
2.错误页面优雅显示 2
3.mod_deflate文件压缩功能 3
4.mod_expires缓存功能 4
5.更改apache的默认用户 5
6.worker模式,提升并发数(可以达到2000-5000) 5
7.屏蔽apache版本等敏感信息 6
8.apache目录文件权限设置(root,目录755,文件644) 6
9.开启httpd-mpm.conf 增加连接数 6
10. apache防盗链功能 8
11.禁止目录Index 8
12. 禁止用户覆盖(重载) 8
13.关闭CGI 9
14.避免使用.htaccess文件(分布式配置文件) 9
15. apache的安全模块 9
16.正确途径取得源代码,勤打apache补丁 10
17.apache日志授予root 700权限 10
18.系统内核参数优化 10
19.禁止PHP解析指定站点的目录 10
20.使用tmpfs文件系统替代频繁访问的目录 11
21尽可能减少 HTTP 请求数 11
22使用CDN做网站加速 12
查看你的服务器网络连接状态
netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}‘
◆CLOSED:无连接是活动的或正在进行
◆LISTEN:服务器在等待进入呼叫
◆SYN_RECV:一个连接请求已经到达,等待确认
◆SYN_SENT:应用已经开始,打开一个连接
◆ESTABLISHED:正常数据传输状态
◆FIN_WAIT1:应用说它已经完成
◆FIN_WAIT2:另一边已同意释放
◆ITMED_WAIT:等待所有分组死掉
◆CLOSING:两边同时尝试关闭
◆TIME_WAIT:另一边已初始化一个释放
◆LAST_ACK:等待所有分组死掉
ESTABLISHED
的值其实也是当前的并发数,这个可重点关注下;另外,可关注下TIME——WAIT这项的数值。Linux下高并发的Squid服务器,TCP
TIME_WAIT套接字数量经常达到两、三万,服务器很容易被拖死。通过修改Linux内核参数,可以减少Squid服务器的TIME_WAIT套接字
数量,具体可参见我的另一篇文章:优化Linux生产服务器的经验之谈。
#查看系统本地可用端口极限值
cat /proc/sys/net/ipv4/ip_local_port_range
寻找恶意IP并用iptables禁止掉
netstat
-an| grep :80 | grep -v 127.0.0.1 |awk ‘{ print $5 }‘ | sort|awk -F:
‘{print $1,$4}‘ | uniq -c | awk ‘$1 >50 {print $1,$2}‘
4.5备份单个数据库
mysqldump -u 用户 –p’密码’ --default-character-set=latin1 数据库名 > 备份文件名(数据库默认编码是latin1)
普通备份:
mysqldump -uroot -p‘oldboy123‘ oldboy > /server/bak/oldboy.sql
压缩备份:
mysqldump -uroot -p‘oldboy123‘ oldboy |gzip > /server/bak/oldboy.sql.gz
设置字符集备份:
mysqldump -uroot -p‘oldboy123‘ oldboy --default-character-set=gbk |gzip > /server/bak/oldboy.sql.gz
执行结果:
[[email protected] ~]# mkdir /server/bak -p
[[email protected] ~]# mysqldump -uroot -p‘oldboy123‘ oldboy > /server/ba
backup/ bak/
[[email protected] ~]# mysqldump -uroot -p‘oldboy123‘ oldboy > /server/bak/oldboy.sql
[[email protected] ~]# mysqldump -uroot -p‘oldboy123‘ oldboy |gzip > /server/bak/oldboy.sql.gz
[[email protected] ~]# ls -l /server/bak/
total 8
-rw-r--r-- 1 root root 1991 Apr 9 00:51 oldboy.sql
-rw-r--r-- 1 root root 801 Apr 9 00:51 oldboy.sql.gz
4.6 mysqldump在做啥?
mysqldump实际上就是把数据从mysql库里以逻辑的sql语句的形式导出。
备份的数据过滤掉注释:
[[email protected] ~]# egrep -v "\*|--|^$" /server/bak/oldboy.sql
DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
`id` int(4) NOT NULL AUTO_INCREMENT,
`name` char(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=gbk;
LOCK TABLES `test` WRITE;
INSERT
INTO `test` VALUES
(1,‘zhaoyue‘),(2,‘jesse‘),(4,‘elain‘),(5,‘wodi‘),(6,‘yingsui‘),
(7,‘zhangyang‘),(8,‘zaixiangpan‘),(9,‘??????‘),(10,‘鑰佺敺瀛?),(11,‘鎴?);
<==这里是乱码,是因为导出时的格式没加字符集,而系统当前字符集又是zh_cn.gb18030格式,一般恢复到数据库里会正常,只是系统外查
看不正常而已。另外insert是批量插入的方式,这样在恢复时效率很高。
UNLOCK TABLES;
提示:看到了吧,就是我们曾经插入的表和数据。
[[email protected] ~]# mysqldump -uroot -p‘oldboy123‘ oldboy --default-character-set=gbk > /server/bak/oldboy-gbk.sql
[[email protected] ~]# egrep -v "\*|--|^$" /server/bak/oldboy-gbk.sql
DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
`id` int(4) NOT NULL AUTO_INCREMENT,
`name` char(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=gbk;
LOCK TABLES `test` WRITE;
INSERT
INTO `test` VALUES
(1,‘zhaoyue‘),(2,‘jesse‘),(4,‘elain‘),(5,‘wodi‘),(6,‘yingsui‘),(7,‘zhangyang‘),(8,‘zaixiangpan‘),(9,‘??????‘),(10,‘老男孩‘),(11,‘我‘); <==老男孩查看不是乱码了。其他乱码是当初插入时就有问题的。
UNLOCK TABLES;
4.7备份多个库
[[email protected] ~]# mysqldump -uroot -p‘oldboy123‘ -B oldboy mysql --default-character-set=gbk > /server/bak/oldboy-gbk-muli.sql
提示:-B参数是关键,表示接多个库。
※※※※※(生产环境常用)
-B, --databases To dump several databases. Note the difference in usage;
In this case no tables are given. All name arguments are
regarded as databasenames. ‘USE db_name;‘ will be
included in the output.
参数说明:该参数用于导出若干个数据库,在备份结果中会加入USE db_name和CREATE DATABASE `db_name`;
-B后的参数都将被作为数据库名。该参数比较常用。当-B后的数据库列全时 同 -A参数。请看-A的说明。
4.8备份单个表
mysqldump -u 用户名 -p 数据库名 表名> 备份的文件名
mysqldump -u root -p oldboy test> oldboy_oldboy.sql
执行结果:
[[email protected] ~]# mysqldump -uroot -p‘oldboy123‘ oldboy test --default-character-set=gbk > /server/bak/oldboy-gbk-single.sql
提示:无-B参数,库oldboy后面就是test表了。
4.9备份多个表
[[email protected]
~]# mysqldump -uroot -p‘oldboy123‘ oldboy test ett
--default-character-set=gbk > /server/bak/oldboy-gbk-muti-tables.sql
[[email protected] ~]# egrep -v "\*|--|^$" /server/bak/oldboy-gbk-muti-tables.sql
DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
`id` int(4) NOT NULL AUTO_INCREMENT,
`name` char(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=gbk;
LOCK TABLES `test` WRITE;
INSERT
INTO `test` VALUES
(1,‘zhaoyue‘),(2,‘jesse‘),(4,‘elain‘),(5,‘wodi‘),(6,‘yingsui‘),
(7,‘zhangyang‘),(8,‘zaixiangpan‘),(9,‘??????‘),(10,‘老男孩‘),(11,‘我‘);
UNLOCK TABLES;
DROP TABLE IF EXISTS `ett`;
CREATE TABLE `ett` (
`id` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=gbk;
LOCK TABLES `ett` WRITE;
UNLOCK TABLES;
4.10备份数据库结构(不包含数据)
mysqldump -uroot -d -p‘oldboy‘ oldboy oldboy> oldboy_oldboy.sql
-d 只备份表结构
[[email protected] ~]# mysqldump -uroot -p‘oldboy123‘ -d oldboy >/tmp/desc.sql
[[email protected] ~]# egrep -v "\*|--|^$" /tmp/desc.sql
DROP TABLE IF EXISTS `ett`;
CREATE TABLE `ett` (
`id` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=gbk;
DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
`id` int(4) NOT NULL AUTO_INCREMENT,
`name` char(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=gbk;
更多用法可以 执行 mysqldump –help 查询。有关mysql和mysqldump同学们要详细总结。
5恢复数据库
5.1 source命令恢复
进入mysql数据库控制台,mysql -u root -p
mysql>use 数据库
然后使用source命令,后面参数为脚本文件(如这里用到的.sql)
mysql>source oldboy_db.sql #这个文件是系统路径。
[[email protected] bak]# mysql -uroot -p‘oldboy123‘
Welcome to the MySQL monitor. Commands end with ; or \g.
...skip...
Type ‘help;‘ or ‘\h‘ for help. Type ‘\c‘ to clear the current input statement.
mysql> use oldboy
Database changed
mysql> show tables;
+------------------+
| Tables_in_oldboy |
+------------------+
| ett |
| test |
+------------------+
2 rows in set (0.00 sec)
mysql> drop tables test;
Query OK, 0 rows affected (0.01 sec)
mysql> system ls .
oldboy-gbk-muli.sql oldboy-gbk-single.sql oldboy.sql
oldboy-gbk-muti-tables.sql oldboy-gbk.sql oldboy.sql.gz
mysql> source ./oldboy.sql <==还是用第一版没加字符集的备份,就是备份后查看乱码的备份。
Query OK, 0 rows affected (0.00 sec)
...skip...
Query OK, 0 rows affected (0.00 sec)
Q...skip...
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test;
+----+-------------+
| id | name |
+----+-------------+
| 1 | zhaoyue |
| 2 | jesse |
| 4 | elain |
| 5 | wodi |
| 6 | yingsui |
| 7 | zhangyang |
| 8 | zaixiangpan |
| 9 | ?????? |
| 10 | ??? |<==乱码
| 11 | ? |
+----+-------------+
10 rows in set (0.00 sec)
mysql> set names gbk;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test;
+----+-------------+
| id | name |
+----+-------------+
| 1 | zhaoyue |
| 2 | jesse |
| 4 | elain |
| 5 | wodi |
| 6 | yingsui |
| 7 | zhangyang |
| 8 | zaixiangpan |
| 9 | ?????? |
| 10 | 老男孩 | <==仍然是正常的,就是说备份不加字符集导出,将来恢复不会影响恢复的数据,但是备份后查看文件会乱码。
| 11 | 我 |
+----+-------------+
10 rows in set (0.00 sec)
5.2 mysql命令恢复(标准)
mysql -u oldboy -p‘oldboy‘ oldboy < oldboy.sql
mysql> system mysql -uroot -p‘oldboy123‘ oldboy < oldboy-gbk.sql <==导入的是备份时加字符集的版本。
mysql> select * from test;
+----+-------------+
| id | name |
+----+-------------+
| 1 | zhaoyue |
| 2 | jesse |
| 4 | elain |
| 5 | wodi |
| 6 | yingsui |
| 7 | zhangyang |
| 8 | zaixiangpan |
| 9 | ?????? |
| 10 | 老男孩 |<==因为上文source导入时已经set names gbk了, 所以此处不是乱码。
| 11 | 我 |
+----+-------------+
10 rows in set (0.00 sec)
2.1.1.1 MyISAM引擎备份
由于MyISAM引擎为表级锁,因此,在备份时需要防止在备份期间数据写入而导致不一致,所以,在备份时使用--lock-all-tables加上读锁
mysqldump -A -F -B --lock-all-tables |gzip >/data/backup/$(date +%F).tar.gz
特别提示:有关MyISAM和InnoDB引擎的差别和在工作中如何选择,在前面的文章已经详细讲解过了,这里就不在讲了。
2.1.1.2 InnoDB引擎备份
InnoDB引擎为行锁,因此,备份时可以不对数据库加锁的操作,可以加选项--single-transaction进行备份:
mysqldump -A -F -B --single-transaction |gzip >/data/backup/$(date +%F).tar.gz
特别注意:
1)--single-transaction仅适用于InnoDB引擎。
生产环境mysqldump备份命令
mysqldump
–u root –p –S /data/3306/mysql.sock –default-character-set=gbk
–single-transaction –F –B oldboy|gzip > /server/backup/mysql_$(date
+%F).sql.gz
:注
-F:刷新bin-log参数,数据库备份完以后,会刷新bin-log
增量备份:
更新bin-log:
mysqladmin –uroot –p –S /data/3306/mysql.sock flush-logs
如生成mysql-bin.000004文件
把生成的最新mysql-bin.000004文件,CP到/var/backup/
把二进制的日志生成 sql语句:
mysqlbinlog mysql-bin.000004>bin04.sql
如果有多个库,我们应该用-d来指定恢复单个库
mysqlbinlog mysql-bin.000004 –d oldboy >binlog.sql (当然对于库也要分库备,否则恢复还是麻烦)
还原数据:先还原全备,再还原增备
先还原全备:mysql –u root –p <mysqlfile.sql
还原增备:mysql –u root –p <binlog.sql(恢复增备的时候,需要把误操作的语句删掉后,再还原,否则,还原后,还是会和误操作后一样)
基于时间点的增量恢复
mysqlbinlog mysql-bin.000004 –start-datetime=’2011-03-19 02:58:54’—stop-datetime=’2011-03-19 03:22:44’ –r time.sql
上面语句将显示2011.03-19 02:58:54-----2011-03-19 03:22:44时间段的binlog,并输出到time.sql
拽定开始时间到文件结束
mysqlbinlog mysql-bin.000004 –start-datetime=’ 2011-03-19 02:58:54’ –d oldboy –r time.sql
这个语句只有开始时间,那么就是从2011-03-19 02:58:54时刻到日志结尾,lodboy数据库的binlog输出到time.sql
基于位置点的增量恢复
指定开始位置和结束位置
mysqlbinlog mysql-bin.000004 –start-position=510 –stop-position=1312 –r pos.sql
输出初始位置510,结束位置1312的所有binlog日志到pos.sql
注意:结尾的日志点细弱特殊不会被包含。即输出1312pos以前的binlog。
指定开始位置到文件结束
mysqlbinlog mysql-bin.000004 –start-position=510 –r pos510-end.sql
输出初始位置510,结束位置到文件结尾的所有binlog到pos510-end.sql。当然,你也可以指定库名输出binlog。如:
mysqlbinlog mysql-bin.000004 --start-position=510 –r pos510-end-oldboy.sql –d oldboy
从文件开头到指定结束位置
mysqlbinlog mysql-bin.000004 --stop-position=954 -r start-954.sql
输出从文件开始位置,到954位置截止的所有binlog
掌握和查找打开的文件
lsof(列出打开的文件)实用程序会显示打开的文件名。其选项仅显示某些进程,只有一个进程的某些文件描述符,或只有某些网络连接(网络连接使用文件描述符,就像普通文件一样,lsof 也显示这些)。使用 ps – ef 确定了可疑进程后,输入以下命令:
# lsof -s -p pid |
服务器最大设置的连接数:151
mysql> show variables like‘max_connections‘;
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 151 |
+-----------------+-------+
1 row in set (0.00 sec)
服务器响应的最大连接数:152
mysql> show global status like ‘Max_used_connections‘;
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| Max_used_connections | 152 |
+----------------------+-------+
1 row in set (0.00 sec)
查看服务器key_buffer_size数值:402653184
mysql> show variables like ‘key_buffer_size‘;
+-----------------+-----------+
| Variable_name | Value |
+-----------------+-----------+
| key_buffer_size | 402653184 |
+-----------------+-----------+
1 row in set (0.00 sec)
查看服务器现在使用的key_buffer_size使用情况:
key_read_requests: 879600044
key-reads: 830525
mysql> show global status like ‘key_read%‘;
+-------------------+-----------+
| Variable_name | Value |
+-------------------+-----------+
| Key_read_requests | 879600044 |
| Key_reads | 830525 |
+-------------------+-----------+
2 rows in set (0.00 sec)
计算索引未命中的概率:
key_cache_miss_rate = key_reads / key_read_requests * 100%
达到0.1%以下(即每1000个请求有一个直接读硬盘)以下都很好,如果key_cache_miss_rae在0.01%以下的话,则说明key_buffer_size分配得过多,可以适当减少。
Key_blocks_unused表示未使用的缓存簇数,Key_blocks_used表示曾经用到的最大的blocks数,比如这台服务器,所有的缓存都用到了,要么增加key_buffer_size,要么就是过度索引,把缓存占满了。比较理想的设置是:
key_blocks_used / ( key_blocks_unused + key_blocks_used ) * 100 % = 80%
mysql> show global status like ‘key_blocks_u%‘;
+-------------------+--------+
| Variable_name | Value |
+-------------------+--------+
| Key_blocks_unused | 317003 |
| Key_blocks_used | 6439 |
+-------------------+--------+
2 rows in set (0.00 sec)
临时表:
当执行语句时,关于已经被创造了的隐含临时表的数量,我们可以用如下命令查询其具体情况:
mysql> show global status like ‘created_tmp%‘;
+-------------------------+--------+
| Variable_name | Value |
+-------------------------+--------+
| Created_tmp_disk_tables | 343326 |
| Created_tmp_files | 172 |
| Created_tmp_tables | 675795 |
+-------------------------+--------+
3 rows in set (0.00 sec)
每次创建临时表时,created_tmp_tables都会增加,如果是在磁盘上创建临时表,created_tmp_disk_tables也会增加。created_tem_files表示MYSQL服务创建的临时文件数,比较理想的配置是:
Created_Tmp_disk_tables / Created_tmp_tables * 100% <= 25%
比如上面服务器Created_Tmp_disk_tables / Created_tmp_tables * 100% = 50%,比较差了。
我们再看一下MYSQL服务器对临时表的配置:
mysql> show variables where Variable_name in (‘tmp_table_size‘,‘max_heap_table_size‘);
+---------------------+----------+
| Variable_name | Value |
+---------------------+----------+
| max_heap_table_size | 16777216 |
| tmp_table_size | 16777216 |
+---------------------+----------+
2 rows in set (0.00 sec)
只有16M以下的临时表才能全部放在内存中,超过的就会用到硬盘临时表。
打开表的情况
Open_tables表示打开表的数量,Opend_tables表示打开过的表数量,我们可以用如下命令查看其具体情况:
mysql> show global status like ‘open%tables%‘;
+---------------+--------+
| Variable_name | Value |
+---------------+--------+
| Open_tables | 512 |
| Opened_tables | 234200 |
+---------------+--------+
2 rows in set (0.00 sec)
如果Opened_tables数量过大,说明配置中tables_caceh(MYSQL 5.1.3 之后这个值叫做table_open_cache)的值可能太小。我们查询一下服务器table_cache值:
mysql> show variables like ‘table_open_cache‘;
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| table_open_cache | 614 |
+------------------+-------+
1 row in set (0.00 sec)
比较合适的值为:
Open_tables / Opened_tables * 100% >= 85%
Open_tables / table_open_cache * 100% <= 95%
进程使用情况
如
果我们在MYSQL服务器的配置文件中设置了thread-cache_size,当客户端断开之时,服务器处理此客户请求的线程将会缓存起来以响应下一
个客户而不是销毁(前提是缓存数未达上限)。Threads_created表示创建过的线程数,我们可以用如下命令查看:
mysql> show global status like ‘Thread%‘;
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_cached | 7 |
| Threads_connected | 2 |
| Threads_created | 2124 |
| Threads_running | 2 |
+-------------------+-------+
4 rows in set (0.00 sec)
如果发现Threads_created的值过大的话,表明MYSQL服务器一直在创建线程,这也是比较耗费资源的,可以适当增大配置文件中的thread_cache_size的值。查询服务器thread_cahce_size配置,如下所示:
mysql> show variables like ‘thread_cache_size‘;
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| thread_cache_size | 8 |
+-------------------+-------+
1 row in set (0.00 sec)
查询缓存
它涉及的主要有两个参数,query_cache_size是设置MYSQL的Query_Cache大小,query_cache_size是设置使用查询缓存的类型,我们可以用如下命令查看其具体情况:
mysql> show global status like ‘qcache%‘;
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_free_blocks | 130 |
| Qcache_free_memory | 31557680 |
| Qcache_hits | 15838885 |
| Qcache_inserts | 2391041 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 671718 |
| Qcache_queries_in_cache | 676 |
| Qcache_total_blocks | 1798 |
+-------------------------+----------+
8 rows in set (0.00 sec)
我们再查询一下服务器上关于query-cache的配置命令如下:
mysql> show variables like ‘query_cache%‘;
+------------------------------+----------+
| Variable_name | Value |
+------------------------------+----------+
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 33554432 |
| query_cache_type | ON |
| query_cache_wlock_invalidate | OFF |
+------------------------------+----------+
5 rows in set (0.00 sec)
排序使用情况
它表示系统中对数据进行排序时所使用的Buffer,我们可以用如下命令查看:
mysql> show global status like ‘sort%‘;
+-------------------+-----------+
| Variable_name | Value |
+-------------------+-----------+
| Sort_merge_passes | 84 |
| Sort_range | 393425 |
| Sort_rows | 751581502 |
| Sort_scan | 324383 |
+-------------------+-----------+
4 rows in set (0.00 sec)
Sort_merge_passes
包括如下步骤:MYSQL首先会尝试在内存中做排序,使用的内存大小由系统变量sort_buffer_size来决定,如果它不够大则把所有的记录都读
到内存中,而MYSQl则会把每次在内存中排序的结果存到临时文件中,等
MYSQL找到所有记录之后,再把临时文件中的记录做一次排序。这次再排序就会增加sort_merge_passes。实际上,MYSQL会用另一个临
时文件来存储再次排序的结果,所以我们通常会看到sort_merge_passes增加的数值是建临时文件数的两倍。因为用到了临时文件,所以速度可能
会比较慢,增大sort_buffer_size会减少sort_merge_passes和创建临时文件的次数,但盲目地增加
sort_buffer_size并不一定能提高速度。
文件打开数(open_files)
我们在处理MYSQL故障时,发现当open_files大于open_files_limit值时,MYSQL数据库就会发生卡住的现象,导致APACHE服务器打不开相应页面。这个问题大家在工作中应注意,我们可以用如下命令查看其具体情况:
mysql> show global status like ‘open_files‘;
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_files | 901 |
+---------------+-------+
1 row in set (0.00 sec)
mysql> show variables like‘open_files_limit‘;
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| open_files_limit | 1185 |
+------------------+-------+
1 row in set (0.00 sec)
比较适合的设置是:open_files / open_files_limit * 100% <= 75%
带宽的大小
通常我们在架构网站的时候,会设定一些目标,比如网站每天要能承受千万PV的访问量,这时我们要估算一下大概需要多大的带宽。计算带宽大小主要的有2个主要指标(峰值流量和页面大小),我们先做出必要的假设:
1. 峰值流量是平均流量的3倍;
2. 每次访问平均的页面大小是100KB左中。
如
果1000万PV的访问量在一天内平均分布,每秒大约120次访问,如果按平均每次访问页面大小是100KB字节计算,120次访问总计大约就是
12000KB。字节的单位是Byte,而带宽单位是bit,它们之间的关系是1Byte=8bit,所以12000k
Byte大致就相当于96000k
bit,也就是90Mbps的样子。实际上,我们的网站必须能在峰值流量时保持正常运行状态,所以按照假设的峰值流量计算,真实带宽的需求应该在
270Mbps左右。
当然,这个结论是根据前面提到的两点假设得出来的,具体值则需要根据公司实际情况来计算。
数
据库服务器是重中之重,因为网站的瓶颈问题大多出在数据库身上。现在一般的中小网站多使用MYSQL数据库。一般而言,使用MYSQL数据库的时候,我们
应该配置为一个主从(一方多从)结构,主数据库服务器使用InnoDB表结构,从数据服务器使用MyiSAM表结构。这样充分发挥它们各大自的优势,而且
这样的方从分离了读写操作,降低了读操作的压力。我们还可以设定一个专门的从服务器作为备份服务器,有时候还需要借助mcached/‘ target=‘_blank‘>Memcached之类的第三方软件,以便适应更大访问量的要求。
跟踪进程:
找其中一个 CPU 100% 的 php-cgi 进程的 PID,用以下命令跟踪一下:
strace -p 10747
如果屏幕显示:
select(7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
那么,就可以确定是 file_get_contents() 导致的问题了。
lsof
lsof -i :80 显示占用80端口的进程
lsof -p 1457 显示进程号为1457的进程所打开的文件
查看服务器型号:
dmidecode -s system-product-name