系统日志

   系统的日志记录提供了对系统活动的详细审计,这些日志用于评估、审查系统的运行环境和各种操作。对于一般情况 ,日志记录包括记录用户登录时间、登录地点、进行什么操作等内容,如果使用得当,日志记录能向系统管理员提供有关危害 安全的侵害或入侵试图等非常有用的信息。

   BSD提供了详细的各种日志记录,以及有关日志的大量工具和实用程序。这些审计记录通常由程序自动产生,是缺 省设置的一部分,能够帮助Unix管理员来寻找系统中存在的问题,对系统维护十分有用。还有另一些日志记录,需要管理 员进行设置才能生效。大部分日志记录文件被保存在/var/log目录中,在这个目录中除了保存系统生成日志之外,还 包括一些应用软件的日志文件。当然/var目录下的其他子目录中也会记录下一些其他种类的日志记录文件,这依赖于具体 的应用程序的设置。


[code]$ ls /var/log
adduser maillog.5.gz sendmail.st.1
dmesg.today maillog.6.gz sendmail.st.10
dmesg.yesterday maillog.7.gz sendmail.st.2
httpd-access.log messages sendmail.st.3
httpd-error.log messages.0.gz sendmail.st.4
kerberos.log messages.1.gz sendmail.st.5
lastlog messages.2.gz sendmail.st.6
lpd-errs messages.3.gz sendmail.st.7
maillog messages.4.gz sendmail.st.8
maillog.0.gz messages.5.gz sendmail.st.9
maillog.1.gz news setuid.today
maillog.2.gz ppp.log setuid.yesterday
maillog.3.gz sendmail.st userlog
maillog.4.gz sendmail.st.0 wtmp [/code]



系统登录日志

   系统会保存每个用户的登录记录,这些信息包括这个用户的名字、登录起始结束时间以及从何处登录入系统的等等。 它们被保存到/var/log/lastlog、/var/log/wtmp和/var/run/utmp文件中,这 三个文件以二进制格式保存了这些用户的登录数据。

   其中/var/run/utmp文件中保存的是当前系统用户的登录记录,因此这个文件会随着用户进入和离开系 统而不断变化,而它也不会为用户保留很长的记录,只保留当时联机的用户记录。系统中需要查询当前用户状态的程序,如 who、w等就需要访问这个文件。utmp可能不包括所有精确的信息,某些突发错误会终止用户登录会话,当没有及时更新 utmp记录,因此utmp的记录不是百分之百的可以信赖的。

   而/var/log/wtmp保存了所有的登录、退出信息,以及系统的启动、停机记录,因此随着系统正常运行 时间的增加,它的大小也会越来越大,增加的速度依赖于系统用户登录次数。因此可以利用这个日志用来查看用户的登录记录 ,last命令就通过访问这个文件来获得这些信息,并以反序从后向前显示用户的登录记录,last也能根据用户、终端 tty或时间显示相应的记录。ac命令同样也使用wtmp中的数据产生报告,但它的显示方式不同。它可以根据用户(ac -p) ,或按日期(ap -d)显示信息,这样管理员就能获得一些非常有用的反常信息,如一个平时不太活跃的用户 突然登录并连接很长时间,就有理由怀疑这个帐户被窃取了。

   注意:X Window由于会同时打开多个终端窗口,因此会使得用户登录连接时间迅速增加。

   lastlog文件保存的是每个用户的最后一次登录信息,包括登录时间和地点,这个文件一般只有login程 序使用,通过用户的UID,来在lastlog文件中查找相应记录,然后报告其最后一次登录时间和终端tty。然后, login程序就使用新的记录更新这个文件。

   这三个文件是使用二进制格式保存的,因此不能直接查看其中的内容,而需要使用相关命令。当然也可以通过程序来 访问这三个文件,这就需要了解它们使用的数据结构。其中utmp和wtmp使用同样的数据结构,而lastlog使用 另外一个数据结构,可使用man来进行查询具体结构。如果系统的用户数量很多,那么wtmp文件的大小会迅速增加,在 系统/var文件系统空间紧张的情况下,就导致这个文件系统被占满。系统不会主动控制这个文件的大小,因此这需要管理 员的干预,需要手工及时清除,或编写shell脚本定期保存和清除。

   系统还可以提供记账统计的功能,要打开系统的计账功能,需要使用accton命令,注意,accton必须跟 随记账日志文件的名字作参数,而不带参数的accton将关闭记账进程。

   当打开了记账功能后,可以使用lastcomm来检查在系统中执行的所有命令的信息,包括执行的命令、执行命 令的用户、用户使用的终端tty,命令完成的时间,执行时间等。从lastcomm的输出也能帮助管理员检查可能的入 侵行为。

   此外可以使用ac命令来查询用户的连接时间的报告,sa命令来查询用户消耗的处理器时间的报告。


Syslog日志记录

   最初,syslog只是为了sendmail而设计的消息日志工具,由于它提供了一个中心控制点,使得sys log非常好用和易配置,因此当今很多程序都使用syslog来发送它们的记录信息。syslog是一种强大的日志记 录方式,不但可以将日志保存在本地文件中,还可以根据设置将syslog记录发送到网络上的另一台主机中。

   支持syslog方式的系统启动了syslogd守护进程,这个程序从本地的Unix套接字和监听在514端 口(UDP)上的Internet套接字,来获得syslog的记录。本机中进程使用syslog系统调用发送来sy slog记录,然后由syslogd将他们保存到正确的文件或发送到网络上另一台运行syslogd主机中去。

   syslogd的设置文件为/etc/syslog.conf,定义消息对应的相应目标,一条消息可以达到多 个目标,也可能被忽略。


[code]# $Id: syslog.conf,v 1.9 1998/10/14 21:59:55 nate Exp $

#

# Spaces are NOT valid fIEld separators in this file.

# Consult the syslog.conf(5) manpage.

*.err;kern.debug;auth.notice;mail.crit /dev/console

*.notice;kern.debug;lpr.info;mail.crit;news.err /var/log/messages

mail.info /var/log/maillog

lpr.info /var/log/lpd-errs

cron.* /var/cron/log

*.err root

*.notice;news.err root

*.alert root

*.emerg *

!ppp

*.* /var/log/ppp.log [/code]
   syslog.conf的配置可以分为两个部分,第一部分用于区分消息的类型,另一个用于设置消息发送的目的 地。通常,消息的类型包括消息的产生者,例如kern表示内核产生的消息,auth表示认证系统产生的消息,等等,还 包括消息的级别,例如emerg表示非常重要的紧急信息,alert表示系统告警状态,crit表示关键状态,err 表示一般的错误信息,warning表示警告信息,notice表示提示信息,但还不是错误,info表示一般信息, debug表示调试信息等,因此一个消息的类型可能为:kern.debug、mail.info等,但页可以使用通 配符*进行匹配。

   从上面的syslog.conf的设置可以看出,系统正常运行中的很多重要的信息,如错误信息*.err、内 核调试信息kern.debuf、认证报告auth.notice等被直接输出的console中,另外还有一些比较 重要的信息被输出到/var/log/messages文件中,发送邮件的记录将被保存在/var/log/mail log文件中,打印记录为/var/log/lpd-errs等,使得管理员可以根据这些文件来查询相关记录,进行统 计或寻找系统问题。其中使用syslog记录的messages文件中包括root登录的信息、用户多次登录失败的尝 试等对系统安全相当重要的信息,因此也是系统遭受攻击之后,攻击者会根据syslog.conf中设置试图清除相关文 件中自己的登录记录。因此对于安全性要求更高的系统,可以尝试将syslog发送到另一台计算机上,或者输出到一些设 备文件中,如在打印机上立即打印输出。

   系统会使用newsyslog定期检查syslog输出的messages文件和maillog文件,将旧数 据压缩保存为备份文件,如messages.1.gz等。


其他日志

   除了系统登录记录和syslog记录之外,其他还有一些应用程序使用自己的记录方式。

   系统每天都会自动检查系统的安全设置,包括对SetUID、SetGID的执行文件的检查,其结果将输出到/ var/log/security.today文件中,管理员可以与/var/log/security.yeste rday文件对比,寻找系统安全设置的变化。

   如果系统使用sendmail,那么sendmail.st文件中以二进制形式保存了sendmail的统计 信息。

   在系统启动的时候,就将内核的检测信息输出到屏幕上,这些信息可以帮助用户分析系统中的硬件状态。一般使用d mesg命令来查看最后一次启动时输出的这个检测信息。这个信息也被系统保存在/var/log/dmesg.tod ay文件中,系统中同时也存在另一个文件dmesg.yesterday,是上次的启动检测信息,对比这两个文件,就 可以了解到系统硬件和内核配置的变化。

   lpd-errs记录了系统中lpd产生的错误信息。

   此外,各种shell还会记录用户使用的命令历史,它使用用户主目录下的文件来记录这些命令历史,通常这个文 件的名字为.history(csh),或.bash-history等。
电脑比收音机简单吗?为什么拆开两者,很明显,收音机看起来还要比电脑更复杂呢?原来,好的架构好的设计在哪里都是通用的!电脑各部件缺一不可,但是绝不是只针对某一个或者某一类产品,所有不同产品的厂商都只服从一个统一的标准,这样,我们就看不出电脑中哪一个是高层了。CPU?内存?或者主板?。。。都不是,谁也不依赖谁,依赖的是一个统一的接口标准!

依赖倒转原则:抽象不应该依赖细节,细节应该依赖抽象。具体到一个实际问题编程,应该是定义好的接口,这个接口不属于哪一个具体的东西,应该是一个高层的抽象,然后就是针对接口编程,而不要对实现编程。

讲到这里,似乎世界的一切问题都迎刃而解,一切显得是那样的轻而易举!慢!一定不要自负的轻视对手,好,谁都很听话的服从这个抽象接口,那么这个抽象接口怎么来?一切都在变,难道这个抽象类就是可以违背这个哲学上绝对真理的特例家伙?他可能自身都要不停的变!完了,到哪里去找这样一根标尺呀?

标尺也是自己定义的!无非是会需要随实际情况变化吗?不要忘了,我们已经学会的绝技——开放—封闭原则。我们保证提供基本功能的接口不变,实际需求增加时,只要做开放扩展即可,面向对象的继承能帮助我们找到正确适用实际问题的方法,问题不就解决了吗?恩,这样设计总结出统一的抽象接口或者抽象类是满足我们的需求的,不过,还有关键的一点,这一系列类必须要满足一个原则:里氏代换原则:子类型必须能够替换掉他们的父类型。这个原则在许多别的情况下,并不一定是完全满足的,但是此处用做标尺的抽象类,必须要满足!子类可以扩展做更多的事情,但是父类已经定义好的接口子类必须有实现,并且也必须是做一致的事情。

依赖倒转原则说明了:好的面向对象设计不应该是依赖具体实现中的那一部分,应该是针对抽象编程而不是针对细节编程,即程序中所有的依赖关系都是终止于抽象类或者接口。那样,高层、底层的改变都不会导致另外一部分要做变化了。

从北京去纽约喽,;-),还有陆路还要海洋,哈哈,变化再大我也不管,因为我做的是飞机!不过,你要是愿意先客车再渡轮也可以的哦~都是交通工具的抽象嘛!应该不会还有那个大侠想着依赖道路的,先穿跑鞋再换个泳衣去的吧~
CentOS 5.3 初始使用yum安装的php最高也只有5.1.6的,这是因为官方的yum库里最高就只有这个了。如何升级到高版本呢,

用下面的方法,我这已经升级到php5.3.1了,有点意外啊,呵呵,想想当初在windows下,装个5.3的版本都特别的费劲,linux下用yum,也有好处。当然这里还是提醒大家,最好还是用编译安装好点~

本站是web开发 企业建站的聚集地,一起来看看教程吧


CentOS5.3的php版本默认为5.1.6,然后在5.2.9版本之前的的php都存在一个漏洞,但是目前网上很多地方都无法使用yum update php*升级到5.2.9,比较常见的是升级到5.2.6版本的,经过搜索国外资料,现在终于找到一种升级CentOS的php到5.2.9的方法。
注意,此方法只能在官方的php版本上升级,如果你使用网上的升级到5.2.6版本的升级方法已经升级了,将无法使用本方法升级php。
运行下面命令:

wget http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm
wget http://rpms.famillecollet.com/enterprise/5/remi/i386/remi-release-5-7.el5.remi.noarch.rpm
rpm -Uvh remi-release-5*.rpm epel-release-5*.rpm

然后编辑/etc/yum.repos.d/remi.repo
#vi /etc/yum.repos.d/remi.repo
在这个文件的最后增加一行:
priority=1

保存退出。

/etc/yum.repos.d/epel.repo和/etc/yum.repos.d/epel-testing.repo这两个文件也按照上面的方法进行编辑!

使用下面的命令进行升级,但是经过测试,如果单独升级php将提示失败,只有联通mysql一起升级才可以,所以我们必须执行以下命令才能升级php到5.2.9版本:
yum --enablerepo=remi update php* mysql*

转自:开源ISPCP社区    http://www.ispcpcn.com/article/13/

CentOS 5.4环境下的php5.3.1手动安装

Cent自带的版本是5.1.16,现下载php5.3.1安装包tar.gz,解压到/usr/local/src中
执行下述命令:

./configure \
          "--prefix=/usr/local/php" \
          "--with-apxs2=/usr/sbin/apxs" \
          "--with-config-file-path=/usr/local/php/etc" \
          "--with-mysql=/usr/local/mysql" \
          "--with-mysqli" \
          "--with-libxml-dir=/usr/lib/libxml" \
          "--with-gd" \
          "--with-pdo-mysql" \
          "--with-pdo-sqlite" \
          "--with-jpeg-dir" \
          "--with-png-dir" \
          "--with-bz2" \
          "--with-pear=/usr/lib/pear" \
          "--with-freetype-dir" \
          "--with-iconv-dir" \
          "--with-zlib-dir " \
          "--with-mcrypt=/usr/lib/libmcrypt" \
          "--enable-sockets" \
          "--enable-soap" \
          "--enable-sqlite-utf8" \
          "--enable-gd-native-ttf" \
          "--enable-ftp" \
          "--enable-mbstring" \
          "--enable-exif" \
          "--disable-ipv6" \
          "--disable-cgi"
enca  文件名

linux文件名编码批量转换

convmv -f 源编码 -t 新编码 [选项] 文件名

常用参数:
-r 递归处理子文件夹
–notest 真正进行操作,请注意在默认情况下是不对文件进行真实操作的,而只是试验。
–list 显示所有支持的编码
–unescap 可以做一下转义,比如把%20变成空格
比如我们有一个utf8编码的文件名,转换成GBK编码,命令如下:

convmv -f UTF-8 -t GBK --notest utf8编码的文件名

Linux下批量转换文件内容编码

1.使用enca,例如要把当前目录下的所有文件都转成utf-8

$enca -x utf-8 *

2,使用iconv 转换

iconv的命令格式如下:

iconv -f encoding -t encoding inputfile

比如将一个UTF-8 编码的文件转换成GBK编码

iconv -f GBK -t UTF-8 file1 -o file2
查看linux文件目录的大小和文件夹包含的文件数

统计总数大小
du -sh xmldb/
du -sm * | sort -n //统计当前目录大小 并安大小 排序
du -sk * | sort -n
du -sk * | grep guojf //看一个人的大小
du -m | cut -d "/" -f 2 //看第二个/ 字符前的文字
查看此文件夹有多少文件 /*/*/* 有多少文件
du xmldb/
du xmldb/*/*/* |wc -l
40752
解释:
wc [-lmw]
参数说明:
-l :多少行
-m:多少字符
-w:多少字

df 查看硬盘的总容量、已用容量与inode等

du 查看文件已用容量

df -[ikm]

-i 使用i-nodes显示结果

-k 使用KB显示结果

-m 使用MB显示结果

du [-abckms] [目录名称]

-a 列出所有文件与目录,默认值是列出目录的值

-b 列出的值以b输出

-c 最后求总total

-k 列出的值 以KB输出

-m 列出的值以mb输出

-s 只列出最后求总的值
一个日记文件很大  很难打开我想通过命令把最后几行输入到一新文本知道怎么做吗?

  tail   -n   10   filename  
  查看filename的最后10行  
  后面再加文件名,可将最后10行导出到新文件

tail   -n   filename   >   newfile  
  其中   -n   的   n   为文件最后的几行,  
  结果重新定向到一个新文件newfile去。

tail   -f   可以保持显示新加入到log中的数据

tail   filenmae   -n   num
官方网站

http://spyc.sourceforge.net/
DownLoad:

spyc-0.4.5.zip
Spyc只有2个类方法


include('spyc.php');

// 读取YAML文件,生成数组
$yaml = Spyc::YAMLLoad('spyc.yaml');

// 将数组转换成YAML文件
$array['name']  = 'andy';
$array['site'] = '21andy.com';
$yaml = Spyc::YAMLDump($array);


php.ini读取ini的解析方式那种配置没法支持多维数组,So,我对yaml生成多维数组很感兴趣,主要想做一下配置文件,如下:
yml:
switches:
  - { row: 0, col: 0, func: {tx: [0, 1]} }

转为php多维数组如下:
spyc.yaml :

family:
  name:xiangs
  general:{frist: {sonone:jackxinag, second: jjjjj}, secondson: {one: 1, two: 2}}


test.php

<?php
include('spyc.php');

// 读取YAML文件,生成数组
$yaml = Spyc::YAMLLoad('spyc.yaml');
print_r($yaml);
?>




PHP code:
Array
(
    [family] => Array
        (
            [name] => xiangs
            [general] => Array
                (
                    [frist] => Array
                        (
                            [0] => sonone:jackxinag
                            [second] => jjjjj
                        )

                    [secondson] => Array
                        (
                            [one] => 1
                            [two] => 2
                        )

                )

        )

)


特别注意:冒号后需要有一个空格,{} 是php哈希,key=>value ,{key: value},空格。
{one: 1, two: 2},one=>1,two=>2,注意1, two,空格,1逗号后面要有空格!!!否则就变为:
          
      
                    [secondson] => Array
                        (
                            [one] => Array
                                (
                                    [1,two] => 2
                                )

                        )


而不是:

                    [secondson] => Array
                        (
                            [one] => 1
                            [two] => 2
                        )


这就是:secondson: {one: 1,two: 2} 和 secondson: {one: 1, two: 2} 的区别,空格是yaml的解析核心!!!

关于| 和 >
family:

   name: |
         'ddd
         dfdf
         dfd'  
family2:
   name: >
         'ddd
         dfdf
         dfd'
  
注意对齐:这儿的name是4个空格,这儿就ddd前面有4个,如果是familiy,那就是2个,否则解析会出问题。

结果:

Array
(
    [family] => Array
        (
            [name] => 'ddd
dfdf
dfd'
        )

    [family2] => Array
        (
            [name] => 'ddd dfdf dfd'
        )

)

换行和空格的转换, | 为换行,>空格!



<?php
include "Spyc.class.php";
function parseYaml($string){
    $data = Spyc::YAMLLoadString($string);
    return $data;
}
?>
memcached的基本设置:


-p 监听的端口
-l 连接的IP地址, 默认是本机
-d start 启动memcached服务
-d restart 重起memcached服务
-d stop|shutdown 关闭正在运行的memcached服务
-d install 安装memcached服务
-d uninstall 卸载memcached服务
-u 以的身份运行 (仅在以root运行的时候有效)
-m 最大内存使用,单位MB。默认64MB
-M 内存耗尽时返回错误,而不是删除项
-c 最大同时连接数,默认是1024
-f 块大小增长因子,默认是1.25
-n 最小分配空间,key+value+flags默认是48
-h 显示帮助
mixi的设置,单台:

[/code]
每台memcached服务器仅启动一个memcached进程。分配给memcached的内存为3GB,启动参数如下:


/usr/bin/memcached -p 11211 -u nobody -m 3000 -c 30720
由于使用了x86_64的操作系统,因此能分配2GB以上的内存。32位操作系统中,每个进程最多只能使用2GB内存。也曾经考虑过启动多个分配2GB以下内存的进程,但这样一台服务器上的TCP连接数就会成倍增加,管理上也变得复杂,所以mixi就统一使用了64位操作系统。

另外,虽然服务器的内存为4GB,却仅分配了3GB,是因为内存分配量超过这个值,就有可能导致内存交换(swap)。连载的第2次中前坂讲解过了memcached的内存存储“slab allocator”,当时说过,memcached启动时指定的内存分配量是memcached用于保存数据的量,没有包括“slab allocator”本身占用的内存、以及为了保存数据而设置的管理空间。因此,memcached进程的实际内存分配量要比指定的容量要大,这一点应当注意。

mixi保存在memcached中的数据大部分都比较小。这样,进程的大小要比指定的容量大很多。因此,我们反复改变内存分配量进行验证,确认了3GB的大小不会引发swap,这就是现在应用的数值。



memcached -d -m 1024 -u root -l 172.25.38.70 -p 12000 -c 4096 -P /tmp/memcached.pid   12000
-p 12000 端口
-m 1024  内存设置 1024
-c 4096  同时连接数


这几天编译PHP5.3.1 fast cgi的时候发现一个问题;configure的时候加上--disable-rpath就会报:
char *... configure: error: cannot compute sizeof (char *), 77

去掉这个参数就能正常通过,但是并不是所有的机器上都出这个错误;看来还是和环境有关系。

看了下文档;这个参数貌似是运行时不去某些路径搜索动态库。不是太理解。



checking sys/un.h presence... yes
checking for sys/un.h... yes
checking errno.h usability... yes
checking errno.h presence... yes
checking for errno.h... yes
checking whether zend_object_value is packed... no
checking for sqlite support... yes
checking whether to enable UTF-8 support in sqlite (default: ISO-8859-1)... no
checking for PDO includes... (cached) /usr/local/src/v1.0/software/php-5.3.1/ext
checking for lemon... no
configure: WARNING: lemon versions supported for regeneration of libsqlite parsers: 1.0 (found: none).
checking for char *... yes
checking size of char *... configure: error: cannot compute sizeof (char *), 77
See `config.log' for more details.



3.安装magickwand-0.1.8

unzip magickwand-0.1.8.zip

mv magickwand php-4.3.6/ext/

cd php-4.3.6/ext/magickwand

phpize

cd ../../

rm -rf configure

./buildconf –force

export PATH=${PATH}:/usr/local/ImageMagick/bin

#关键一步,否则编译无法通过,会有这样错误误导你:

.......... checking for ImageMagick / MagickWand in provided path... found in /usr/local/ImageMagick checking for ImageMagick / MagickWand 6.2.4 or greater with /usr/local/ImageMagick/bin/Wand-config... 6.2.6 /usr/local/ImageMagick/bin/Wand-config: line 42: Magick-config: command not found /usr/local/ImageMagick/bin/Wand-config: line 39: Magick-config: command not found ........... ........... checking size of char... configure: error: cannot compute sizeof (char), 77 See `config.log' for more details.


./configure --with-png-dir=/usr --with-gd --enable-gd-native-ttf --with-ttf --with-freetype --without-gdbm --with-gettext --with-ncurses --with-gmp --with-iconv --with-jpeg-dir=/usr  --with-png --enable-ftp --enable-sockets -with-xml --with-dom --with-zlib --enable-track-vars --with-mysql=/usr/local/mysql --with-imagick=/usr/local/ImageMagick --with-apxs2=/usr/local/apache2/bin/apxs

make

make install


补充问题:
如果MagickWand 执行./configure 时,出现checking for MagickSetImageTicksPerSecond in -lWand… NO的错误,可能是您现在安装了两个版本的ImageMagick,且默认的版本低于ImageMagick-6.3.3
可以用Magick-config –version命令查看其版本。
通常是系统安装了rpm包,解决方法是卸载掉libImageMagick包:
rpm -qa | grep 'ImageMagick'
rpm -e ImageMagick*
突然间,机器上的Mysql不能启动了,查看日志发现,INNODB报这样错误:

090819 10:45:09  InnoDB: Error: cannot allocate 2147500032 bytes of
InnoDB: memory with malloc! Total allocated memory
InnoDB: by InnoDB 35493848 bytes. Operating system errno: 12
InnoDB: Check if you should increase the swap file or
InnoDB: ulimits of your operating system.
InnoDB: On FreeBSD check you have compiled the OS with
InnoDB: a big enough maximum process size.
InnoDB: Note that in most 32-bit computers the process
InnoDB: memory space is limited to 2 GB or 4 GB.
InnoDB: We keep retrying the allocation for 60 seconds
InnoDB: Fatal error: cannot allocate the memory for the buffer pool
090819 10:46:09 [ERROR] Plugin 'InnoDB' init function returned error.
090819 10:46:09 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
090819 10:46:09 [Note] /usr/local/webserver/mysql/libexec/mysqld: Normal shutdown

090819 10:46:09 [Warning] 'user' entry 'root@zhangyufeng' ignored in --skip-name-resolve mode.
090819 10:46:09 [Warning] 'user' entry '@zhangyufeng' ignored in --skip-name-resolve mode.
090819 10:46:09 [Note] Event Scheduler: Loaded 0 events
090819 10:46:09 [Note] /usr/local/webserver/mysql/libexec/mysqld: ready for connections.
Version: '5.1.32-log'  socket: '/tmp/mysql.sock'  port: 3306  Source distribution
090819 10:46:09 [Note] Event Scheduler: Purging the queue. 0 events
090819 10:46:09 [Note] /usr/local/webserver/mysql/libexec/mysqld: Shutdown complete

我一开始以为是innoDB的扩展坏掉了,于是重新编译安装了mysql,后来才发现,原来是配置文件中
innodb_buffer_pool_size 设置的值过大了,(我设置了2048M) 呵呵 ,缓冲池过大了,原来没有

出错是因为我没开大的应用,我机器内存是4G,现在跑了个虚拟机后,内存剩余就不足了。
MYSQL数据库从5.1开始支持分区,本人下载了5.1最后的版本5.1.14(最好的版本应该最稳定)。
当尝试分区时,发现MYSQL分区的约束不少。
我打算使用RANGE分区类型,通过日期'BOOK_DATE'每年一个分区。

CREATE TABLE `in_book_main` (
  `BOOK_MAIN_ID` varchar(32) NOT NULL,
  `BOOK_DATE` date NOT NULL,
  `PROVIDER_ID` varchar(32) default NULL,
  `STATUS` varchar(4) NOT NULL,
  `RMK` varchar(400) default NULL,
  PRIMARY KEY  (`BOOK_MAIN_ID`),
  KEY `FK_Reference_7` (`PROVIDER_ID`),
  CONSTRAINT `FK_Reference_7` FOREIGN KEY (`PROVIDER_ID`) REFERENCES `base_provider` (`PROVIDER_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
partition by range (to_days(BOOK_DATE))
(PARTITION p0 VALUES LESS THAN (to_days('2007-01-01')),
PARTITION p1 VALUES LESS THAN (to_days('2008-01-01')) ,
PARTITION p2 VALUES LESS THAN (to_days('2009-01-01')) ,
PARTITION p3 VALUES LESS THAN (to_days('2010-01-01')) ,
PARTITION p4 VALUES LESS THAN (to_days('2011-01-01')) ,
PARTITION p5 VALUES LESS THAN (to_days('2012-01-01')) ,
PARTITION p6 VALUES LESS THAN (to_days('2013-01-01')) ,
PARTITION p7 VALUES LESS THAN (to_days('2014-01-01')) ,
PARTITION p8 VALUES LESS THAN (to_days('2015-01-01')) ,
PARTITION p9 VALUES LESS THAN (to_days('2016-01-01')) ,
PARTITION p10 VALUES LESS THAN (to_days('2017-01-01')),
PARTITION p11 VALUES LESS THAN MAXVALUE );

注意:表的PRIMARY KEY是BOOK_MAIN_ID,有一个FOREIGN KEY引用另外一个表的ID("PROVIDER_ID"),
另外被引用的表结构如下:
CREATE TABLE `base_provider` (
  `PROVIDER_ID` varchar(32) NOT NULL,
  `PROVIDER_NAME` varchar(100) NOT NULL,
  `ADDRESS` varchar(200) default NULL,
  `PHONE` varchar(20) default NULL,
  `CONTRACT_MAN` varchar(20) default NULL,
  `Email` varchar(100) default NULL,
  `RMK` varchar(400) default NULL,
  PRIMARY KEY  (`PROVIDER_ID`),
  UNIQUE KEY `INDEX_PROVIDER_NAME` (`PROVIDER_NAME`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

结果令我 意外的是报错
ERROR 1215 : Cannot add foreign key constraint

外键出错,把添加外键的语句删除
CREATE TABLE `in_book_main` (
  `BOOK_MAIN_ID` varchar(32) NOT NULL,
  `BOOK_DATE` date NOT NULL,
  `PROVIDER_ID` varchar(32) default NULL,
  `STATUS` varchar(4) NOT NULL,
  `RMK` varchar(400) default NULL,
  PRIMARY KEY  (`BOOK_MAIN_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
partition by range (to_days(BOOK_DATE))
(PARTITION p0 VALUES LESS THAN (to_days('2007-01-01')),
PARTITION p1 VALUES LESS THAN (to_days('2008-01-01')) ,
PARTITION p2 VALUES LESS THAN (to_days('2009-01-01')) ,
PARTITION p3 VALUES LESS THAN (to_days('2010-01-01')) ,
PARTITION p4 VALUES LESS THAN (to_days('2011-01-01')) ,
PARTITION p5 VALUES LESS THAN (to_days('2012-01-01')) ,
PARTITION p6 VALUES LESS THAN (to_days('2013-01-01')) ,
PARTITION p7 VALUES LESS THAN (to_days('2014-01-01')) ,
PARTITION p8 VALUES LESS THAN (to_days('2015-01-01')) ,
PARTITION p9 VALUES LESS THAN (to_days('2016-01-01')) ,
PARTITION p10 VALUES LESS THAN (to_days('2017-01-01')),
PARTITION p11 VALUES LESS THAN MAXVALUE );

又报错,这次轮到主键了。
ERROR 1490 : A PRIMARY KEY must include all columns in the table's partitioning function

再把添加主键的语句删除
CREATE TABLE `in_book_main` (
  `BOOK_MAIN_ID` varchar(32) NOT NULL,
  `BOOK_DATE` date NOT NULL,
  `PROVIDER_ID` varchar(32) default NULL,
  `STATUS` varchar(4) NOT NULL,
  `RMK` varchar(400) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
partition by range (to_days(BOOK_DATE))
(PARTITION p0 VALUES LESS THAN (to_days('2007-01-01')),
PARTITION p1 VALUES LESS THAN (to_days('2008-01-01')) ,
PARTITION p2 VALUES LESS THAN (to_days('2009-01-01')) ,
PARTITION p3 VALUES LESS THAN (to_days('2010-01-01')) ,
PARTITION p4 VALUES LESS THAN (to_days('2011-01-01')) ,
PARTITION p5 VALUES LESS THAN (to_days('2012-01-01')) ,
PARTITION p6 VALUES LESS THAN (to_days('2013-01-01')) ,
PARTITION p7 VALUES LESS THAN (to_days('2014-01-01')) ,
PARTITION p8 VALUES LESS THAN (to_days('2015-01-01')) ,
PARTITION p9 VALUES LESS THAN (to_days('2016-01-01')) ,
PARTITION p10 VALUES LESS THAN (to_days('2017-01-01')),
PARTITION p11 VALUES LESS THAN MAXVALUE );

成功,但不是我所想要的,因为没有了主键和外键。上网找了些资料,了解到确实主键要去掉,但是外键问题没有找到。
牺牲主键我可以接受,但是外键要去掉我很不理解也不能接受。
请~~~
今天看到一个老兄的问题,
大概如下:
查询出部门的最低工资的userid 号
表结构:

D号      工资      部门
userid  salary   dept
  1      2000      1
  2      1000      1
  3      500       2
  4      1000      2

有一个高人给出了一种答案:
SELECT MIN (salary) OVER (PARTITION BY dept ) salary, dept  
FROM ss

运行后得到:
1000 1
1000 1
500 2
500 2
楼主那位老兄一看觉得很高深。大叹真是高人阿~
我也觉得这位老兄实在是高啊。

但我仔细研究一下发现那位老兄对PARTITION BY的用法理解并不深刻。并没有解决楼主的问题。
大家请看我修改后的语句
SELECT userid,salary,dept,MIN (salary) OVER (PARTITION BY dept ) salary  
FROM ss

运行后的结果:
userid   salary  dept      MIN (salary) OVER (PARTITION BY dept )
1 2000 1 1000
2 1000 1 1000
3 500 2 500
4 1000 2 500

大家看出端倪了吧。
高深的未必适合。

一下是我给出的答案:
SELECT * FROM SS
INNER JOIN (SELECT MIN(SALARY) AS SALARY, DEPT FROM SS GROUP BY DEPT) SS2
USING(SALARY,DEPT)

运行后的结果:
salary  dept     userid
1000 1 2
500 2 3

由此我想到总结一下group by和partition by的用法
group by是对检索结果的保留行进行单纯分组,一般总爱和聚合函数一块用例如AVG(),COUNT(),max(),main()等一块用。

partition by虽然也具有分组功能,但同时也具有其他的功能。
它属于oracle的分析用函数。
借用一个勤快人的数据说明一下:

sum()   over   (PARTITION   BY   ...)   是一个分析函数。   他执行的效果跟普通的sum   ...group   by   ...不一样,它计算组中表达式的累积和,而不是简单的和。  
  
  表a,内容如下:  
  B C D  
  02 02 1  
  02 03 2  
  02 04 3  
  02 05 4  
  02 01 5  
  02 06 6  
  02 07 7  
  02 03 5  
  02 02 12  
  02 01 2  
  02 01 23  
  
  select   b,c,sum(d)   e   from   a   group   by   b,c  
  得到:  
  B C E  
  02 01 30  
  02 02 13  
  02 03 7  
  02 04 3  
  02 05 4  
  02 06 6  
  02 07 7  
  
  而使用分析函数得到的结果是:  
  SELECT   b,   c,   d,   SUM(d)   OVER(PARTITION   BY   b,c   ORDER   BY   d)   e   FROM   a  
  B C E  
  02 01 2  
  02 01 7  
  02 01 30  
  02 02 1  
  02 02 13  
  02 03 2  
  02 03 7  
  02 04 3  
  02 05 4  
  02 06 6  
  02 07 7  
  结果不一样,这样看还不是很清楚,我们把d的内容也显示出来就更清楚了:  
  SELECT   b,   c,   d,SUM(d)   OVER(PARTITION   BY   b,c   ORDER   BY   d)   e   FROM   a  
  B C D E  
  02 01 2 2                     d=2,sum(d)=2  
  02 01 5 7                     d=5,sum(d)=7  
  02 01 23 30                   d=23,sum(d)=30  
  02 02 1 1                     c值不同,重新累计  
  02 02 12 13  
  02 03 2 2  
  02 03 5 7  
  02 04 3 3  
  02 05 4 4  
  02 06 6 6  
  02 07 7 7
今天看了MYSQL官方网站,发现这个UDFs,UDFs 是 User Defined Functions 的缩写,指 Mysql 的用户定义函数,应用可以通过使用这些函数从 Mysql5.0 以上版本的数据库中访问 Memcached 写入或者获得数据。此外,从 Mysql5.1 开始支持触发器,这样就可以在触发器中使用 UDFs 直接更新 Memcached 的内容,减轻了应用程序设计和编写的复杂性。下面我们简要介绍 UDFs 的安装和使用:
  1、安装Libmemcached(memcached的客户端C API)
  下载地址:http://download.tangent.org/
       # ./configure –prefix=/usr  && make && make install
       注意:请安装在/usr下,不然后面安装memcached_functions_mysql的时候找不到,还要指定PKG_CONFIG_PATH,麻烦。

  2、安装memcached_functions_mysql
  下载地址:http://download.tangent.org/

  # ./configure –with-mysql=/usr/local/mysql/bin/mysql_config
      安装完成之后,需要将 libmemcached_functions_mysql 的库文件拷贝到 mysql/lib 目录下的 plugin 目录中。
  # cp /usr/local/lib/libmemcached_functions_mysql* /usr/local/mysql/lib/plugin/.
      # shell> mysql <sql/install_functions.sql

    3、触发器实现
  定义memcached服务器
  mysql> SELECT memc_servers_set(’192.168.0.1:11211,192.168.0.2:11211′);
  创建测试表:
  mysql> create table test3 (
     -> id int(3) not null,
        -> name varchar(64) not null default ”,
        -> primary key (id)
        -> );
    创建触发器
  mysql>DELIMITER |
      ->CREATE TRIGGER test3_insert
      ->BEFORE INSERT ON test3
      ->FOR EACH ROW BEGIN
      ->SET @mm = memc_set(concat(’id:’,NEW.id), NEW.name);
      ->END |

  可以参见官方网站:http://dev.mysql.com/doc/refman/5.1/en/ha-memcached-interfaces-mysqludf.html

后记:我觉得它的应用场景应该是写操作不太频繁,但查询量非常大的网站,memcache不超时的缓存数据库的数据,当数据库发生更改的时候,利用 mysql的insert,update,delete触发器来更改memcached服务器的数据。但mysql的操作数据类型不支持数组,memc_set应该也不支持对象或者数组等数据类型。实现起来有点难度。
续记:MYSQL UDF OF JSON
  基于以上的试用感想,我认为应该有UDF可以将数据行转成json格式的数据,这样就真的可以实现前端不用访问数据库的想法了,GOOGLE真是个好东西,google后还真找到了:UDF Repository for MySQL,外国人真是有开源精神:),这是一个MYSQL UDF库的网站,我在里面找到for json的udf。

下载地址:http://www.mysqludf.org/lib_mysqludf_json/lib_mysqludf_json_0.0.2.tar.gz
安装:
# mkdir udf_of_json
# cd udf_of_json
# wget http://www.mysqludf.org/lib_mysqludf_json/lib_mysqludf_json_0.0.2.tar.gz
# tar zxvf lib_mysqludf_json_0.0.2.tar.gz
# cp ./lib_mysqludf_json.so /usr/local/mysql/lib/plugin/.
# mysql -u root
mysql> source ./ lib_mysqludf_json.sql

测试:
DELIMITER ||
CREATE TRIGGER user_insert
AFTER INSERT ON users
FOR EACH ROW BEGIN
SELECT json_array(username,user_type,real_name,password,active,last_login,description) into @user_info FROM users where user_id=NEW.user_id;
SET @mm= memc_set(concat(’user_info_’,NEW.user_id), @user_info);
END ||

它还支持中文真是让人很欣喜,但不支持多行集,如果我用存储过程或者自定义函数自己写一个呢。研究中。。。。


继续参看:
http://www.jackxiang.com/post/2494/
点击在新窗口中浏览此图片


/*
index.php   程序入口,用来构造sql(如查询,更新)
config.php  配置参数(memcache,mysql)
init.php    封装memcached操作(memcache连接,设置,获取)
mysqli.php  封闭mysql操作(mysql主连接,mysql从连接,mysql主更新,mysql从查询)
*/

index.php
<?php
require 'init.php';              //加载init.php
$mem = new Memcached;            //建立memcached对象,对象为$mem
/*
$mem->set('en_xx','bucuo',0,30); //测试连接memcached,用来调试很不错。
echo($mem->get('en_xx'));
$mem->set('cn_jjyy','wokao',0,30);
echo($mem->get('cn_jjyy'));
*/

require 'mysqli.php';
$sq = new Mysql;    
//下面这两个sql是人为构造的,这也可以做成一个接口                
$sql = "Select * from traffic";                  
//$sql = "insert into traffic(id,acct_mth,amount) values(14,14,46)";
//进行判断,如果sql语句中有头有select(不区分大小写)
if(preg_match ("/^select/i", $sql)){
    $mdsql = md5($sql);
    if(!$result=$mem->get('cn_'.$mdsql)){      //这里选择的是cn memcached,大家也可以根据需求在前面做个条件来将数据存取放入到另一个memcached中。
           $result = $sq->fetArray($sql); //查询是 从mysql
           foreach($result as $var){
                echo $var['amount'];
            }
           $mem->set('cn_'.$mdsql,$result,0,600); //添加到 名为cn的memcached 服务器
    }else{
            foreach($result as $var){
                echo $var['amount']."<br>";
          }
    }
}else{
    $sq->mquery($sql);     //更新是 主mysql
}

?>



config.php

<?php
$memcached = array(
     'cn'=>array('192.168.x.y',11211),
     'en'=>array('192.168.y.x',11211)
     );
$mysql    = array(
     'master'=>array('x','root','','test'),
     'slave_1'=>array('y','root','','test'),
     'slave_2'=>array('z','root','','test') //可以灵活添加多台从服务器
     );
?>




init.php


<?php
class Memcached
{
private $mem;
public $pflag=''; // memcached pconnect tag
    private function memConnect($serkey){     //建立memcached连接,这些都很容易理解
                require 'config.php';
                $server = $memcached;  //$memcached是cn,en的数组
                $this->mem = new Memcache;  
                $link = !$this->pflag ? 'connect' : 'pconnect' ;
                $this->mem->$link($server[$serkey][0],$server[$serkey][1]) or $this->errordie('memcached connect error');
      }

    public function set($ser_key,$values,$flag='',$expire=''){  //设置获取数据
               $this->memConnect($this->tag($ser_key));
                if($this->mem->set($ser_key,$values,$flag,$expire)) return true;
                else return false;
      }

    public function get($ser_key){
               $this->memConnect($this->tag($ser_key));
               if($var=$this->mem->get($ser_key)) return $var;
               else return false;
      }
    private function tag($ser_key){
               $tag=explode('_',$ser_key);
               return $tag[0];
      }
    private function errordie($errmsg){
                die($errmsg);
      }
/*  这段函数是我用来在类中做调试用的。
    public function show($messages){
               echo $messages;
    }
*/
}
?>





mysqli.php

<?php
class Mysql
{
/* 这段函数是我用来调试的
public function show($messages){
               var_dump($messages);
    }
*/
private   $mysqlmaster;
private   $myssqlslave;

public function __construct(){   //构造函数
         require 'config.php';
         $msg = $mysql;          //$mysql是master,slave_1,slave_2
         $this->mysqlmaster = new mysqli($msg['master'][0],$msg['master'][1],$msg['master'][2],$msg['master'][3]); //master mysql
         $this->mysqlslave = $this->autotranscat($msg); // slave mysql

         if(mysqli_connect_errno()){
                     printf("Connect failed: %s\n",mysqli_connect_error());
                      exit();
          }
        if(!$this->mysqlmaster->set_charset("latin1") && !$this->mysqlslave->set_charset("latin1")){
                    exit("set charset error");
          }
}
private function autotranscat($mysql){        //这段函数的作用是获取从服务器序列号,如1,2
        session_start();                      //启动会话
       $_SESSION['SID']!=0 || $_SESSION['SID']=0;  //如果不为0,就不做赋值操作(那第一次访问的话,肯定会做赋值操作的)
        if($_SESSION['SID'] >=count($mysql)-1) $_SESSION['SID'] = 1;  //上面那个动作是为这个动作准备的
        else $_SESSION['SID']++;
        $key = 'slave_'.$_SESSION['SID'];
        return new mysqli($mysql[$key][0],$mysql[$key][1],$mysql[$key][2],$mysql[$key][3]);
}

public function mquery($sql){ //mysql主 insert update
if(!$this->mysqlmaster->query($sql)){
   return false;
}
}

public function squery($sql){   //mysql从 查询
if($result=$this->mysqlslave->query($sql)){
   return $result;
}else{
   return false;
};
}
public function fetArray($sql){  //mysql从 查询 入口
if($result=$this->squery($sql)){
   while($row=$result->fetch_array(MYSQLI_ASSOC)){
    $resultraa[] = $row;
   };
   return $resultraa;
}
}
}
?>

点击在新窗口中浏览此图片
linux删除目录很简单,很多人还是习惯用rmdir,不过一旦目录非空,就陷入深深的苦恼之中……
直接rm就可以了,不过要加两个参数-rf 即:rm -rf   目录名字
-r 就是向下递归,不管有多少级目录,一并删除
-f 就是直接强行删除,不作任何提示的意思

需要提醒的是:使用这个rm -rf的时候一定要格外小心,linux没有回收站的

当然,rm还有更多的其他参数和用法,man rm就可以查看了


名称:rmdir
使用权限:于目前目录有适当权限的所有使用者
使用方式: rmdir [-p] dirName
说明: 删除空的目录。
参数: -p 是当子目录被删除后使它也成为空目录的话,则顺便一并删除。
范例:
将工作目录下,名为 AAA 的子目录删除 :
rmdir AAA
在工作目录下的 BBB 目录中,删除名为 Test 的子目录。若 Test 删除后,BBB 目录成为空目录,则 BBB 亦予删除。
rmdir -p BBB/Test
分页: 180/272 第一页 上页 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 下页 最后页 [ 显示模式: 摘要 | 列表 ]