attachEvent与addEventListener区别

适应的浏览器版本不同,同时在使用的过程中要注意
attachEvent方法          按钮onclick
addEventListener方法    按钮click

有关addEventListener函数的相关参数请点击这里查看

两者使用的原理:可对执行的优先级不一样,下面实例讲解如下:
attachEvent方法,为某一事件附加其它的处理事件。(不支持Mozilla系列)

addEventListener方法 用于 Mozilla系列

举例: document.getElementById(“btn”).onclick = method1;
document.getElementById(“btn”).onclick = method2;
document.getElementById(“btn”).onclick = method3;如果这样写,那么将会只有medhot3被执行

写成这样:
var btn1Obj = document.getElementById(“btn1”); //object.attachEvent(event,function);
btn1Obj.attachEvent(“onclick”,method1);
btn1Obj.attachEvent(“onclick”,method2);
btn1Obj.attachEvent(“onclick”,method3);执行顺序为method3->method2->method1

如果是Mozilla系列,并不支持该方法,需要用到addEventListener var btn1Obj = document.getElementById(“btn1”);
//element.addEventListener(type,listener,useCapture);
btn1Obj.addEventListener(“click”,method1,false);
btn1Obj.addEventListener(“click”,method2,false);
btn1Obj.addEventListener(“click”,method3,false);执行顺序为method1->method2->method3

使用实例:

1。 var el = EDITFORM_DOCUMENT.body;
//先取得对象,EDITFORM_DOCUMENT实为一个iframe
if (el.addEventListener){
el.addEventListener(‘click’, KindDisableMenu, false);
} else if (el.attachEvent){
el.attachEvent(‘onclick’, KindDisableMenu);
}2。 if (window.addEventListener) {
window.addEventListener(‘load’, _uCO, false);
} else if (window.attachEvent) {
window.attachEvent(‘onload’, _uCO);
}

如何记录mysql慢查询sql日志

修改my.cnf的mysqld部分:
long_query_time = 1              //定义慢查询的时间1表示1秒
–log-slow-queries[=file_name]   //记录慢查询到日志文件
–log-queries-not-using-indexes //将没使用索引的sql记录到日志文件
实例:
[mysqld]
long_query_time = 1
log-slow-queries = /usr/local/mysql5.0.40/var/slow_query.log
log-queries-not-using-indexes = true

“too many connections”找不到问题所在,后来发现打开mysql的慢查询会有很大的帮助就搞了一个. Continue reading

mysql优化-缓存篇

在整体的系统运行过程中,数据库服务器 MySQL 的压力是最大的,不仅占用很多的内存和 cpu 资源,而且占用着大部分的磁盘 io 资源,连 PHP 的官方都在声称,说 PHP 脚本 80% 的时间都在等待 MySQL 查询返回的结果。由此可见,提高系统的负载能力,降低 MySQL 的资源消耗迫在眉睫。
1、页面缓存功能:
页面缓存功能降低MySQL的资源消耗的(系统本身就已经考虑,采用生成HTML页面,大大降低了数据库的压力)。
2、mysql服务器的优化

2.1、修改全站搜索
修改my.ini(my.cnf) ,在 [mysqld] 后面加入一行“ft_min_word_len=1”,然后重启Mysql,再登录网站后台(模块管理->全站搜索)重建全文索引。
2.2、记录慢查询sql语句,修改my.ini(my.cnf),添加如下代码: Continue reading

Apache 的信息查看模块——Server-Status

前提:启用httpd.conf配置文件里的两个模块:|
LoadModule status_module modules/mod_status.so
LoadModule info_module modules/mod_info.so

本文我们将讨论使用 mod_status 和 mod_info to 来告诉你目前服务器的工作情况
我可以得到什么样的信息?
使用 mod_status,你可以知道谁在你的服务器上看些什么东西,以及有多少人连在Web 服务器上。还有其他可能你的客户不关心的信息,但是对于你,一个站点管理员来说,却是十分有用的信息。

客户喜欢这些资料
我不知道你的客户都是怎样的人物,但是我的客户喜欢我提供的信息。每天一次的信息还不够,因为到一天结束时才知道就太晚了。所以他们喜欢知道现在正在发生的事情。 Continue reading

解决win环境下Apache占用大量内存的问题

我有个服务是在windows下的Apache2提供的。访问量不是很大,隔4、5天竟然停止服务,调查发现Apache2的进程httpd.exe占用内存达到了1.5G。在网上找到如下解决办法。

用记事本打开apache2\conf\httpd.conf,查找MaxRequestsPerChild,将MaxRequestsPerChild 0改成MaxRequestsPerChild 50即可。

原因是:

  通常在“Windows任务管理器-进程”中可以看到两个apache.exe进程,一个是父进程、一个是子进程,父进程接到访问请求后,将请 求交由子进程处理。MaxRequestsPerChild这个指令设定一个独立的子进程将能处理的请求数量。在处理 “MaxRequestsPerChild 数字”个请求之后,子进程将会被父进程终止,这时候子进程占用的内存就会释放,如果再有访问请求,父进程会重新产生子进程进行处理。

  如果MaxRequestsPerChild缺省设为0(无限)或较大的数字(例如10000以上)可以使每个子进程处理更多的请求,不会因为 不断终止、启动子进程降低访问效率,但MaxRequestsPerChild设置为0时,如果占用了200~300M内存,即使负载下来时占用的内存也 不会减少。内存较大的服务器可以设置为0或较大的数字。内存较小的服务器不妨设置成30、50、100,以防内存溢出。

因为Windows NT下Apache只能启动父子两个进程,因此只能通过增大单个进程的线程数以及单个进程能够处理的最大请求数来进行优化。其他优化的参数同Linux系统下是一样的,大家可以加以参考。下面针对上述两个参数给出一个建议的设置:

    ThreadsPerChild 250
    MaxRequestsPerChild 5000

 

来源:

1. http://mingling123456.blog.163.com/blog/static/1066189200814112544921/

2. http://www.javatang.com/archives/2008/02/19/0801260.html

windows下nginx-0.7.10+php-5.2.6+fastcgi安装日志

最近心里有点痒,打算怀下旧,搞个php玩玩。找了几台服务器想装个php,虽然是举手之劳,但是总觉得有点不方便。另外家里的宽带总被占线,所以在服务器上做测试那也比较痛苦。

所以就想在本机弄个,记得以前有个apache php mysql的整合安装版,这可是个好东西,如果有人问我怎么在windows装php啊,我顺口就告诉他找这个,的确可以省不少力气。

不过今天我就不想用这古老的玩意装机了,虽然这东西装得是快,不过我已经不怎么记得起apache的配置怎么写,甚至有点厌恶写那配置。

于是我下了个nginx的windows版,然后再找个php的windows版,在http://www.kevinworthington.com/category/computers/nginx/,下完后先装nginx,没什么复杂,启动,在浏览器输入http://127.0.0.1,没有反应,看一下netstat -an,发现貌似80端口存在,估计这个端口不是nginx占用的,于是关掉所有开启的程序,再启动,再刷新,就可以看到有一个测试页出现了。

这样算是弄完了一个东西,接下来装php吧,先把它解压到d盘,放在d:\php-5.2.6-win32这个目录,有点冗长,不过算了,现在老了也不想对这种太过纠缠。接下来思维就有点短路了,因为windows上哪去找个什么spawn-fcgi来用啊,没办法,google一下。

打开了十几个网页,还是在一篇介绍lighttpd的文章里找到了办法,lighttpd对nginx还是大有帮助的,nginx安装php的办法,linux和windows下都是lighttpd先有,nginx在后面照着抄就可以了,他们所使用的思路都是一样的。那篇lighttpd的文章看来是提供的一份完整解决方案,我从里面揪出了一句话:

php-cgi -b 127.0.0.1:521

用这行小命令就可以启动php-cgi进程和端口了。不过运行时这个dos窗口不会关闭,也挺碍眼的,所以根据该文所述,用一个RunHiddenConsole.exe来启动,就可以了,不知道怎么关闭?很笨的说,ctrl alt del,杀死php-cgi进程就可以了。

最后贴一份nginx的php配置文件,小改一下端口,写一个phpinfo页,运行正常。

—————————————————————–

nginx conf:

server {
listen 127.0.0.1:80;
server_name localhost;

location / {
root d:/php/ ;
}

location ~ .php$ {
fastcgi_pass   127.0.0.1:521;
fastcgi_index  index.php;
fastcgi_param  SCRIPT_FILENAME  d:/php$fastcgi_script_name;
include        fastcgi_params;
}
}

—————————————————————–

我的php解压在d:\php-5.2.6-win32,在里面多放了几个东东:

d:\php-5.2.6-win32\RunHiddenConsole.exe

这个exe在http://www.box.net/shared/vfvqyjhday这里找得到

d:\php-5.2.6-win32\start_fastcgi

这是个快捷方式,先造一个RunHiddenConsole.exe的快捷方式,然后进入属性修改目标为

D:\php-5.2.6-Win32\RunHiddenConsole.exe php-cgi -b 127.0.0.1:521

当然,亦可写个bat,目的都是一样的

—————————————————————–

使用的时候,开启nginx,然后执行一下d:\php-5.2.6-win32\start_fastcgi就可以了,php和nginx的其他配置,自己打理去咯。

附说-nginx php的工作原理:

nginx以一种类似代理的模式,去连接fastcgi的端口,php需要开启cgi引擎,然后监听相应的端口即可,fastcgi下nginx和php的耦合度比较小,所以相互影响会减到最低限度。spawn-fcgi和RunHiddenConsole.exe分别是linux和windows下用来管理php-cgi的工具,spawn-fcgi可以制造多个php-cgi进程监听同样端口比较强大,RunHiddenConsole仅仅是隐藏掉cmd窗口,就算不用这两个工具,php-cgi也能启动。

如何收集及删除列的统计信息

本文只涉及使用dbm_stats来收集或删除列的统计信息的一些命令,以备查询。

测试表如下(实验环境为10.2.0.4):

SQL> create table test(i int,a varchar2(30));
Table created.

SQL> insert into test select rownum,object_name from all_objects;
9907 rows created.

简单的说,列的统计信息,主要包括两种类型:

  • 只有基本信息:收集的统计信息只有1个桶(bucket)
  • 包含柱状图信息:收集的统计信息包含2到254个桶

也就是说,如果想收集列的基本信息,同时不希望收集柱状图,则需要指定bucket的size为1:

SQL> exec dbms_stats.gather_table_stats(user, 'TEST',
cascade=>false, method_opt=>'for columns i size 1');

PL/SQL procedure successfully completed.                                                                             

SQL> select column_name,num_distinct,num_buckets,low_value,high_value,density,avg_col_len,histogram
  2  from user_tab_columns where table_name='TEST';

COLUMN_NAM NUM_DISTINCT NUM_BUCKETS LOW_VALUE  HIGH_VALUE    DENSITY AVG_COL_LEN HISTOGRAM
---------- ------------ ----------- ---------- ---------- ---------- ----------- ---------------
I                  9907           1 C102       C26408     .000100939           4 NONE
A                                                                                NONE

如果要收集列的柱状图信息,则bucket的个数必须大于等于2(最多不超过254)

SQL> exec dbms_stats.gather_table_stats(user, 'TEST',
cascade=>false, method_opt=>'for columns i size 2');

PL/SQL procedure successfully completed.

SQL> select column_name,num_distinct,num_buckets,low_value,high_value,density,avg_col_len,histogram
  2  from user_tab_columns where table_name='TEST';

COLUMN_NAM NUM_DISTINCT NUM_BUCKETS LOW_VALUE  HIGH_VALUE    DENSITY AVG_COL_LEN HISTOGRAM
---------- ------------ ----------- ---------- ---------- ---------- ----------- ---------------
I                  9907           2 C102       C26408     .000100939           4 HEIGHT BALANCED
A                                                                                NONE

如果要删除列已有的柱状图信息而保留列的基本统计信息,则需要重新收集bucket为1的统计信息

SQL> exec dbms_stats.gather_table_stats(user, 'TEST',
cascade=>false, method_opt=>'for columns i size 1');

PL/SQL procedure successfully completed.

SQL> select column_name,num_distinct,num_buckets,low_value,high_value,density,avg_col_len,histogram
  2  from user_tab_columns where table_name='TEST';

COLUMN_NAM NUM_DISTINCT NUM_BUCKETS LOW_VALUE  HIGH_VALUE    DENSITY AVG_COL_LEN HISTOGRAM
---------- ------------ ----------- ---------- ---------- ---------- ----------- ---------------
I                  9907           1 C102       C26408     .000100939           4 NONE
A                                                                                NONE

这个操作明显不太合理,重新收集统计信息的代价有时候是很大的,所以Oracle11g对此做出了改进,允许只删除柱状图而保留基本统计信息,命令语法如下:

exec dbms_stats.delete_column_stats('', '
', '', col_stat_type=>'HISTOGRAM');

而要彻底删除整个列的统计信息,则需要调用delete_column_stats过程

SQL> exec dbms_stats.delete_column_stats(user, 'TEST', 'I');

PL/SQL procedure successfully completed.

SQL> select column_name,num_distinct,num_buckets,low_value,high_value,density,avg_col_len,histogram
  2  from user_tab_columns where table_name='TEST';

COLUMN_NAM NUM_DISTINCT NUM_BUCKETS LOW_VALUE  HIGH_VALUE    DENSITY  AVG_COL_LEN HISTOGRAM
---------- ------------ ----------- ---------- ---------- ----------  ----------- ---------------
I                                                                                 NONE
A                                                                                 NONE

可以在同一个过程中收集多个列的统计信息,并且可以为不同的列指定不同的bucket个数:

SQL> exec dbms_stats.gather_table_stats(user, 'TEST',
cascade=>false, method_opt => 'for columns size 1 T for columns size 2 A');

PL/SQL procedure successfully completed.

SQL> select column_name,num_distinct,num_buckets,low_value,high_value,density,avg_col_len,histogram
  2  from user_tab_columns where table_name='TEST';

COLUMN_NAM NUM_DISTINCT NUM_BUCKETS LOW_VALUE  HIGH_VALUE              DENSITY AVG_COL_LEN HISTOGRAM
---------- ------------ ----------- ---------- -------------------- ---------- ----------- ---------------
I                  9907           1 C102       C26408               .000100939           4 NONE
A                  7376           2 41         5F75746C245F6C6E635F .000185239          18 HEIGHT BALANCED
                                               696E645F7061727473

值得注意的是,从上一篇文章我们知道,9i的dbms_stats中,method_opt的默认值是FOR ALL COLUMNS SIZE 1,也就是收集列的基本统计信息而不收集柱状图信息,而10g的默认值则变成了FOR ALL COLUMNS SIZE AUTO,则Oracle在收集列的基本信息之外,还会根据情况收集某些列的柱状图。

如何根据rowid获取extent_id

我们知道,rowid是由四部分组成的,分别是data_object_id,file_id,block_number和row_number,通过oracle提供的dbms_rowid包可以很方便的将一串rowid解析出上述四部分的内容。然后根据这些信息,则可以获取其extent_id。

SYS@datac>declare
  2  v_block_id number;
  3  v_file_id number;
  4  v_object_id number;
  5  v_extent_id number;
  6  v_object_name varchar2(30);
  7  v_owner varchar2(30);
  8  v_rowid varchar2(20):='AAACrKAAXAAAAzUAAH';
  9  begin
 10  select dbms_rowid.ROWID_BLOCK_NUMBER(v_rowid),
 11         dbms_rowid.ROWID_RELATIVE_FNO(v_rowid),
 12         dbms_rowid.ROWID_OBJECT(v_rowid)
 13   into v_block_id,v_file_id,v_object_id
 14  from dual;
 15
 16  select owner,object_name
 17    into v_owner,v_object_name
 18  from dba_objects
 19  where data_object_id=v_object_id;
 20
 21  select extent_id into v_extent_id
 22  from dba_extents
 23  where owner=v_owner
 24  and segment_name=v_object_name
 25  and file_id=v_file_id
 26  and v_block_id between block_id and block_id+blocks-1;
 27
 28  dbms_output.put_line('         rowid: '||v_rowid);
 29  dbms_output.put_line('       file_id: '||v_file_id);
 30  dbms_output.put_line('      block_id: '||v_block_id);
 31  dbms_output.put_line('data_object_id: '||v_object_id);
 32  dbms_output.put_line('         owner: '||v_owner);
 33  dbms_output.put_line('   object_name: '||v_object_name);
 34  dbms_output.put_line('     extent_id: '||v_extent_id);
 35  end;
 36  /
         rowid: AAACrKAAXAAAAzUAAH
       file_id: 23
      block_id: 3284
data_object_id: 10954
         owner: NINGOO
   object_name: TEST
     extent_id: 5

将上述代码打包到一个shell脚本中,rowid通过参数传入,则可以更方便日常环境中使用。工欲善其事,必先利其器,将经验转化为工具,利用工具提升效率,才能做一个Lazy DBA

$ tbsql rowid AAACrKAAXAAAAzUAAH
         rowid: AAACrKAAXAAAAzUAAH
       file_id: 23
      block_id: 3284
data_object_id: 10954
         owner: NINGOO
   object_name: TEST
     extent_id: 5

$ tbsql rowid AAACrKAAZAAABiiAAR
         rowid: AAACrKAAZAAABiiAAR
       file_id: 25
      block_id: 6306
data_object_id: 10954
         owner: NINGOO
   object_name: TEST
     extent_id: 7

如何获得Oracle用户创建和授权语句

有时候,我们需要在不同的库中复制用户定义,比如需要在一个测试库中创建和产品库中同名的用户,并且拥有同样的权限。或者在同一个库中创建一个不同名的用户,但是和另外一个用户拥有同样的权限等。换句话说,就是需要获得某个用户的创建和授权语句。

可以通过SQL从一些数据字典中查询到授权信息,生成授权语句:

undefine user_name
set pagesize 1000
select ‘grant ‘||tt.granted_role||’ to ‘||tt.grantee||’;’ as SQL_text
from dba_role_privs tt where tt.grantee=(upper(‘&&user_name’))
union all
select ‘grant ‘||tt.privilege||’ to ‘||tt.grantee||’;’
from dba_sys_privs tt where tt.grantee=(upper(‘&&user_name’))
union all
select ‘grant ‘||tt.privilege||’ on ‘||owner||’.’||table_name||’ to ‘||tt.grantee||’;’
from dba_tab_privs tt where tt.grantee=(upper(‘&&user_name’))
union all
select ‘alter user ‘||tt.user_name||’ quota ‘||maxblocks*blocksize||’ on ‘||ts_name||’;’
from KU$_TSQUOTA_VIEW tt where tt.user_name=(upper(‘&&user_name’));

 

另外,通过Oracle提供的dbms_metadata包,可以获得更加详细准确的创建用户以及授权的DDL语句,注意在9i中dbms_output.put_line中限制一行不能超过255个字符,所以如果某些授权语句超长,可能无法打印出来,折衷的办法可能,先将结果插入的临时表然后select出来,或者将一行截断循环打印,或者干脆使用前面的SQL语句直接查数字字典表就没有这个限制了:

set serveroutput on size 1000000
set verify off
undefine user_name
declare
 v_name varchar2(30) := upper(‘&user_name’);
 no_grant exception;
 pragma exception_init( no_grant, -31608 );
begin
 dbms_metadata.set_transform_param(dbms_metadata.SESSION_TRANSFORM, ‘SQLTERMINATOR’, TRUE);
 dbms_output.enable(1000000);
 dbms_output.put_line(dbms_metadata.get_ddl(‘USER’,v_name));
 begin
   dbms_output.put_line(dbms_metadata.get_granted_ddl(‘SYSTEM_GRANT’,v_name));
 exception
   when no_grant then dbms_output.put_line(‘– No system privs granted’);
 end;
 begin
   dbms_output.put_line(dbms_metadata.get_granted_ddl(‘ROLE_GRANT’,v_name));
 exception
   when no_grant then dbms_output.put_line(‘– No role privs granted’);
 end;
 begin
   dbms_output.put_line(dbms_metadata.get_granted_ddl(‘OBJECT_GRANT’,v_name));
 exception
   when no_grant then dbms_output.put_line(‘– No object privs granted’);
 end;
 begin
  dbms_output.put_line(dbms_metadata.get_granted_ddl(‘TABLESPACE_QUOTA’,v_name));
 exception
   when no_grant then dbms_output.put_line(‘– No tablespace quota specified’);
 end;
 dbms_output.put_line(dbms_metadata.get_granted_ddl(‘DEFAULT_ROLE’, v_name ));
exception
 when others then
  if SQLCODE = -31603 then dbms_output.put_line(‘– User does not exists’);
  else raise;
  end if;
end;
/

运行结果如下:

输入 user_name 的值:  NinGoo

   CREATE USER “NINGOO” IDENTIFIED BY VALUES
‘S:76033D49338E38166B0C090A4447B3D58A70B16C2001A39D7AA844B25616;DABAE35759’
      DEFAULT TABLESPACE “USERS”
      TEMPORARY TABLESPACE “TEMP”;
  GRANT UNLIMITED TABLESPACE TO “NINGOO”;
   GRANT “CONNECT” TO “NINGOO”;
   GRANT “RESOURCE” TO “NINGOO”;
   GRANT “DBA” TO “NINGOO”;
  GRANT “PLUSTRACE” TO “NINGOO”;
  GRANT SELECT ON “SYS”.”V_$PROCESS” TO “NINGOO”;
  GRANT SELECT ON “SYS”.”V_$SESSION” TO “NINGOO”;

  DECLARE
  TEMP_COUNT NUMBER;
  SQLSTR VARCHAR2(200);
BEGIN
  SQLSTR :=
‘ALTER USER “NINGOO” QUOTA 1048576000 ON “USERS”‘;
  EXECUTE IMMEDIATE
SQLSTR;
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE = -30041 THEN
      SQLSTR
:= ‘SELECT COUNT(*) FROM USER_TABLESPACES
              WHERE TABLESPACE_NAME =
”USERS” AND CONTENTS = ”TEMPORARY”’;
      EXECUTE IMMEDIATE SQLSTR INTO
TEMP_COUNT;
      IF TEMP_COUNT = 1 THEN RETURN;
      ELSE RAISE;
      END
IF;
    ELSE
      RAISE;
    END IF;
END;
/

   ALTER USER “NINGOO” DEFAULT ROLE ALL;

PL/SQL 过程已成功完成。