手把手教你在centos下编译安装配置高性能web服务器环境nginx+php(fast-cgi)+mysql等/适合小内存vps使用

本文为实战操作过程的全程记录,采用一台新创建的linode vps(512M内存)环境,操作系统采用centos 6.2,以从源码编译的方式安装配置nginx, php(fast-cgi模式)web环境。

我们的目标:配置一台高性能、安全的web服务器。

继续阅读

mysql错误/usr/libexec/mysqld: Out of memory (Needed xxx bytes)及The table 'pre_common_session' is full处理手记

核心提示:检查mysqld配置my.conf,着重看key_buffer_size, max_heap_table_size, tmp_table_size几个参数,推荐设置key_buffer_size值为max_heap_table_size的1/4.

因为服务器内存而大富余比较多,前些天把my.conf里的好几个参数调得相当大,1G甚至2G,但并不稳定,mysqld报出过几次Out of memory (Needed xxx bytes)这样的错误,分析原因时,想到是32位linux系统上的linux不支持PAE,不能使用超过3G以上的内存,所以把改大的几个参数适当改小了点,最大也只有几百M的样子,但还是出现过几次Out of memory错误。于是网上多方查询,后来受到公式

key_buffer_size + (read_buffer_size + sort_buffer_size)*max_connections

的启发,两次检查了key_buffer_size, max_heap_table_size, tmp_table_size几个参数,发现这三个值的设置是一样的,竟然都是512M!

于是改小key_buffer_size到128M,重启mysqld接下来5个小时的监测,没有再发生类似错误。

mysql修改配置参数innodb_log_file_size后不能正常工作,在phpmyadmin中innodb表状态为“使用中”

问题:修改mysql配置参数innodb_log_file_size 后,可能无法正常启用,或者innodb表将不能工作,在phpmyadmin中显示为“使用中”

解决方法:先停掉mysql,然后删掉旧innodb日志文件后,再启动mysqld就可以正常启用了.innodb旧日志文件位于mysql data 目录下的ib_logfile0, ib_logfile1 文件

innodb日志文件在linux下的典型位置为 /var/lib/mysql
在windows下则默认位于安装目录下的data子目录里。

原因:是旧的innodb日志文件,与改后的innodb_log_file_size不匹配,所以造成mysql不能正常工作。

简单命令对mysql数据库的备份与还原

使用phpMyAdmin备份mysql数据库

备份mysql的最简单方法是的使用phpMyAdmin的“导出”功能,导出成sql文件,不用管其它选项,只管导出就可以,这就是mysql标准的备份文件。

导出时,一般不要勾选压缩选项。因为如果备份文件大到一定程度,就会因为php分配不到足够内存而死掉;经验是50M以上的表,就不要压缩了。这是个蛋疼的事情:小文件不值得压缩,大了反而压缩不动。所以不压缩就是了。

还原mysql数据库

要还原mysql数据库时,使用phpMyAdmin是个简单的方法,但更容易因为备份文件过大而超过php内存限制而死掉,这时你会有种痛不欲生的感觉。

推荐使用命令行连接mysql,以source命令导入还原,这个导入过程是件愉悦的事情。

不幸的是如果你在windows下,会比较啰嗦:

把你的mysql备份文件放到一个比较浅的目录里,比如放在 E:\120507.sql ,你要还原的数据库叫mydata

找到你的mysql安装在哪里,假如你的mysql安装在D:\Program Files\MySQL\MySQL Server 5.0 ,那么你的mysql命令行客户端将位于D:\Program Files\MySQL\MySQL Server 5.0\bin ,按着按下面的步骤来:

  • 1. 开始-运行,输入cmd,确定,你将进入命令行界面
  • 2. 输入 d: 然后回车,进入D盘
  • 3. 输入cd "D:\Program Files\MySQL\MySQL Server 5.0\bin" 再回车(注意,如果路径中有空格,那引号是必须的)
  • 4. 输入mysql -uroot -p123456 --default-character-set=utf8 --max_allowed_packet=16777216 --net_buffer_length=16384 回车(假设你的mysql的root用户密码是123456, 注意,这里u与p后面带不带空格都可以,我习惯不带; 你只需改这行命令里的密码部分,其它不需要改变,照用即可)
  • 你将看到

    注意到光标闪烁处的mysql> ,这就说明已经成功连接到本机的mysql数据库。
  • 输入use mydata 回车 ,进入mydata数据库
  • 输入source E:\120507.sql 回车,你将看到一行行快速滚动的信息。滚动完毕就导入完成了。
  • 输入exit驾车即可。回到phpmyadmin里看导入的结果吧.

核心回顾

mysql备份,使用phpMyAdmin,导出需要的表,或整个数据库,注意最好不要勾选压缩

还原,使用命令行客户端连上mysql服务器,mysql -uroot -p123456 --default-character-set=utf8 --max_allowed_packet=16777216 --net_buffer_length=16384,然后use mydata进入需要还原的数据库,运行source x:\bakup_file.sql 导入备份。

phpmyadmin删除“追踪”(就是在表名旁的眼睛图标)/phpmyadmin(v3.3+)追踪功能简介

数据库phpmyadmin里的表pma_tracking,打开,里面即是追踪项的配置记录,删掉就可以了。

使用新版本的phpmyadmin,试用里面的追踪功能,不过用过后不知道怎么删掉了。于是google到这里,网上有人问同样问题,但没人回答。于是只好做罢,自己动手,丰衣足食。

猜想这是否是phpmyadmin本身的功能,而非mysql的;因为之前google这个问题时,搜索mysql trace并没有发现说mysql有这样的追踪功能。

于是查找phpmyadmin库,见表pma_tracking打开,删除记录,问题解决。

 

附:phpmyadmin官方中文文档的“追踪”功能简介:

$cfg['Servers'][$i]['tracking'] 字符串
自 3.3.x 起可以使用追踪功能。它可以帮你追踪每个通过 phpMyAdmin 执行的 SQL 命令。它支持记录数据修改和数据定义语句。启用后还可以创建数据表的版本。

创建版本会造成两个影响:

  • phpMyAdmin 保存当前数据表的快照,包括结构和索引。
  • phpMyAdmin 针对当前数据表记录的所有修改结构和/或数据的命令都将与版本关联。

当然你也能查看追踪到的修改。在"追踪"页里每个版本都会有一份完整的报告。你可以在报告中搜索,如你可以只列出一段时间内的语句。若想根据用户名搜索可以输入 * 表示任意用户或者输入 ',' 分隔的用户列表。你还可以导出 (包括搜索结果) 报告为文件或者临时数据库。

要启用此功能:

  • 设置好 pmadb 和 phpMyAdmin 高级功能
  • put the table name in $cfg['Servers'][$i]['tracking'] (e.g. 'pma_tracking')
$cfg['Servers'][$i]['tracking_version_auto_create'] 布尔
设置追踪系统是否自动为数据表和视图创建版本。默认为 false 。

若设为 true 然后你通过

  • CREATE TABLE ...
  • CREATE VIEW ...

创建了一张表或视图并且它当前没有任何版本,系统将会自动为你创建一个版本。

mysql多表join联查语句错误:#1241 - Operand should contain 1 column(s)

对ecshop系统做一些改造,需要一个三表join的查询,但写出语句却报错了

#1241 - Operand should contain 1 column(s)

语句如下:

SELECT a . * , IFNULL( g.goods_thumb, '' ) AS goods_thumb, g.goods_name AS goods_name_from_goods, g.brand_id, b.brand_name
FROM `eb`.`ec_goods_activity` AS a
LEFT JOIN (`eb`.`ec_goods` AS g , `eb`.`ec_brand` AS b )
ON (a.goods_id = g.goods_id , b.brand_id = g.brand_id)
WHERE a.act_type = '5'
AND a.start_time <= '1333010119'
AND a.end_time >= '1333010119'
AND a.is_finished <2
ORDER BY a.act_id DESC
LIMIT 20

起初死活找不到错误,突然发现ON子句里把条件and错写成逗号了,改正后执行正确,问题解决。

SELECT a. * , IFNULL( g.goods_thumb, '' ) AS goods_thumb, g.goods_name AS goods_name_from_goods, g.brand_id, b.brand_name
FROM `eb`.`ec_goods_activity` AS a
LEFT JOIN (
`eb`.`ec_goods` AS g, `eb`.`ec_brand` AS b
) ON ( a.goods_id = g.goods_id AND b.brand_id = g.brand_id )
WHERE a.act_type = '5'
AND a.start_time = '1333010119'
AND a.is_finished ORDER BY a.act_id DESC
LIMIT 20

一次linux下mysql服务优化(环境为vps上的centos5)

一台vps服务器,使用centos 5操作操作系统,销售商声称是“上海戴尔VM/HV(IP)512M内存20G硬盘”,基于xen虚拟化技术,算是比中低端的vps了,上面跑一个ecshop的商城系统。

主要运行的服务为

apache (httpd-2.2.3-53.el5.centos.3/php-5.1.6-27.el5_7.5)

mysqld (mysql-server-5.0.95-1.el5_7.1)

ecshop商城上线后,访问量还并不很大,但web经常卡死,几乎访问不动。ssh登录服务器后,内存用尽,连swap都使用过半。top显示有几十个httpd进程;mysql占用cpu持续超过50%,经常达80%甚至100%, 这个状况,不死就怪了。

起初以为是apache子进程太多了,修改apache配置,只开8个子进程;同时还注意到有个yum 进程在运行,于是停掉apache,mysql,运行yum update ,升级一下系统。当时是周五下午,搞好后看起来比较正常了,

然而到了周一,问题依旧,apache进程数多达100多个!

网上有人说apache进程数过多,很可能不是apache的问题,而是web应用的问题,导致一些子进程假死或死掉。通过phpmyadmin查看mysql的进程,很多类似如下的语句:

SELECT a.attr_name
FROM `ecs_attribute` AS a, `ecs_goods_attr` AS ga, `ecs_goods` AS g
WHERE (
g.cat_id
IN ('105', '171', '173', '106', '111', '108', '113', '151', '112', '157', '153', '152', '110', '150', '147', '155', '148', '156', '172', '109', '149', '114')
OR g.goods_id
IN ('')
)
AND a.attr_id = ga.attr_id
AND g.goods_id = ga.goods_id
AND g.is_delete =0
AND g.is_on_sale =1
AND g.is_alone_sale =1
AND a.attr_id = '219'

而且查询执行时间多数比较长,经常出现多个耗时达5秒以上的语句在执行。状态经常是 Copying to tmp table,或sending data. 怀疑mysql问题比较大,开始关注mysql配置,通过phpmyadmin查看mysql变量,与一台运行平稳的实体服务器比对,主要看是缓存、临时表等变量。果然,这些值都相当的小。

查看mysql配置文件如下:

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Default to using old password format for compatibility with mysql 3.x
# clients (those using the mysqlclient10 compatibility package).
old_passwords=1

# Disabling symbolic-links is recommended to prevent assorted security risks;
# to do so, uncomment this line:
# symbolic-links=0

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

参看windows版mysql官方自带的配置文件(\MySQL\MySQL Server 5.0\my-large.ini),修改配置文件如下:

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql

myisam_sort_buffer_size=64M
key_buffer = 64M
table_cache = 128
read_buffer_size = 1M
read_rnd_buffer_size = 1M
sort_buffer_size = 2M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size= 16M

# Default to using old password format for compatibility with mysql 3.x
# clients (those using the mysqlclient10 compatibility package).
old_passwords=1

# Disabling symbolic-links is recommended to prevent assorted security risks;
# to do so, uncomment this line:
# symbolic-links=0

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

重启mysql,apache,再通过phpmyadmin看查询进程,比之前大为改观。通过几个小时的观查,已经较少出现查询耗时超过5秒的进程。基本上每2、3秒重新一下一下phpmyadmin的“进程”,有一半以上机会看不到正在执行的语句。也就是说,大多数语句都可以很快执行完,以致于较很少有机会看到它们。这个现象与那台参考的实体服务器上的mysql相同。

通过free查看内存使用情况:

[root@localhost ~]# free -m
             total       used       free     shared    buffers     cached
Mem:           503        469         33          0         25        305
-/+ buffers/cache:        138        364
Swap:         1023         23       1000

swap几乎没有使用,物理内存(除去缓存)占用并也不高。

通过top查看进程:

top - 13:19:21 up 165 days,  3:11,  2 users,  load average: 0.47, 0.36, 0.52
Tasks: 101 total,   1 running,  98 sleeping,   2 stopped,   0 zombie
Cpu(s): 20.3%us, 12.5%sy,  0.0%ni, 62.1%id,  0.0%wa,  1.0%hi,  4.1%si,  0.0%st
Mem:    515268k total,   504416k used,    10852k free,    26712k buffers
Swap:  1048568k total,    23712k used,  1024856k free,   314496k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 6848 mysql     23   0  225m  56m 4432 S 32.1 11.3  33:48.61 mysqld
 7399 apache    15   0 33516  13m 4384 S  0.0  2.7   0:09.48 httpd
 7401 apache    15   0 33328  13m 3884 S  2.6  2.6   0:08.00 httpd
 7406 apache    15   0 32864  12m 3848 S  0.0  2.5   0:07.92 httpd
 7429 apache    15   0 32704  12m 3528 S  0.0  2.4   0:00.57 httpd
 7400 apache    15   0 32672  12m 3740 S  5.6  2.4   0:09.77 httpd
 7428 apache    15   0 32684  12m 3544 S  0.0  2.4   0:01.34 httpd
 7404 apache    15   0 32348  12m 3736 S  0.0  2.4   0:08.98 httpd
 7407 apache    15   0 32100  12m 3884 S  0.0  2.4   0:08.02 httpd
 7411 apache    15   0 32436  12m 3848 S  0.0  2.4   0:06.43 httpd
 7405 apache    15   0 32184  11m 3740 S  0.0  2.4   0:09.60 httpd
 7408 apache    15   0 32432  11m 3588 S  0.0  2.4   0:07.21 httpd
 7427 apache    15   0 32368  11m 3540 S  0.0  2.4   0:00.98 httpd
 6874 root      18   0 27512 9448 5672 S  0.0  1.8   0:00.40 httpd
 1765 root      34  19 27884 3200 1148 S  0.0  0.6   9:33.82 yum-updatesd
 7112 root      18   0 10216 2980 2372 S  0.0  0.6   0:00.20 sshd
 7024 root      15   0  7620 2664 1952 T  0.0  0.5   0:00.10 vim
 7114 root      15   0  6656 1608 1188 S  0.0  0.3   0:00.05 sftp-server
12180 root      15   0 25424 1188  804 S  0.0  0.2   0:34.97 snmpd
 5411 root      15   0  8520 1124 1120 T  0.0  0.2   0:00.01 mysql
 5085 root      15   0  2688 1028  800 S  0.0  0.2   0:00.20 bash
 6801 root      22   0  2504 1000  856 S  0.0  0.2   0:00.00 mysqld_safe
 7432 root      18   0  2292 1000  792 R  0.3  0.2   0:00.24 top
 1429 dbus      15   0  2964  792  544 S  0.0  0.2   2:55.54 dbus-daemon
 5077 root      15   0 10220  792  668 S  0.3  0.2   0:04.47 sshd
12307 root      15   0  9348  576  408 S  0.0  0.1   0:05.80 sendmail
12197 root      20   0 13564  572  412 S  0.0  0.1   0:04.28 snmptrapd
...

mysql的内存占用也不高,httpd进程数目也正常。

也就是说,改后的配置参数,整个vps服务器运行状态还是比较正常。

只是因为vps本身性能并不高,而访问量较多时候load average值达5以上;不过即便这时,网站还能访问;之前假死时,页面超过半分钟都打不开的。

excel表格导入mysql方法(手工导入)

这不是最好的办法,但对于只导一次的数据,却是一个有效的方法,虽然非常麻烦。

microsoft office/excel 在日常的应用中,还是相当广泛,但它不是个好工具。把excel导入mysql表,是一个无法忍受的麻烦工作;尤其是表格里带大字段的列,使用phpMyAdmin导入经常是失败的。如果你也遇到这种问题,可以尝试以下方法。

1. 在excel里选中所有数据列,执行替换,把 ' 替换成 \' (把单引号替换成斜杠加单引号,即mysql中的单引号转义)

2. 在excel表格里插入一列,根据mysql表结构,写个excel公式,其实只是个字符串拼接操作,目的是构造一个mysql插入语句,形式大至如下

="insert into `article`(cat_id,title,content,add_time) values('"&D3&"','"&A3&"','"&B3&"',1330516016);"

3. 复制该列,并作为新列粘贴值到旁边(选择性粘贴);或者粘贴到新表格里也可以。

4. 除了刚才的新数据列,把其它列全部删掉,另存为unicode文本格式(实际是utf-16的csv)。

5. 使用记事本打/或其它纯文本编辑工具打开该文件,另存为utf-8编码。(windows下所谓的unicode格式实际是utf-16,这是M$在误导大家)

6. 使用editplus等文本编辑工具,打开该utf-8格式的文件,查找替换,把 ""  替换成 " (两个连续单引号替换成一个单引号); 因为M$的CSV使用两个双引号来转义双引号,这是个非常愚蠢的约定!MS/windows很多地方都是这样愚蠢的做双字符转义!而标准的csv使用斜杠做特殊字符转义的。

7. 把 "\n\" (行尾双引号与下一行的双引号) 替换成 \n (亦即把行首及行尾的双引号删掉)

8. 把文件最开头及文件最末尾的双引号删掉。

9. 现在就是可以在mysql里执行的insert插入语句了,拿到mysql里执行吧。如果数据量大,推荐使用mysql命令行下导入,连接时最好加上参数 --default-character-set=utf8 ,这样不容易出现乱码。

mysql -uroot -p --default-character-set=utf8

MySQL函数 GROUP_CONCAT,相当有用

一直想找这个函数,今天终于找到了,属于聚合函数,也正是猜测可能是个函数函数、才通过“MySQL 聚合函数” google到的。

使用过程中可能会遇到1260错误,如下:

#1260 - %d line(s) were cut by GROUP_CONCAT()

这是因为group_concat()有最大长度限制,该限制值默认为1024,可以从mysql环境变量里可以查看。如需修改该值,可以在mysql配置文件里指定:

group_concat_max_len = 102400

也可以在mysql运行时动态指定,执行语句:

SET GLOBAL group_concat_max_len=102400;

参考该链接http://www.fuchaoqun.com/2008/12/mysql-trap-of-group-concat/,或者mysql手册(推荐)。

Pages: Prev 1 2 3 Next