调优实践04–利用FORCE_MATCHING_SIGNATURE捕获非绑定变量SQL语句

利用FORCE_MATCHING_SIGNATURE捕获非绑定变量SQL语句
1.10g之后的v$sql视图增加了两列:
1.EXACT_MATCHING_SIGNATURE:Signature calculated on the normalized SQL text. The normalization includes the removal of white space and the uppercasing of all non-literal strings.
2.FORCE_MATCHING_SIGNATURE:Signature used when the CURSOR_SHARING parameter is set to FORCE,也就是SQL语句在CURSOR_SHARING=FORCE模式下运行的签名值;
2.控制共享游标的参数:CURSOR_SHARING
1.FORCE:在不改变语义的情况下都使用游标共享,可能使用的并不是最优的执行计划,强制绑定变量,并在左边的列进行to_char转换;
2.EXACT:默认值,只有在SQL语句完全一致的情况下才共享游标;
3.SIMILAR:在不改变语义或者不降低性能的情况下,尽量采用游标共享,一般用于第三方的系统,无法修改源码的情况;
3.执行计划相关内容:
1.v$sql_plan:在Shared Pool中的Library Cache中保存的实际使用的执行计划;
2.查看实际的执行计划:SELECT * FROM table(DBMS_XPLAN.DISPLAY_CURSOR(‘sql_id’));
4.在CURSOR_SHARING=EXACT模式下查看使用字面值的sql语句;
4.1创建测试表;
CREATE TABLE tb_sqltuning AS SELECT * FROM dba_objects;
ALTER TABLE TB_SQLTUNING ADD CONSTRAINT PK_sqltuning_sqlid PRIMARY KEY (OBJECT_ID);
4.2清除shared pool内容;
ALTER SYSTEM FLUSH SHARED_POOL;
4.3执行测试sql;
SELECT /* SQL_TUNING_LITERAL */ * FROM tb_sqltuning WHERE object_id = 1;
SELECT /* SQL_TUNING_LITERAL */ * FROM tb_sqltuning WHERE object_id = 2;
SELECT /* SQL_TUNING_LITERAL */ * FROM tb_sqltuning WHERE object_id = 3;
SELECT /* SQL_TUNING_LITERAL */ * FROM tb_sqltuning WHERE object_id = 4;
SELECT /* SQL_TUNING_LITERAL */ * FROM tb_sqltuning WHERE object_id = 5;
SELECT /* SQL_TUNING_LITERAL */ * FROM tb_sqltuning WHERE object_id = 6;
4.4查看sql的信息;
SELECT sql_text,
sql_id,
address,
hash_value,
plan_hash_value,
is_shareable,
executions,
parse_calls,
child_address,
child_number,
force_matching_signature,
exact_matching_signature
FROM v$sql
WHERE sql_text LIKE ‘%SQL_TUNING_LITERAL%’ AND
sql_text NOT LIKE ‘%LIKE%’;
4.5结论;
每一条sql都会进行硬结析并产生不同的执行计划,它们的exact_matching_signature不同,但是force_matching_signature相同;(plan_hash_value相同更说明了,不同的sql产生的执行计划是相同的,需要优化)
5.在CURSOR_SHARING=EXACT模式下查看使用绑定变量的sql语句;
5.1清除shared pool内容;
ALTER SYSTEM FLUSH SHARED_POOL;
5.2执行测试sql;
VARIABLE id NUMBER;
EXEC :id := 1;
SELECT /* SQL_TUNING_BIND */ * FROM tb_sqltuning WHERE object_id = :id;
EXEC :id := 2;
SELECT /* SQL_TUNING_BIND */ * FROM tb_sqltuning WHERE object_id = :id;
EXEC :id := 3;
SELECT /* SQL_TUNING_BIND */ * FROM tb_sqltuning WHERE object_id = :id;
EXEC :id := 4;
SELECT /* SQL_TUNING_BIND */ * FROM tb_sqltuning WHERE object_id = :id;
EXEC :id := 5;
SELECT /* SQL_TUNING_BIND */ * FROM tb_sqltuning WHERE object_id = :id;
EXEC :id := 6;
SELECT /* SQL_TUNING_BIND */ * FROM tb_sqltuning WHERE object_id = :id;
5.3查看sql信息;
SELECT sql_text,
sql_id,
address,
hash_value,
plan_hash_value,
is_shareable,
executions,
parse_calls,
child_address,
child_number,
force_matching_signature,
exact_matching_signature
FROM v$sql
WHERE sql_text LIKE ‘%SQL_TUNING_BIND%’ AND
sql_text NOT LIKE ‘%LIKE%’;
5.4结论;
只进行一次硬结析,之后的语句使用相同的执行计划,它们的exact_matching_signature和force_matching_signature都相同;
硬结析了三次是应为11g里面SPM(Sql Plan Management)的特性,它可以自动学习并选择最优的执行计划,最大的优点是通过避免执行计划的退化,从而保证系统性能的稳定;10g的话第一次产生执行计划就固定了,很可能不是最优的执行计划;
1.第一次执行SQL的时候跟原来一样,什么也不做,只是把执行计划保存在Library Cache中;
2.第二次执行SQL的时候会产生Plan History,而且Plan Baseline为空,把这次的执行计划放到Plan Baseline中,并且固定执行计划;
3.第三次执行SQL的时候,会把产生的执行计划放入到Plan History中,但是不会进入Plan Baseline;
6.修改参数,在CURSOR_SHARING=SIMILAR模式下查看使用字面值的sql语句;
6.1修改参数;
ALTER SYSTEM SET cursor_sharing = SIMILAR
6.2清除shared pool内容;
ALTER SYSTEM FLUSH SHARED_POOL;
6.3执行测试sql;
SELECT /* SQL_TUNING_LITERAL */ * FROM tb_sqltuning WHERE object_id = 1;
SELECT /* SQL_TUNING_LITERAL */ * FROM tb_sqltuning WHERE object_id = 2;
SELECT /* SQL_TUNING_LITERAL */ * FROM tb_sqltuning WHERE object_id = 3;
SELECT /* SQL_TUNING_LITERAL */ * FROM tb_sqltuning WHERE object_id = 4;
SELECT /* SQL_TUNING_LITERAL */ * FROM tb_sqltuning WHERE object_id = 5;
SELECT /* SQL_TUNING_LITERAL */ * FROM tb_sqltuning WHERE object_id = 6;
6.4查看sql的信息;
SELECT sql_text,
sql_id,
address,
hash_value,
plan_hash_value,
is_shareable,
executions,
parse_calls,
child_address,
child_number,
force_matching_signature,
exact_matching_signature
FROM v$sql
WHERE sql_text LIKE ‘%SQL_TUNING_LITERAL%’ AND
sql_text NOT LIKE ‘%LIKE%’;
6.5结论;
跟在EXACT模式下使用绑定变量的结果一致:每一条sql都会进行硬结析并产生不同的执行计划,它们的exact_matching_signature不同,但是force_matching_signature相同;
7.How to Find Literal SQL in Shared Pool;
DECLARE
b_myadr   VARCHAR2(20);
b_myadr1  VARCHAR2(20);
qstring   VARCHAR2(100);
b_anybind NUMBER;

CURSOR my_statement IS
SELECT address FROM v$sql GROUP BY address;
CURSOR getsqlcode IS
SELECT substr(sql_text, 1, 60) FROM v$sql WHERE address = b_myadr;
CURSOR kglcur IS
SELECT kglhdadr
FROM x$kglcursor
WHERE kglhdpar = b_myadr AND
kglhdpar != kglhdadr AND
kglobt09 = 0;
CURSOR isthisliteral IS
SELECT kkscbndt FROM x$kksbv WHERE kglhdadr = b_myadr1;
BEGIN
dbms_output.enable(10000000);
OPEN my_statement;
LOOP
FETCH my_statement
INTO b_myadr;
OPEN kglcur;
FETCH kglcur
INTO b_myadr1;
IF kglcur%FOUND THEN
OPEN isthisliteral;
FETCH isthisliteral
INTO b_anybind;
IF isthisliteral%NOTFOUND THEN
OPEN getsqlcode;
FETCH getsqlcode
INTO qstring;
dbms_output.put_line(‘Literal:’ || qstring || ‘ address: ‘ || b_myadr);
CLOSE getsqlcode;
END IF;
CLOSE isthisliteral;
END IF;
CLOSE kglcur;
EXIT WHEN my_statement%NOTFOUND;
END LOOP;
CLOSE my_statement;
END;

调优实践03–使用SQL_TRACE和10046事件跟踪SQL的执行

使用SQL_TRACE和10046事件跟踪SQL的执行

  1. 当在数据库中启动SQL_TRACE或者设置10046事件之后,Oracle将会启动内核跟踪程序,持续记录会话的相关信息,并写入到相应的trace文件中;跟踪记录的内容包括SQL的解析过程,执行计划,绑定变量的使用和会话中发生的等待事件等;
  2. SQL_TRACE和10046事件介绍:
    1. SQL_TRACE:
      1. 是一个静态的初始化参数,可以设置为TRUE/FALSE,用于开启/关闭SQL TRACE工具默认为FALSE;
      2. 设置SQL_TRACE=TRUE的话可以收集信息用于性能优化(DBMS_SYSTEM包可以实现相同的功能),但是对数据库会产生严重的性能问题,生产环境一定不要打开此参数,如果一定要在全局打开,要做到以下几点:
        1. 保证25%的CPU idle;
        2. 为USER_DUMP_DEST分配足够的空间:ALTER SYSTEM SET max_dump_file_size=UNLIMITED;
        3. 条带化磁盘,减轻IO负担;
        4. 设置timed_statistics打开:ALTER SYSTEM SET timed_statistics=TRUE;
      3. 打开SQL_TRACE功能:
        1. 全局打开:ALTER SYSTEM SET SQL_TRACE=TRUE SCOPE=SPFILE;重启数据库服务,会跟踪所有进程的活动,包括用户进程和后台进程;可以通过跟踪文件的实时变化来分析各个进程之间的协作关系;
        2. Session级别打开:ALTER SESSION SET SQL_TRACE=TRUE/FALSE;通过跟踪当前进程,来发现后台数据库的递归活动,用于研究SQL执行和发现后台错误等;
        3. 如果要跟踪其它用户的进程,可以通过DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION来完成,所需要的sid和serial#参数可以通过v$session视图查看得到;
        4. 如果要针对其它用户的参数进行设置,可以通过DBMS_SYSTEM.SET_INI_PARAM_IN_SESSION过程或者DBMS_SYSTEM.SET_BOOL_PARAM_IN_SESSION过程来完成;
      4. 其它方式:EXEC DBMS_SESSION.SET_SQL_TRACE(sql_trace=>TRUE/FALSE);
    2. 10046事件:
      1. 是Oracle提供的内部事件,是对SQL_TRACE的增强;
      2. 10046分为四个级别:
        1. level 1:启用标准的sql_trace功能,等于sql_trace(包含了SQL语句,响应事件,服务时间,处理的行数,物理读和写的数目,执行计划以及其它一些额外信息);
        2. level 4:level 1加上绑定值;
        3. level 8:level 1加上等待事件;
        4. level 12:level 1 + level 4 + level 8;
      3. 设置10046事件:
        1. 全局开启:在spfile中添加events=”10046 trace name context forever, level 12″:ALTER SYSTEM SET EVENTS ‘10046 trace name context forever, level 12’;
        2. 全局关闭:ALTER SYSTEM SET EVENTS ‘10046 trace name context off’;
        3. 针对当前session的开启:ALTER SESSION SET EVENTS ‘10046 trace name context forever, level 12’;
        4. 针对当前session的关闭:ALTER SESSION SET EVENTS ‘10046 trace name context off’;
        5. 针对其它用户session的开启:使用DBMS_SYSTEM.SET_EV(si in integer, se in integer, ev in integer, le in integer, nm in varchar):EXEC DBMS_SYSTEM.SET_EV(38,25,10046,12,’HR’);
          1. si:sid;
          2. se:serial#;
          3. ev:event number;
          4. le:level;
          5. nm:username;
          6. 可以通过v$session视图查询:SELECT sid, serial#, username FROM v$session WHERE username IS NOT NULL;
        6. 针对其它用户session的关闭:EXEC DBMS_SYSTEM.SET_EV(38,25,10046,0,’HR’);
    3. 也可以使用oradebug工具或者DBMS_MONITOR包;
    4. 获取跟踪文件的脚本;
    5. 获取当前session设置的参数的脚本;
  3. 实例分析步骤:
    1. 隐式转换与索引失效:
      1. 问题描述:反应前端程序某个功能非常慢;
      2. 首先检查并跟踪数据库进程:SELECT sid, serial#, username FROM v$session WHERE username IS NOT NULL AND username <> ‘SYS’;
      3. 然后对这几个进程开启sql trace:EXEC dbms_system.set_sql_trace_in_session(sid, serial#, TRUE);等待一段时间后关闭:EXEC dbms_system.set_sql_trace_in_session(sid, serial#, FALSE);
      4. 针对产生的trace文件使用tkprof工具进行格式化,然后查看内容;
      5. 一般发生索引失效或者是隐式转换的话就会发现返回少量的数据但是却产生特别多的物理读(也有可能是汇总操作);
      6. 可以查看关键列的索引和索引列的类型:SELECT index_name, table_name, column_name FROM user_ind_columns WHERE table_name = upper(‘tb_name’);DESC tb_name;
      7. 然后可以针对发现的问题做相应的处理,比如创建索引,手动处理隐式转换等问题;
    2. 对数据库进行操作时(如drop table/user)发生错误:
      1. 问题描述:对数据库操作后发生了ORA错误;
      2. 首先在当前的会话开启一个标识符:ALTER SESSION SET TRACEFILE_IDENTIFIER='<TRACEFILE_IDENTIFIER>’;
      3. 然后打开sql trace功能:ALTER SESSION SET SQL_TRACE=TRUE;
      4. 重现错误,即再执行当前操作;
      5. 关闭sql trace功能;
      6. 然后查看trace文件,找到具体的错误并解决;
  4. 10046查看等待事件的例子;
  5. db_file_multiblock_read_count:
    1. 表示全表扫描时,ORACLE一次I/O可以读取的数据库的数据块数,Oracle的一次I/O操作不能跨extent;
    2. 最大值为((max OS I/O size)/db_block_size),一般操作系统一次I/O最大读取1M,db_block_size=8k,所以这个参数最大为128;
    3. 这个参数也会受到SSTIOMAX的参数影响,这是一个内核参数,不能被修改,同时db_file_multiblock_read_count也不能超过db_block_buffer/4;
    4. 在OLTP系统中一般设置为4-16,在DSS系统中可以根据需要设置更大的值;
    5. 增大db_file_multiblock_read_count参数会使全表扫面的成本降低,但是在CBO下,Oracle会更倾向于使用全表扫面而不是索引扫描,db_file_multiblock_read_count与执行计划选择的例子;
  6. 为什么要使用10046事件:
    1. 10046事件可以帮助我们解析SQL语句的运行状态(包括Parse/Fetch/Execute三个阶段中遇到的等待事件,消耗的物理和逻辑读,CPU时间,执行计划等等);
    2. 即10046为我们揭示了SQL语句的运行情况,对于以点入手的SQL调优是很好的辅助工具,特别是在10g之前没有ASH的情况下;但整体系统调优不是10046所擅长的,需要用到AWR;
    3. 10046还能帮助我们分析一些DDL维护命令的内部工作原理,比如RMAN,expdp/impdp等工具的缓慢问题等;
  7. 10046事件和10053事件的区别:
    1. 10053事件是最常用的Oracle优化器optimizer跟踪trace,10053可以作为我们解释优化器为什么选择某个执行计划,但并不告诉我们这个执行计划到底运行地如何;
    2. 10046并不解释optimizer优化器的工作,但它同样说明了在SQL解析parse阶段所遇到的等待事件和所消耗的CPU等资源,以及Execute执行和Fetch阶段的各项指标;
    3. 简而言之10046告诉我们SQL(执行计划)运行地如何,10053告诉我们优化器为什么为这个SQL选择某个执行计划;
  8. 10046跟踪文件的阅读;
———————————– 获取跟踪文件的脚本 ———————————–
— 1.解析阶段;
PARSING IN CURSOR #11328540 len=56 dep=0 uid=84 oct=3 lid=84 tim=1396508012619901 hv=3963517665 ad=’4464298c’ sqlid=’25vmrurq3wyr1′
SELECT COUNT(*) FROM HR.EMPLOYEES WHERE DEPARTMENT_ID=20
END OF STMT
PARSE #11328540:c=6999,e=6974,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=2271004725,tim=1396508012619893
PARSING
1.#11328540:表示游标号,非常重要,后面的PARSE,EXEC,WAIT,FETCH,STAT,CLOSE阶段都需要使用这个游标号和前面的sql关联起来;
2.这个过程之后可能会产生很多的递归sql,一般是用来查询一些数据字典的,所消耗的资源和时间都非常的少;
3.len=56:表示sql的长度;
4.dep=0:表示Recursive Depth,即sql递归的深度;如果为0表示不是递归sql,如果大于0表示递归sql;
5.uid=84:表示解析这个游标的用户的UID,如果是0表示是sys;通过dba_users/user$查看;
6.oct=3:表示Oracle Command Type,即Oracle中的命令类型,与v$sql中的command_type列对应,可以通过查询v$sqlcommand视图查看具体的定义;
7.lid=84:表示Privilege User Id,即权限用户ID;
8.tim:表示timestamp时间戳,9i之后单位是ms,用来判断trace中两个点的时间差;来自v$timer视图,一个Oracle的内部时钟;
9.hv:表示sql的hash value,10g之前没有sqlid就使用hash value来定位一个sql;
10.ad:表示sqltext的地址,来自于v$sql的address列;
11.sqlid:表示对应的sql id;
12.err:如果有错误的话,代表错误代码,可以通过oerr ora xxx;
PARSE:是sql运行的第一个阶段,解析SQL语句;
1.c:表示cpu time,即消耗cpu的时间,9i之后单位是ms;
2.e:表示elapsed time,即消耗的自然时间,9i之后单位是ms;
3.p:表示physcial read,即物理的数目;
4.cr:表示consist read,即一致性读引起的buffer get数目;
5.cu:表示current read,即当前读取引起的buffer get数目;
6.mis:表示读取library cache的miss的数目,如果=0的话表示使用软解析或者更好的方式;如果大于0表示发生了硬结析;
7.r:表示rows,即处理的行数;
8.dep:表示Recursive Depth,即sql递归的深度;如果为0表示不是递归sql,如果大于0表示递归sql;
9.og:表示optimizer_mode,对应关系为:0-游标不可见/优化器环境未合理创建;1-ALL_ROWS;2-FIRST_ROWS;3-RULE;4-CHOOSE;
EXEC:sql运行的第二个阶段,执行sql语句;
FETCH:从游标中fetch数据行;
UNMAP:当游标使用临时表时,若游标关闭则使用UNMAP释放临时表相关的资源;
— 2.执行阶段;
EXEC #11328540:c=0,e=102,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=2271004725,tim=1396508012620426
— 3.相关的等待;

WAIT #11328540: nam=’db file sequential read’ ela= 25707 file#=5 block#=243 blocks=1 obj#=76349 tim=1396508012647378
1.Nam:等待针对的事件名字,它的P1/P2/P3可以参考视图V$EVENT_NAME,也可以从V$SESSION/ASH中观察到等待事件;
2.ela:本操作的耗时,单位是ms;
3.p1,p2,p3:针对该事件的三个描述参数,见V$EVENT_NAME;
4.obj#:相关的对象id;
— 4.获取数据;

FETCH #11328540:c=4000,e=27513,p=1,cr=1,cu=0,mis=0,r=1,dep=0,og=1,plh=2271004725,tim=1396508012648208
— 5.相关的统计;
STAT #11328540 id=1 cnt=1 pid=0 pos=1 obj=0 op=’SORT AGGREGATE (cr=1 pr=1 pw=0 time=27520 us)’
STAT #11328540 id=2 cnt=2 pid=1 pos=1 obj=76349 op=’INDEX RANGE SCAN EMP_DEPARTMENT_IX (cr=1 pr=1 pw=0 time=27485 us cost=1 size=6 car
d=2)’
STAT:相关行反应解释执行计划的统计信息
1.id:执行计划的行数,从1开始;
2.cnt:该数据源的行数;
3.pid:该数据源的父ID;
4.pos:在执行计划中的位置;
5.obj:对应数据源的object id;
6.op:数据源的访问操作,例如FULL TABLE SCAN;
7.cr:代表一致性读的数量
8.pr:代表物理读的数量
9.pw:代表物理写的数量
10.time:单位为ms,本步骤的耗时间;
11.cost:本操作的优化器成本;
12.size:评估的数据源大小,单位为字节;
13.card:评估的优化器基数Cardinality;
— 6.关闭游标;

CLOSE #11328540:c=0,e=21,dep=0,type=0,tim=1396508016737280

CLOSE:关闭游标;
type:关闭游标的操作类型;
0-该游标从未被缓存且执行次数小于3次,也叫hard close;
1-该游标从未被缓存但执行次数至少3次,若在session cached cursor中有free slot,则将该游标放入session cached cursor;
2-该游标从未被缓存但执行次数至少3次,该游标置入session cached cursor的条件是讲老的缓存age out掉;
3-该游标已经在缓存里;
— 7.其它,如果有绑定变量的话;
BINDS:
1.kkscoacd:是绑定变量相关的描述符;
2.Bind#0:说明是第0个变量;
3.oacdty:data type,96是ANSI fixed char;
4.oacflg:代表绑定选项的特殊标志位;
5.size:为该内存chunk分配的内存大小;
6.mxl:绑定变量的最大长度;
7.pre:precision;
8.scl:Scale;
9.kxsbbbfp:buffer point;
10.bln:bind buffer length;
11.avl:实际的值的长度;
12.flg:代表绑定状态;
13.value:实际的绑定值;
———————————– 获取跟踪文件的脚本 ———————————–
———————————– 获取跟踪文件的脚本 ———————————–
SELECT a.VALUE || b.symbol || c.instance_name || ‘_ora_’ || d.spid || ‘.trc’ trace_file
FROM (SELECT VALUE FROM v$parameter WHERE NAME = ‘user_dump_dest’) a,
(SELECT substr(VALUE, -6, 1) symbol FROM v$parameter WHERE NAME = ‘user_dump_dest’) b,
(SELECT instance_name FROM v$instance) c,
(SELECT spid
FROM v$session s, v$process p, v$mystat m
WHERE s.paddr = p.addr AND
s.sid = m.sid AND
m.statistic# = 0) d;
11g later:SELECT VALUE FROM v$diag_info WHERE NAME = ‘Default Trace File’;

———————————– 获取跟踪文件的脚本 ———————————–
———————————– 获取当前session设置的参数的脚本 ———————————–

DECLARE
event_level NUMBER;
BEGIN
FOR event_number IN 10000 .. 10999 LOOP
sys.dbms_system.read_ev(event_number, event_level);
IF (event_level > 0) THEN
sys.dbms_output.put_line(‘Event ‘ || to_char(event_number) || ‘ is set at level ‘ || to_char(event_level));
END IF;
END LOOP;
END;

———————————– 获取当前session设置的参数的脚本 ———————————–
———————————– 10046查看等待事件的例子 ———————————–
— 1.查看系统参数;
show parameter db_block_size; — 8192;
show parameter db_file_multiblock_read_count; — 128;
SELECT tablespace_name, block_size, initial_extent / block_size, next_extent / block_size
FROM dba_tablespaces
WHERE tablespace_name IN (‘SYSTEM’, ‘TBS32B’);
SYSTEM     8192     8
TBS32B     8192     32     32
— 2.创建一个测试表;
sqlplus / as sysdba
CREATE TABLE TB10046 AS SELECT * FROM dba_objects;
SELECT file_id, block_id, blocks FROM dba_extents WHERE segment_name = ‘TB10046’;
   FILE_ID   BLOCK_ID     BLOCKS
———- ———- ———-
1      93784          8
1      93792          8
1      93800          8
1      93808          8
1      93816          8
1     104832          8
1     104840          8
1     104848          8
1     104856          8
1     104864          8
1     104872          8

FILE_ID   BLOCK_ID     BLOCKS
———- ———- ———-
1     104880          8
1     104888          8
1     104896          8
1     104904          8
1     104912          8
1     104960        128
1     105088        128
1     105216        128
1     105344        128
1     105472        128
1     105600        128

FILE_ID   BLOCK_ID     BLOCKS
———- ———- ———-
1     105728        128
1     105856        128

24 rows selected.

— 3.生成trace文件;
ALTER SESSION SET TRACEFILE_IDENTIFIER=’t1′;
ALTER SESSION SET EVENTS ‘10046 trace name context forever, level 12’;
SELECT event, total_waits FROM V$system_EVENT WHERE EVENT = ‘db file scattered read’; — 146913315
SELECT COUNT(*) FROM TB10046; — 发生全表扫描;
SELECT event, total_waits FROM V$system_EVENT WHERE EVENT = ‘db file scattered read’; — 146913412
— 4.查看trace文件,发现一次读取8个blocks,因为扫描不能跨extent,此时一个extent中是8个块;(trace中的file#,block#和blocks是与等待事件中参数一一对应的:SELECT NAME, parameter1, parameter2, parameter3 FROM v$event_name WHERE NAME = ‘db file scattered read’;)
WAIT #1: nam=’db file scattered read’ ela= 82 file#=1 block#=104961 blocks=8 obj#=95923 tim=1389859838564653
WAIT #1: nam=’db file scattered read’ ela= 66 file#=1 block#=104986 blocks=8 obj#=95923 tim=1389859838565112
WAIT #1: nam=’db file scattered read’ ela= 64 file#=1 block#=105009 blocks=8 obj#=95923 tim=1389859838565556
WAIT #1: nam=’db file scattered read’ ela= 65 file#=1 block#=105017 blocks=8 obj#=95923 tim=1389859838565951
WAIT #1: nam=’db file scattered read’ ela= 66 file#=1 block#=105059 blocks=8 obj#=95923 tim=1389859838566301
WAIT #1: nam=’db file scattered read’ ela= 77 file#=1 block#=105070 blocks=8 obj#=95923 tim=1389859838566646
WAIT #1: nam=’db file scattered read’ ela= 62 file#=1 block#=105106 blocks=8 obj#=95923 tim=1389859838567210
WAIT #1: nam=’db file scattered read’ ela= 65 file#=1 block#=105118 blocks=8 obj#=95923 tim=1389859838567565
WAIT #1: nam=’db file scattered read’ ela= 71 file#=1 block#=105163 blocks=8 obj#=95923 tim=1389859838567961
WAIT #1: nam=’db file scattered read’ ela= 65 file#=1 block#=105185 blocks=8 obj#=95923 tim=1389859838568283
WAIT #1: nam=’db file scattered read’ ela= 65 file#=1 block#=105200 blocks=8 obj#=95923 tim=1389859838568635
WAIT #1: nam=’db file scattered read’ ela= 68 file#=1 block#=105226 blocks=8 obj#=95923 tim=1389859838568997
WAIT #1: nam=’db file scattered read’ ela= 65 file#=1 block#=105236 blocks=8 obj#=95923 tim=1389859838569331
WAIT #1: nam=’db file scattered read’ ela= 67 file#=1 block#=105264 blocks=8 obj#=95923 tim=1389859838569659
WAIT #1: nam=’db file scattered read’ ela= 67 file#=1 block#=105291 blocks=8 obj#=95923 tim=1389859838569972
WAIT #1: nam=’db file scattered read’ ela= 65 file#=1 block#=105303 blocks=8 obj#=95923 tim=1389859838570278
WAIT #1: nam=’db file scattered read’ ela= 79 file#=1 block#=105325 blocks=8 obj#=95923 tim=1389859838570640
WAIT #1: nam=’db file scattered read’ ela= 63 file#=1 block#=105371 blocks=8 obj#=95923 tim=1389859838571135
WAIT #1: nam=’db file scattered read’ ela= 65 file#=1 block#=105425 blocks=8 obj#=95923 tim=1389859838571486
WAIT #1: nam=’db file scattered read’ ela= 69 file#=1 block#=105474 blocks=8 obj#=95923 tim=1389859838571855
WAIT #1: nam=’db file scattered read’ ela= 65 file#=1 block#=105516 blocks=8 obj#=95923 tim=1389859838572204
WAIT #1: nam=’db file scattered read’ ela= 64 file#=1 block#=105528 blocks=8 obj#=95923 tim=1389859838572530
WAIT #1: nam=’db file scattered read’ ela= 66 file#=1 block#=105601 blocks=8 obj#=95923 tim=1389859838572887
WAIT #1: nam=’db file scattered read’ ela= 65 file#=1 block#=105617 blocks=8 obj#=95923 tim=1389859838573215
WAIT #1: nam=’db file scattered read’ ela= 65 file#=1 block#=105644 blocks=8 obj#=95923 tim=1389859838573561
WAIT #1: nam=’db file scattered read’ ela= 64 file#=1 block#=105676 blocks=8 obj#=95923 tim=1389859838573917
WAIT #1: nam=’db file scattered read’ ela= 66 file#=1 block#=105700 blocks=8 obj#=95923 tim=1389859838574251
WAIT #1: nam=’db file scattered read’ ela= 66 file#=1 block#=105712 blocks=8 obj#=95923 tim=1389859838574650
WAIT #1: nam=’db file scattered read’ ela= 64 file#=1 block#=105759 blocks=8 obj#=95923 tim=1389859838575214
WAIT #1: nam=’db file scattered read’ ela= 66 file#=1 block#=105779 blocks=8 obj#=95923 tim=1389859838575545
WAIT #1: nam=’db file scattered read’ ela= 65 file#=1 block#=105795 blocks=8 obj#=95923 tim=1389859838575886
WAIT #1: nam=’db file scattered read’ ela= 65 file#=1 block#=105820 blocks=8 obj#=95923 tim=1389859838576234
WAIT #1: nam=’db file scattered read’ ela= 63 file#=1 block#=105828 blocks=8 obj#=95923 tim=1389859838576565
WAIT #1: nam=’db file scattered read’ ela= 65 file#=1 block#=105842 blocks=8 obj#=95923 tim=1389859838576902
WAIT #1: nam=’db file scattered read’ ela= 64 file#=1 block#=105871 blocks=8 obj#=95923 tim=1389859838577386
WAIT #1: nam=’db file scattered read’ ela= 66 file#=1 block#=105879 blocks=8 obj#=95923 tim=1389859838577723
— 5.创建一个256k大小extent的表空间,即一个extent可以存放32个块;
CREATE TABLESPACE TBS32B DATAFILE ‘/u01/app/oracle/oradata/ORCL/tbs32b.dbf’ SIZE 50M AUTOEXTEND ON MAXSIZE UNLIMITED EXTENT MANAGEMENT LOCAL UNIFORM SIZE 256K;
ALTER TABLE TB10046 MOVE TABLESPACE TBS32B;
SELECT file_id, block_id, blocks FROM dba_extents WHERE segment_name = ‘TB10046’;
   FILE_ID   BLOCK_ID     BLOCKS
———- ———- ———-
8        128         32
8        160         32
8        192         32
8        224         32
8        256         32
8        288         32
8        320         32
8        352         32
8        384         32
8        416         32
8        448         32

FILE_ID   BLOCK_ID     BLOCKS
———- ———- ———-
8        480         32
8        512         32
8        544         32
8        576         32
8        608         32
8        640         32
8        672         32
8        704         32
8        736         32
8        768         32
8        800         32

FILE_ID   BLOCK_ID     BLOCKS
———- ———- ———-
8        832         32
8        864         32
8        896         32
8        928         32
8        960         32
8        992         32
8       1024         32
8       1056         32
8       1088         32
8       1120         32
8       1152         32

FILE_ID   BLOCK_ID     BLOCKS
———- ———- ———-
8       1184         32
8       1216         32

35 rows selected.

ALTER SYSTEM FLUSH BUFFER_CACHE;
ALTER SESSION SET TRACEFILE_IDENTIFIER=’t2′;
ALTER SESSION SET EVENTS ‘10046 trace name context forever, level 12’;
SELECT COUNT(*) FROM TB10046; — 发生全表扫描;
— 6.查看trace文件,发现一次读取32个blocks;
WAIT #1: nam=’db file scattered read’ ela= 114 file#=8 block#=132 blocks=28 obj#=95923 tim=1389860294615193
WAIT #1: nam=’db file scattered read’ ela= 118 file#=8 block#=162 blocks=30 obj#=95923 tim=1389860294616423
WAIT #1: nam=’db file scattered read’ ela= 109 file#=8 block#=194 blocks=30 obj#=95923 tim=1389860294617528
WAIT #1: nam=’db file scattered read’ ela= 111 file#=8 block#=225 blocks=31 obj#=95923 tim=1389860294618635
WAIT #1: nam=’db file scattered read’ ela= 117 file#=8 block#=256 blocks=32 obj#=95923 tim=1389860294619776
WAIT #1: nam=’db file scattered read’ ela= 133 file#=8 block#=289 blocks=31 obj#=95923 tim=1389860294620942
WAIT #1: nam=’db file scattered read’ ela= 142 file#=8 block#=320 blocks=32 obj#=95923 tim=1389860294622095
WAIT #1: nam=’db file scattered read’ ela= 115 file#=8 block#=353 blocks=31 obj#=95923 tim=1389860294623268
WAIT #1: nam=’db file scattered read’ ela= 117 file#=8 block#=384 blocks=32 obj#=95923 tim=1389860294624399
WAIT #1: nam=’db file scattered read’ ela= 113 file#=8 block#=417 blocks=31 obj#=95923 tim=1389860294625493
WAIT #1: nam=’db file scattered read’ ela= 114 file#=8 block#=448 blocks=32 obj#=95923 tim=1389860294626569
WAIT #1: nam=’db file scattered read’ ela= 112 file#=8 block#=481 blocks=31 obj#=95923 tim=1389860294627654
WAIT #1: nam=’db file scattered read’ ela= 117 file#=8 block#=512 blocks=32 obj#=95923 tim=1389860294628730
WAIT #1: nam=’db file scattered read’ ela= 113 file#=8 block#=545 blocks=31 obj#=95923 tim=1389860294629788
WAIT #1: nam=’db file scattered read’ ela= 139 file#=8 block#=576 blocks=32 obj#=95923 tim=1389860294631207
WAIT #1: nam=’db file scattered read’ ela= 123 file#=8 block#=609 blocks=31 obj#=95923 tim=1389860294632340
WAIT #1: nam=’db file scattered read’ ela= 191 file#=8 block#=640 blocks=32 obj#=95923 tim=1389860294633470
WAIT #1: nam=’db file scattered read’ ela= 193 file#=8 block#=673 blocks=31 obj#=95923 tim=1389860294634671
WAIT #1: nam=’db file scattered read’ ela= 131 file#=8 block#=704 blocks=32 obj#=95923 tim=1389860294635781
WAIT #1: nam=’db file scattered read’ ela= 119 file#=8 block#=737 blocks=31 obj#=95923 tim=1389860294636852
WAIT #1: nam=’db file scattered read’ ela= 125 file#=8 block#=768 blocks=32 obj#=95923 tim=1389860294637924
WAIT #1: nam=’db file scattered read’ ela= 126 file#=8 block#=801 blocks=31 obj#=95923 tim=1389860294638974
WAIT #1: nam=’db file scattered read’ ela= 119 file#=8 block#=832 blocks=32 obj#=95923 tim=1389860294640007
WAIT #1: nam=’db file scattered read’ ela= 123 file#=8 block#=865 blocks=31 obj#=95923 tim=1389860294641040
WAIT #1: nam=’db file scattered read’ ela= 116 file#=8 block#=896 blocks=32 obj#=95923 tim=1389860294642112
WAIT #1: nam=’db file scattered read’ ela= 114 file#=8 block#=929 blocks=31 obj#=95923 tim=1389860294643170
WAIT #1: nam=’db file scattered read’ ela= 135 file#=8 block#=960 blocks=32 obj#=95923 tim=1389860294644287
WAIT #1: nam=’db file scattered read’ ela= 183 file#=8 block#=993 blocks=31 obj#=95923 tim=1389860294645459
WAIT #1: nam=’db file scattered read’ ela= 131 file#=8 block#=1024 blocks=32 obj#=95923 tim=1389860294646588
WAIT #1: nam=’db file scattered read’ ela= 116 file#=8 block#=1057 blocks=31 obj#=95923 tim=1389860294647669
WAIT #1: nam=’db file scattered read’ ela= 116 file#=8 block#=1088 blocks=32 obj#=95923 tim=1389860294648735
WAIT #1: nam=’db file scattered read’ ela= 114 file#=8 block#=1121 blocks=31 obj#=95923 tim=1389860294649806
WAIT #1: nam=’db file scattered read’ ela= 119 file#=8 block#=1152 blocks=32 obj#=95923 tim=1389860294650864
WAIT #1: nam=’db file scattered read’ ela= 113 file#=8 block#=1185 blocks=31 obj#=95923 tim=1389860294651919
———————————– 10046查看等待事件的例子 ———————————–
———————————– db_file_multiblock_read_count与执行计划选择的例子 ———————————–
— 1.准备工作;
SELECT owner, count(*) FROM TB10046 GROUP BY owner ORDER BY 2;

OWNER                            COUNT(*)
—————————— ———-
OWBSYS                                  2
APPQOSSYS                               3
SCOTT                                   6
ORACLE_OCM                              8
SI_INFORMTN_SCHEMA                      8
BI                                      8
OUTLN                                   9
ORDPLUGINS                             10
OWBSYS_AUDIT                           12
FLOWS_FILES                            12
PM                                     27

OWNER                            COUNT(*)
—————————— ———-
HR                                     34
IX                                     55
DBSNMP                                 65
OE                                    127
ORDDATA                               248
SH                                    306
EXFSYS                                310
WMSYS                                 316
CTXSYS                                366
SYSTEM                                529
OLAPSYS                               719

OWNER                            COUNT(*)
—————————— ———-
XDB                                   844
MDSYS                                1509
PV                                   2161
APEX_030200                          2406
ORDSYS                               2532
SYSMAN                               3491
PUBLIC                              27702
SYS                                 31132

30 rows selected.

CREATE INDEX IDX_TB10046_HR ON TB10046(owner);

EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, ‘TB10046’, cascade=>TRUE);
— 2.设置db_file_multiblock_read_count参数为8,查看表的执行计划;
ALTER SYSTEM SET db_file_multiblock_read_count=8;
SET AUTOT TRACE EXP;
SQL> SELECT * FROM tb10046 WHERE OWNER=’SYSMAN’;
Execution Plan
———————————————————-
Plan hash value: 3379381082

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

| Id  | Operation                   | Name           | Rows  | Bytes | Cost (%CP
U)| Time     |

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

|   0 | SELECT STATEMENT            |                |  3268 |   315K|    95   (
0)| 00:00:02 |

|   1 |  TABLE ACCESS BY INDEX ROWID| TB10046        |  3268 |   315K|    95   (
0)| 00:00:02 |

|*  2 |   INDEX RANGE SCAN          | IDX_TB10046_HR |  3268 |       |     8   (
0)| 00:00:01 |

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

Predicate Information (identified by operation id):
—————————————————

2 – access(“OWNER”=’SYSMAN’)

— 3.设置db_file_multiblock_read_count参数为128,查看表的执行计划;
ALTER SYSTEM SET db_file_multiblock_read_count=;128
SQL> SELECT * FROM tb10046 WHERE OWNER=’SYSMAN’;
Execution Plan
———————————————————-
Plan hash value: 3237706262

—————————————————————————–
| Id  | Operation         | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
—————————————————————————–
|   0 | SELECT STATEMENT  |         | 3268  |   315K|    99   (1)| 00:00:03 |

|*  1 |  TABLE ACCESS FULL| TB10046 | 3268  |   315K|    99   (1)| 00:00:03 |
—————————————————————————–

Predicate Information (identified by operation id):
—————————————————

1 – filter(“OWNER”=’SYSMAN’)

———————————– db_file_multiblock_read_count与执行计划选择的例子 ———————————–

性能调优工具02–Sql Access Advisor工具的使用

SAA(Sql Access Advisor)工具的使用

  1. SAA可以做什么:
    1. 在给定的负载上推荐一些物化视图,物化视图日志和索引;
    2. 推荐的索引包括Bitmap索引,基于函数的索引和B-Tree索引;
    3. 推荐如何创建物化视图,以至于可以实现快速刷新和查询重写;
  2. SAA的使用模型:
    1. SQL的来源:
      1. SQL Cache:即当前v$sql视图中记录的sql语句;
      2. User-defined:自定义一个表,记录执行的sql语句和执行sql语句的用户,然后把这个表传给SAA;
      3. STS:使用Sql Tuning Set,主要是从负载中获得;
    2. 给出的建议:
      1. Simultaneously considers index solutions, materialized view solutions, or combinations of both;
      2. Considers storage for creation and maintenance costs;
      3. Does not generate drop recommendations for partial workloads;
      4. Optimizes materialized views for maximum query rewrite usage and fast refresh;
      5. Recommends materialized view logs for fast refresh;
      6. Combines similar indexes into a single index;
      7. Generates recommendations that support multiple workload queries;
    3. 架构图;                                                                                          
    4. 推荐的两种方式:Comprehensive和Limited;
      1. Add new index on table or materialized view;
      2. Drop an unused index;
      3. Modify an existing index by changing the index type;
      4. Modify an existing index by adding columns at the end;
      5. Add a new materialized view;
      6. Drop an unused materialized view;
      7. Add a new materialized view log;
      8. Modify an existing materialized view log to add new columns or clauses;
      9. Comprehensive可以分析1-8所有的推荐;
      10. Limited只能分析1,4,5,7,8推荐;
  3. 使用SAA需要的权限:
    1. ADVISOR的系统权限;
    2. 目标表的SELECT权限,而且这个权限不能从一个角色中获得;
  4. 使用SAA工具:
    1. 执行负载;
    2. 使用EM中图形化界面;
    3. 使用脚本调用DMBS_ADVISOR包;
  5. 使用DMBS_ADVISOR包:
    1. 步骤:
      1. 创建一个任务,并定义参数;
      2. 定义负载;
      3. 生成一些建议;
      4. 查看并应用建议;
    2. SAA的工作流;
    3. 创建一个任务:DBMS_ADVISOR.CREATE_TASK(DBMS_ADVISOR.SQLACCESS_ADVISOR, :task_id, :task_name);
    4. 设置SAA的参数:
      1. 设置任务的参数:DBMS_ADVISOR.SET_TASK_PARAMETER(:task_name, parameter, value);
      2. 设置负载的参数:DBMS_ADVISOR.SET_SQLWKLD_PARAMETER(:workload_name, parameter, value);
    5. 创建模板:DBMS_ADVISOR.CREATE_TASK(DBMS_ADVISOR.SQLACCESS_ADVISOR, :task_id, :task_name, template=>:template_name, is_template=>’TRUE’);
    6. 创建一个负载:DBMS_ADVISOR.CREATE_SQLWKLD(:workload_name);
      1. SQL Tuning Sets:DBMS_ADVISOR.IMPORT_SQLWKLD_STS();
      2. 用户自定义负载:DBMS_ADVISOR.IMPORT_SQLWKLD_USER();
      3. SQL Cache:DBMS_ADVISOR.IMPORT_SQLWKLD_SQLCACHE();
      4. 单条的SQL语句:DBMS_ADVISOR.ADD_SQLWKLD_STATEMENT();
      5. 某个用户下的SQL语句:DBMS_ADVISOR.IMPORT_SQLWKLD_SCHEMA();
    7. 删除负载:DBMS_ADVISOR.DELETE_SQLWKLD(:workload_name);
    8. 任务与负载关联:DBMS_ADVISOR.ADD_SQLWKLD_REF(:task_name, :workload_name);
    9. 生成建议并把建议保存在SAA的资源库:DBMS_ADVISOR.EXECUTE_TASK(:task_name);
      1. 相应的视图为:dba/user_advisor_recommendations;
      2. 或者使用dbms_advisor.get_task_script生成相应的脚本;
    10. SAA的主要建议有:
      1. 创建/删除物化视图;
      2. 创建/删除物化视图日志;
      3. 创建/删除索引;
      4. 收集统计信息;
    11. 生成SQL脚本:
      1. 创建DIRECTORY;
      2. 授权给用户;
      3. 生成脚本;
  6. 如果只是想调优一条SQL语句的话,可以执行快速调优,使用DBMS_ADVISOR.QUICK_TUNE()过程;
  7. 对于物化视图的优化:
    1. DBMS_MVIEW.EXPLAIN_MVIEW:查看使用/不使用物化视图的原因;
    2. DBMS_MVIEW.EXPLAIN_REWRITE:为没有么有使用查询重写,如果使用了,使用的哪个物化视图;
    3. DBMS_ADVISOR.TUNE_MVIEW:生成快速刷新物化视图和生成查询重写的建议;
——————————– 使用SAA工具 ——————————–
— 1.执行负载;
CONNECT / AS SYSDBA;
ALTER USER sh IDENTIFIED BY oracle ACCOUNT UNLOCK;
GRANT DBA TO sh;
ALTER SYSTEM FLUSH shared_pool;
ALTER SYSTEM FLUSH buffer_cache;
CONNECT sh/oracle;
SET autotrace traceonly stat;

SELECT c.cust_last_name, SUM(s.amount_sold) AS dollars, SUM(s.quantity_sold) AS quantity
FROM sales s, customers c, products p
WHERE c.cust_id = s.cust_id AND
s.prod_id = p.prod_id AND
c.cust_state_province IN (‘Dublin’, ‘Galway’)
GROUP BY c.cust_last_name;

SELECT c.cust_id, SUM(amount_sold) AS dollar_sales
FROM sales s, customers c
WHERE s.cust_id = c.cust_id
GROUP BY c.cust_id;

SELECT SUM(unit_cost) FROM costs GROUP BY prod_id;
SELECT * FROM customers WHERE cust_postal_code = ‘83786’;

— 2.使用EM中的SAA工具;
1.Databaes Instance->Advisor Central->SQL Access Advisor;
2.选择SQL语句的来源:选择从内存中的SQL语句;
3.选择推荐的选项:生成索引和物化视图,并使用综合模式;
4.系统创建了一个作业,指定立即执行;
5.查看作业已完成;
6.然后查看和采用相应的建议;
— 3.使用脚本调用DBMS_ADVISOR包;
1.定义变量;
VARIABLE v_task_id NUMBER;
VARIABLE v_task_name VARCHAR2(255);
VARIABLE v_wkld_name VARCHAR2(255);
2.指定任务的名称和负载的名称;
EXECUTE :v_task_name := ‘my_task’;
EXECUTE :v_wkld_name := ‘my_sql_wkld’;
3.删除之前的任务和负载;
BEGIN
dbms_advisor.delete_sqlwkld_ref(:v_task_name, :v_wkld_name);
dbms_advisor.delete_sqlwkld(:v_wkld_name);
dbms_advisor.delete_task(:v_task_name);
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
/
4.创建一个任务;
EXECUTE DBMS_ADVISOR.CREATE_TASK(DBMS_ADVISOR.SQLACCESS_ADVISOR, :v_task_id, :v_task_name);

5.查看当天前的优化任务;
SELECT * FROM user_advisor_tasks;

6.设置任务的参数,生成所有建议,并使用综合模式;
EXECUTE dbms_advisor.set_task_parameter(:v_task_name, ‘EXECUTION_TYPE’, ‘FULL’);
EXECUTE dbms_advisor.set_task_parameter(:v_task_name, ‘MODE’, ‘COMPREHENSIVE’);

7.创建一个负载;
EXECUTE dbms_advisor.create_sqlwkld(:v_wkld_name);
8.把任务与负载关联;
EXECUTE dbms_advisor.add_sqlwkld_ref(:v_task_name, :v_wkld_name);

9.查看任务与负载的映射关系;
SELECT * FROM user_advisor_sqla_wk_map;

10.导入负载,使用SQL Cache的模式;
VARIABLE v_saved_stmts NUMBER;
VARIABLE v_failed_stmts NUMBER;
EXECUTE DBMS_ADVISOR.IMPORT_SQLWKLD_SQLCACHE(:v_wkld_name, ‘APPEND’, 2, :v_saved_stmts, :v_failed_stmts);

11.查看负载中的SQL语句;
SELECT * FROM user_advisor_sqlw_stmts;
12.执行任务,生成优化建议;
EXECUTE DBMS_ADVISOR.EXECUTE_TASK(:v_task_name);
13.查看优化建议;
SELECT * FROM user_advisor_recommendations;
14.生成优化建议的脚本;
直接查看:SELECT DBMS_ADVISOR.GET_TASK_SCRIPT(:v_task_name) FROM dual;
或者创建目录,生成建议的脚本;
CONNECT / AS SYSDBA;
DROP DIRECTORY ADVISOR_RESULTS;
CREATE OR REPLACE DIRECTORY ADVISOR_RESULTS AS ‘/home/oracle’;
GRANT READ, WRITE ON DIRECTORY ADVISOR_RESULTS TO sh;
CONNECT SH/ORACLE
EXECUTE DBMS_ADVISOR.CREATE_FILE(DBMS_ADVISOR.GET_TASK_SCRIPT(:v_task_name), ‘ADVISOR_RESULTS’, ‘advscript.sql’);
——————————– 使用SAA工具 ——————————–
——————————– SAA的快速调优 ——————————–
1.定义变量;
CONNECT sh/oracle;
VARIABLE v_task_name VARCHAR2(30);
EXECUTE :v_task_name := ‘quick_task’;
2.执行快速调优,只能执行一条SQL语句,默认是在当前用户下执行;
EXECUTE dbms_advisor.quick_tune(dbms_advisor.sqlaccess_advisor, :v_task_name, ‘SELECT AVG(amount_sold) FROM sh.sales WHERE promo_id=10’);
3.查看优化建议结果;
SELECT DBMS_ADVISOR.GET_TASK_SCRIPT(:v_task_name) FROM dual;
——————————– SAA的快速调优 ——————————–

性能调优工具01–Sql Tuning Advisor工具的使用

STA(Sql Tuning Advisor)工具的使用

  1. STA工具其实就是DBMS_SQLTUNE包,要使用STA的话,必须是在CBO模式下使用;
  2. 执行DBMS_SQLTUNE包,需要有advisor角色权限;
  3. DBMS_SQLTUNE包介绍:
    1. DBMS_SQLTUNE.CREATE_TUNING_TASK(sql_text, bind_list, user_name, scope, time_limit, task_name, DESCRIPTION) RETURN VARCHAR2;
      1. sql_text:需要优化的sql语句;
      2. bind_list:绑定的变量列表,默认为NULL;
      3. user_name:要优化的sql语句通过哪个用户执行,默认为NULL;
      4. scope:优化范围,有两个取值,limited-分析时不使用推荐的SQL Profile,大约每个语句1s时间;comprehensive-分析时使用推荐的SQL Profile,可能花费的时间较长,默认值;
      5. time_limit:优化过程的时间限制,默认为TIME_LIMIT_DEFAULT;
      6. task_name:优化任务的名称,默认为NULL;
      7. decription:描述信息,默认为NULL;
    2. DBMS_SQLTUNE.EXECUTE_TUNING_TASK(task_name);
      1. task_name:要执行的优化任务的名称;
    3. DBMS_SQLTUNE.REPORT_TUNING_TASK(task_name, type, level, section, object_id, result_limit);
      1. task_name:要查看的优化任务的名称;
      2. type:优化报告的类型,TEXT,HTML或者XML,默认是TEXT;
      3. level:格式化的级别,TYPICAL, BASIC, ALL.默认是TYPICAL;
      4. section:优化报告的部分,FINDING,PLAN,INFORMATION,ERROR或者ALL,默认是ALL;
      5. 调用方法:SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK(‘task_name’) from dual;
    4. DBMS_SQLTUNE.DROP_TUNING_TASK(task_name);
      1. task_name:要删除的优化任务的名称;
    5. DBMS_SQLTUNE.RESET_TUNING_TASK(task_name):重置优化任务的结果;
      1. task_name:优化任务的名称;
      2. 执行过之后就可以重新执行EXECUTE_TUNING_TASK过程了;
  4. 一般的步骤:
    1. 创建优化任务;
    2. 执行优化任务;
    3. 显示优化结果;
    4. 根据建议来做相应的优化;
    5. 删除优化任务;
  5. 创建测试用户:SQLTUNE;                                                            
  6. 创建测试表;                                                                     
  7. 执行查询语句:SELECT COUNT(*) FROM bigtable a, smalltable b WHERE a.object_name = b.object_name;
    1. 需要的时间;                                                          
    2. 执行计划;                                                         
    3. 统计信息;                                                          
  8. 创建优化任务;                                                            
  9. 执行优化任务,并查看优化任务的执行进度;                                          
  10. 查询优化结果;
    1. 关于这次优化任务的基本信息:如任务名称,执行时间,范围,涉及到的语句,发现问题的类型及个数的信息等等;      
    2. 发现的问题:两个表没有收集统计信息;                                               
    3. 发现的问题:两个表没有索引;                                                    
    4. 按照优化建议修改前后的执行计划的对比;                                             
  11. 按照建议做相应的修改,然后执行语句验证优化的结果;                                 
  12. 删除优化任务:                                                           
  13. 如果需要对多条语句进行优化时,应该使用STS(Sql Tuning Set);
    1. STS可以从多种数据源(Cursor Cache, AWR, STS)获取SQL;
    2. 创建一个STS:DBMS_SQLTUNE.CREATE_SQLSET(sqlset_name => ‘sts_test’);
    3. 使用Cursor Cache加载STS:DBMS_SQLTUNE.LOAD_SQLSET();
    4. 查看STS的内容:SELECT * FROM TABLE(DBMS_SQLTUNE.SELECT_SQLSET(‘sts_test’));
    5. 使用STS创建一个优化任务:DBMS_SQLTUNE.CREATE_TUNING_TASK(sqlset_name=>’sts_test’, task_name=>’sta_test’);
  14. 使用EM,在EM->Performance->Advisor Central->SQL Advisors->SQL Tuning Advisor;                      
  15. 单条sql的调优可以使用sqltrpt.sql(执行SQL>@?/rdbms/admin/sqltrpt.sql sqlid即可)脚本传入sqlid即可;对于多条sql语句可以使用dbmssqlt.sql脚本,这个脚本给出了dbms_sqltune包的定义和相关的例子;
— 创建测试用户SQLTUNE;
CREATE USER SQLTUNE IDENTIFIED BY “oracle”;
GRANT CONNECT, RESOURCE, ADVISOR TO SQLTUNE;
CONN SQLTUNE/ORACLE;
— 创建测试表;
CREATE TABLE bigtable AS SELECT rownum id, t.* FROM sys.all_objects t;
CREATE TABLE smalltable AS SELECT rownum id, t.* FROM sys.all_objects t;
INSERT INTO bigtable SELECT * FROM bigtable;
INSERT INTO bigtable SELECT * FROM bigtable;
INSERT INTO bigtable SELECT * FROM bigtable;
COMMIT;
— 创建优化任务;
DECLARE
my_task_name VARCHAR2(30);
my_sqltext   CLOB;
BEGIN
my_sqltext := ‘SELECT COUNT(*) FROM bigtable a, smalltable b WHERE a.object_name = b.object_name’;
my_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(sql_text => my_sqltext, user_name => ‘SQLTUNE’, task_name => ‘sta_test’);
END;
—  执行优化任务;
EXEC DBMS_SQLTUNE.EXECUTE_TUNING_TASK(‘sta_test’);
SELECT task_name,status FROM USER_ADVISOR_TASKS WHERE task_name =’sta_test’;
— 查看优化结果;
SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK(‘sta_test’) from dual;
— 执行优化建议;
CREATE INDEX IDX_BIGTABLE_OBJECTNAME ON BIGTABLE(‘OBJECT_NAME’);
CREATE INDEX IDX_SMALLTABLE_OBJECTNAME ON SMALLTABLE(‘OBJECT_NAME’);
EXEC dbms_stats.gather_table_stats(USER, ‘BIGTABLE’, CASCADE=>TRUE);
EXEC dbms_stats.gather_table_stats(USER, ‘SMALLTABLE’, CASCADE=>TRUE);
— 删除优化任务;
EXEC DBMS_SQLTUNE.DROP_TUNING_TASK(‘sta_test’);
— 创建SQL Tuning Set创建优化任务;
— create a STS
BEGIN
dbms_sqltune.create_sqlset(sqlset_name => ‘my_sts’);
END;
/

— load STS using cursor cache
DECLARE
l_cur dbms_sqltune.sqlset_cursor;
BEGIN
OPEN l_cur FOR
SELECT VALUE(t)
FROM TABLE(dbms_sqltune.select_cursor_cache(‘sql_id in (”588rxmp05xt7g”,”7rucbfq8vcr7d”)’)) t;

dbms_sqltune.load_sqlset(sqlset_name => ‘sts_test’, populate_cursor => l_cur);
END;
/

— display contents of STS
SELECT * FROM TABLE(dbms_sqltune.select_sqlset(‘sts_test’));

— drop a sql tuning task
BEGIN
dbms_sqltune.drop_tuning_task(task_name => ‘my_sql_tuning_task’);
END;
/

— create a sql tuning task by using STS
DECLARE
l_task_name VARCHAR2(30);
l_sqltext CLOB;
BEGIN
l_task_name := dbms_sqltune.create_tuning_task(sqlset_name => ‘sts_test’, task_name => ‘my_sql_tuning_task’);

END;
/

调优实践02–ALTER SYSTEM/SESSION SET EVENTS转储

ALTER SYSTEM/SESSION SET EVENTS
  1. 语法:alter system|session set events ‘[eventnumber|immediate] trace name eventname [forever] [, level levelnumber] : ……’; 通过[:]符号,可以连续设置多个事件,也可以通过连续使用alter session set events来设置多个事件;
  2. 参数说明:
    1. eventnumber:指触发dump的事件号,事件号可以是Oracle错误号(出现相应错误时跟踪指定的事件)或oralce内部事件号(内部事件号在10000到10999之间),不能与immediate关键字同用;
    2. immediate:关键字表示命令发出后,立即将指定的结构dump到跟踪文件中,这个关键字只用在alter session语句中,并且不能与eventnumber/forever关键字同用;
    3. eventname:指事件名称,即要进行dump的实际结构名;若eventname为context,则指根据内部事件号进行跟踪;
    4. forever:关键字表示事件在实例或会话的周期内保持有效状态,不能与immediate同用;
    5. level:为事件级别关键字,但在dump错误栈(errorstack)时不存在级别;
    6. levelnumber:表示事件级别号,一般从1到10,1表示只dump结构头部信息,10表示dump结构的所有信息;
  3. 常用的事件名称和级别:
    1. Memory Dumps:
      1. Global Area:ALTER SESSION SET EVENTS ‘immediate trace name global_area level n’;
        1. 1 包含PGA
        2. 2 包含SGA
        3. 4 包含UGA
        4. 8 包含indrect memory
      2. Library Cache:ALTER SESSION SET EVENTS ‘immediate trace name library_cache level n’;
        1. 1 library cache统计信息
        2. 2 包含hash table histogram
        3. 3 包含object handle
        4. 4 包含object结构
      3. Row Cache:ALTER SESSION SET EVENTS ‘immediate trace name row_cache level n’;
        1. 1 row cache统计信息
        2. 2 包含hash table histogram
        3. 8 包含object结构
      4. Buffers:ALTER SESSION SET EVENTS ‘immediate trace name buffers level n’;
        1. 1 buffer header
        2. 2 level 1 + block header
        3. 3 level 2 + block contents
        4. 4 level 1 + hash chain
        5. 5 level 2 + hash chain
        6. 6 level 3 + hash chain
        7. 8 level 4 + users/waiters
        8. 9 level 5 + users/waiters
        9. 10 level 6 + users/waiters
      5. Buffer:ALTER SESSION SET EVENTS ‘immediate trace name buffer level n’;
        1. n为某个指定block的rdba,该命令可以转储某个block在buffer中的所有版本;
      6. Heap:ALTER SESSION SET EVENTS ‘immediate trace name heapdump level n’;
        1. 1 PGA摘要
        2. 2 SGA摘要
        3. 4 UGA摘要
        4. 8 Current call(CGA)摘要
        5. 16 User call(CGA)摘要
        6. 32 Large call(LGA)摘要
        7. 1025 PGA内容
        8. 2050 SGA内容
        9. 4100 UGA内容
        10. 8200 Current call内容
        11. 16400 User call内容
        12. 32800 Large call内容
      7. Sub Heap:
        1. ALTER SESSION SET EVENTS ‘immediate trace name heapdump_addr level n’;(oracle 9.0.1版本之前)
          1. 若n为subheap的地址,转储的是subheap的摘要信息
          2. 若n为subheap的地址+1,转储的则是subheap的内容
        2. ALTER SESSION SET EVENTS ‘immediate trace name heapdump_addr level n, addr m’;(oracle 9.2.0版本之后)
          1. 其中m为subheap的地址
          2. n为1转储subheap的摘要,n为2转储subheap的内容
      8. Process State:ALTER SESSION SET EVENTS ‘immediate trace name processstate level n’;
      9. System State:ALTER SESSION SET EVENTS ‘immediate trace name systemstate level n’;
      10. Error State:ALTER SESSION SET EVENTS ‘immediate trace name errorstack level n’;
        1. 0 Error stack
        2. 1 level 0 + function call stack
        3. 2 level 1 + process state
        4. 3 level 2 + context area
      11. Hang Analysis:ALTER SESSION SET EVENTS ‘immediate trace name hanganalyze level n’;
      12. Work Area:ALTER SESSION SET EVENTS ‘immediate trace name workareatab_dump level n’;
        1. 1 SGA信息
        2. 2 Workarea Table摘要信息
        3. 3 Workarea Table详细信息
      13. Latches:ALTER SESSION SET EVENTS ‘immediate trace name latches level n’;
        1. 1 latch信息
        2. 2 统计信息
      14. Events:ALTER SESSION SET EVENTS ‘immediate trace name events level n’;
        1. 1 session
        2. 2 process
        3. 3 system
      15. Locks:ALTER SESSION SET EVENTS ‘immediate trace name locks level n’;
      16. Shared Server Process:ALTER SESSION SET EVENTS ‘immediate trace name shared_server_state level n’;
        1. n取值为1~14
      17. Background Messages:ALTER SESSION SET EVENTS ‘immediate trace name bg_messages level n’;
        1. n为pid+1
    2. File Dumps:
      1. Block:
        1. ALTER SESSION SET EVENTS ‘immediate trace name blockdump level n’;(oracle 7之前)
          1. n为block的rdba
        2. ALTER SYSTEM DUMP DATAFILE file# BLOCK block#;(oracle8以后)
        3. ALTER SYSTEM DUMP DATAFILE file# BLOCK MIN minimum_block# BLOCK MAX maximum_block#;
      2. Tree Dump:ALTER SESSION SET EVENTS ‘immediate trace name treedump level n’;
        1. n为object_id
      3. Undo Segment Header:ALTER SYSTEM DUMP UNDO_HEADER ‘segment_name’;
      4. Undo for a Transaction:ALTER SYSTEM DUMP UNDO BLOCK ‘segment_name’ XID xidusn xidslot xidsqn;
      5. File Header:ALTER SESSION SET EVENTS ‘immediate trace name file_hdrs level n’;
        1. 1 控制文件中的文件头信息
        2. 2 level 1 + 文件头信息
        3. 3 level 2 + 数据文件头信息
        4. 10 level 3
      6. Control file:ALTER SESSION SET EVENTS ‘immediate trace name controlf level n’;
        1. 1 文件头信息
        2. 2 level 1 + 数据库信息 + 检查点信息
        3. 3 level 2 + 可重用节信息
        4. 10 level 3
      7. Redo log Header:ALTER SESSION SET EVENTS ‘immediate trace name redohdr level n’;
        1. 1 控制文件中的redo log信息
        2. 2 level 1 + 文件头信息
        3. 3 level 2 + 日志文件头信息
        4. 10 level 3
      8. Redo log
        1. ALTER SYSTEM DUMP LOGFILE ‘FileName’;
        2. ALTER SYSTEM DUMP LOGFILE ‘FileName’
          1. SCN MIN MinimumSCN
          2. SCN MAX MaximumSCN
          3. TIME MIN MinimumTime
          4. TIME MAX MaximumTime
          5. LAYER Layer
          6. OPCODE Opcode
          7. DBA MIN FileNumber . BlockNumber
          8. DBA MAX FileNumber . BlockNumber
          9. RBA MIN LogFileSequenceNumber . BlockNumber
          10. RBA MAX LogFileSequenceNumber . BlockNumber;
        3. 其中time = (((((yyyy – 1988)) * 12 + mm – 1) * 31 + dd – 1) * 24 + hh) * 60 + mi) * 60 + ss;
      9. Loghist:ALTER SESSION SET EVENTS ‘immediate trace name loghist level n’;
        1. 1 dump控制文件中最早和最迟的日志历史项
        2. >1 dump 2^n个日志历史项
  4. 事件编号和对应的描述;
  5. 获得对应trace文件的脚本;
  6. 例子:
    1. alter session set events ‘10046 trace name context forever,level 12’;
    2. alter session set events ‘immediate trace name controlf level 12’;
———————————- 获得对应trace文件的脚本 ———————————-
SELECT a.VALUE || b.symbol || c.instance_name || ‘_ora_’ || d.spid || ‘.trc’ trace_file
FROM (SELECT VALUE FROM v$parameter WHERE NAME = ‘user_dump_dest’) a,
(SELECT substr(VALUE, -6, 1) symbol FROM v$parameter WHERE NAME = ‘user_dump_dest’) b,
(SELECT instance_name FROM v$instance) c,
(SELECT spid
FROM v$session s, v$process p, v$mystat m
WHERE s.paddr = p.addr AND
s.sid = m.sid AND
m.statistic# = 0) d;
———————————- 获得对应trace文件的脚本 ———————————-
———————————- 事件编号和对应的描述 ———————————-
10000 Controlfile debug event, name ‘control_file’
10001 Controlfile crash event1
10002 Controlfile crash event2
10003 Controlfile crash event3
10004 Controlfile crash event4
10005 Trace latch operations for debugging
10006 Testing – block recovery forced
10007 Log switch debug crash after new log select, thread %s
10008 Log switch debug crash after new log header write, thread %s
10009 Log switch debug crash after old log header write, thread %s
10010 Begin Transaction
10011 End Transaction
10012 Abort Transaction
10013 Instance Recovery
10014 Roll Back to Save Point
10015 Undo Segment Recovery
10016 Undo Segment extend
10017 Undo Segment Wrap
10018 Data Segment Create
10019 Data Segment Recovery
10020 Partial link restored to linked list (KSG)
10021 Latch cleanup for state objects (KSS)
10022 Trace ktsgsp
10023 Create Save Undo Segment
10024 Write to Save Undo
10025 Extend Save Undo Segment
10026 Apply Save Undo
10027 Latch cleanup for enqueue locks (KSQ)
10028 Latch cleanup for enqueue resources (KSQ)
10029 Session logon (KSU)
10030 Session logoff (KSU)
10031 Sort debug event (S*)
10032 Sort statistics (SOR*)
10033 Sort run information (SRD*/SRS*)
10034 Access path analysis (APA*)
10035 Parse SQL statement (OPIPRS)
10036 Create remote row source (QKANET)
10037 Allocate remote row source (QKARWS)
10038 Dump row source tree (QBADRV)
10039 Type checking (OPITCA)
10040 Dirty cache list
10041 Dump undo records skipped
10042 Trap error during undo application
10043 Check consistency of owner/waiter/converter lists in KSQ
10044 Free list undo operations
10045 Free list update operations – ktsrsp, ktsunl
10046 Enable SQL statement timing
10047 Trace switching of sessions
10048 Undo segment shrink
10049 Protect library cache memory heaps
10050 Sniper trace
10051 Trace OPI calls
10052 Don’t clean up obj$
10053 CBO Enable optimizer trace
10054 Trace UNDO handling in MLS
10055 Trace UNDO handing
10056 Dump analyze stats (kdg)
10057 Suppress file names in error messages
10058 Use table scan cost in tab$.spare1
10059 Simulate error in logfile create/clear
10060 CBO Enable predicate dump
10061 Disable SMON from cleaning temp segment
10062 Disable usage of OS Roles in osds
10063 Disable usage of DBA and OPER privileges in osds
10064 Thread enable debug crash level %s, thread %s
10065 Limit library cache dump information for state object dump
10066 Simulate failure to verify file
10067 Force redo log checksum errors – block number
10068 Force redo log checksum errors – file number
10069 Trusted Oracle test event
10070 Force datafile checksum errors – block number
10071 Force datafile checksum errors – file number
10072 Protect latch recovery memory
10073 Have PMON dump info before latch cleanup
10074 Default trace function mask for kst
10075 CBO Disable outer-join to regular join conversion
10076 CBO Enable cartesian product join costing
10077 CBO Disable view-merging optimization for outer-joins
10078 CBO Disable constant predicate elimination optimization
10079 Trace data sent/received via SQL*Net
10080 Dump a block on a segment list which cannot be exchanged
10081 Segment High Water Mark has been advanced
10082 Free list head block is the same as the last block
10083 A brand new block has been requested from space management
10084 Free list becomes empty
10085 Free lists have been merged
10086 CBO Enable error if kko and qka disagree on oby sort
10087 Disable repair of media corrupt data blocks
10088 CBO Disable new NOT IN optimization
10089 CBO Disable index sorting
10090 Invoke other events before crash recovery
10091 CBO Disable constant predicate merging
10092 CBO Disable hash join
10093 CBO Enable force hash joins
10094 Before resizing a data file
10095 Dump debugger commands to trace file
10096 After the cross instance call when resizing a data file
10097 After generating redo when resizing a data file
10098 After the OS has increased the size of a data file
10099 After updating the file header with the new file size
10100 After the OS has decreased the size of a data file
10101 Atomic redo write recovery
10102 Switch off anti-joins
10103 CBO Disable hash join swapping
10104 Dump hash join statistics to trace file
10105 CBO Enable constant pred trans and MPs w WHERE-clause
10106 CBO Disable evaluating correlation pred last for NOT IN
10107 CBO Always use bitmap index
10108 CBO Don’t use bitmap index
10109 CBO Disable move of negated predicates
10110 CBO Try index rowid range scans
10111 Bitmap index creation switch
10112 Bitmap index creation switch
10113 Bitmap index creation switch
10114 Bitmap index creation switch
10115 CBO Bitmap optimization use maximal expression
10116 CBO Bitmap optimization switch
10117 CBO Disable new parallel cost model
10118 CBO Enable hash join costing
10119 QKA Disable GBY sort elimination
10120 Generate relative file # different from absolute
10121 CBO Don’t sort bitmap chains
10122 Disable transformation of count(col) to count(*)
10123 QKA Disable Bitmap And-EQuals
10124 Force creation of segmented arrays by kscsAllocate
10125 Disable remote sort elimination
10126 Debug oracle java xa
10127 Disable remote query block operation
10128 Dump Partition Pruning Information
10129 Alter histogram lookup for remote queries
10130 Sort disable readaheads
10131 Use v$sql_plan code path for explain plan
10132 Dump plan after compilation
10133 Testing for SQL Memory Management
10134 Tracing for SQL Memory Management for session
10135 CBO do not count 0 rows partitions
10136 CBO turn off fix for bug 1089848
10137 CBO turn off fix for bug 1344111
10138 CBO turn off fix for bug 1577003
10139 CBO turn off fix for bug 1386119
10140 CBO turn off fix for bug 1332980
10141 CBO disable additional keys for inlist in bitmap optimization
10142 CBO enable dynamic selectivity estimation
10143 CBO force dynamic selectivity estimation (if enabled)
10145 Test auditing network errors
10146 Enable Oracle TRACE collection
10148 Use pre-7.3.3 random generator
10149 Allow the creation of constraints with illegal date constants
10150 Import exceptions
10151 Force duplicate dependency removal
10152 CBO don’t consider function costs in plans
10153 Switch to use public synonym if private one does not translate
10154 Switch to disallow synonyms in DDL statements
10155 CBO disable generation of transitive OR-chains
10156 CBO disable index fast full scan
10157 CBO disable index access path for in-list
10158 CBO preserve predicate order in post-filters
10159 CBO disable order-by sort pushdown into domain indexes
10160 CBO disable use of join index
10161 CBO recursive semi-join on/off-switch
10162 CBO join-back elimination on/off-switch
10163 CBO join-back elimination on/off-switch
10164 CBO disable subquery-adjusted cardinality fix
10165 Mark session to be aborted during shutdown normal
10166 Trace long operation statistics updates
10167 CBO use old index MIN/MAX optimization
10168 CBO disable single-table predicate predicate generation
10169 CBO disable histograms for multi partitions
10170 CBO use old bitmap costing
10171 CBO disable transitive join predicates
10172 CBO force hash join back
10173 CBO no constraint-based join-back elimination
10174 View join-back elimination switch
10175 CBO star transformation switch
10176 CBO colocated join switch
10177 CBO colocated join switch
10178 CBO turn off hash cluster filtering through memcmp
10179 CBO turn off transitive predicate replacement
10180 Temp table transformation print error messages
10181 CBO disable multi-column in-list processing
10182 CBO disable generation of implied predicates
10183 CBO disable cost rounding
10184 CBO disable OR-exp if long inlist on bitmap column
10185 CBO force index joins
10186 CBO disable index join
10187 CBO additional index join switch
10188 “CBO additional index join switch
10189 CBO turn off FFS null fix
10190 Analyze use old frequency histogram collection and density
10191 Avoid conversion of in-lists back to OR-expanded form
10192 Nopushdown when number of groups exceed number of rows
10193 Force repeatable sampling with specified seed
10194 CBO disable new LIKE selectivity heuristic
10195 CBO don’t use check constraints for transitive predicates
10196 CBO disable index skip scan
10197 CBO force index skip scan
10198 Check undo record
10199 Set parameter in session
10200 Consistent read buffer status
10201 Consistent read undo application
10202 Consistent read block header
10203 Block cleanout
10204 Signal recursive extend
10205 Row cache debugging
10206 Transaction table consistent read
10207 Consistent read transactions’ status report
10208 Consistent read loop check
10209 Enable simulated error on controlfile
10210 Check data block integrity
10211 Check index block integrity
10212 Check cluster integrity
10213 Crash after controlfile write
10214 Simulate write errors on controlfile
10215 Simulate read errors on controlfile
10216 Dump controlfile header
10217 Debug sequence numbers
10218 Dump uba of applied undo
10219 Monitor multi-pass row locking
10220 Show updates to the transaction table
10221 Show changes done with undo
10222 Row cache
10223 Transaction layer – turn on verification codes
10224 Index block split/delete trace
10225 Free/used extent row cache
10226 Trace CR applications of undo for data operations
10227 Verify (multi-piece) row structure
10228 Trace application of redo by kcocbk
10229 Simulate I/O error against datafiles
10230 Check redo generation by copying before applying
10231 Skip corrupted blocks on _table_scans_
10232 Dump corrupted blocks symbolically when kcbgotten
10233 Skip corrupted blocks on index operations
10234 Trigger event after calling kcrapc to do redo N times
10235 Check memory manager internal structures
10236 Library cache manager
10237 Simulate ^C (for testing purposes)
10238 Instantiation manager
10239 Multi-instance library cache manager
10240 Dump dba’s of blocks that we wait for
10241 Remote SQL execution tracing/validation
10242 Suppress OER 2063 (for testing distrib w/o different error log)
10243 Simulated error for test %s of K2GTAB latch cleanup
10244 Make tranids in error msgs print as 0.0.0 (for testing)
10245 Simulate lock conflict error for testing PMON
10246 Print trace of PMON actions to trace file
10247 Turn on scgcmn tracing. (VMS ONLY)
10248 Turn on tracing for dispatchers
10249 Turn on tracing for multi-stated servers
10250 Trace all allocate and free calls to the topmost SGA heap
10251 Check consistency of transaction table and undo block
10252 Simulate write error to data file header
10253 Simulate write error to redo log
10254 Trace cross-instance calls
10255 Pl/sql parse checking
10256 Turn off shared server load balancing
10257 Trace shared server load balancing
10258 Force shared servers to be chosen round-robin
10259 Get error message text from remote using explicit call
10260 Trace calls to SMPRSET (VMS ONLY)
10261 Limit the size of the PGA heap
10262 Don’t check for memory leaks
10263 Don’t free empty PGA heap extents
10264 Collect statistics on context area usage (x$ksmcx)
10265 Keep random system generated output out of error messages
10266 Trace OSD stack usage
10267 Inhibit KSEDMP for testing
10268 Don’t do forward coalesce when deleting extents
10269 Don’t do coalesces of free space in SMON
10270 Debug shared cursors
10271 Distributed transaction after COLLECT
10272 Distributed transaction before PREPARE
10273 Distributed transaction after PREPARE
10274 Distributed transaction before COMMIT
10275 Distributed transaction after COMMIT
10276 Distributed transaction before FORGET
10277 Cursor sharing (or not) related event (used for testing)
10278 Internal testing
10279 Simulate block corruption in kdb4chk
10280 Internal testing – segmentation fault during crash recovery
10281 Maximum time to wait for process creation
10282 Inhibit signalling of other backgrounds when one dies
10283 Simulate asynch I/O never completing
10284 Simulate zero/infinite asynch I/O buffering
10285 Simulate controlfile header corruption
10286 Simulate controlfile open error
10287 Simulate archiver error
10288 Do not check block type in ktrget
10289 Do block dumps to trace file in hex rather than fromatted
10290 Kdnchk – checkvalid event – not for general purpose use.
10291 Die in tbsdrv to test controlfile undo
10292 Dump uet entries on a 1561 from dtsdrv
10293 Dump debugging information when doing block recovery
10294 Enable PERSISTENT DLM operations on non-compliant systems
10295 Die after file header update durning cf xact
10296 Disable ORA-379
10297 Customize dictionary object number cache
10298 Ksfd i/o tracing
10299 Trace prefetch tracking decisions made by CKPT
10300 Disable undo compatibility check at database open
10301 Enable LCK timeout table consistency check
10302 Trace create or drop internal trigger
10303 Trace loading of library cache for internal triggers
10304 Trace replication trigger
10305 Trace updatable materialized view trigger
10306 Trace materialized view log trigger
10307 Trace RepCat execution
10308 Replication testing event
10309 Trigger Debug event
10310 Trace synchronous change table trigger
10311 Disable Flashback Table Timestamp checking
10312 Allow disable to log rows into the mapping table
10319 Trace PGA statistics maintenance
10320 Enable data layer (kdtgrs) tracing of space management calls
10321 Datafile header verification debug failure.
10323 Before committing an add datafile command
10324 Enable better checking of redo logs errors
10325 Trace control file record section expand and shrink operations
10326 Clear logfile debug crash at %s, log %s
10327 Simulate ORA-00235 error for testing
10328 Disable first-to-mount split-brain error, for testing
10329 Simulate lost write, test detection by two-pass recovery
10330 Clear MTTR statistics in checkpoint progress record
10331 Simulate resilvering during recovery
10332 Force ALTER SYSTEM QUIESCE RESTRICTED command to fail
10336 Do remote object transfer using remote SQL
10337 Enable padding owner name in slave sql
10340 Buffer queues sanity check for corrupted buffers
10341 Simulate out of PGA memory in DBWR during object reuse
10342 Raise unknown exception in ACQ_ADD when checkpointing
10343 Raise an out of memory exception-OER 4031 in ACQ_ADD
10344 Simulate kghxal returning 0 in ACQ_ADD but no exception
10345 Validate queue when linking or unlinking a buffer
10346 Check that all buffers for checkpoint have been written
10347 Dump active checkpoint entries and checkpoint buffers
10348 Test abnormal termination of process initiating file checkpoint
10349 Do not allow ckpt to complete
10350 Simulate more than one object & tsn id in object reuse
10351 Size of slots
10352 Report direct path statistics
10353 Number of slots
10354 Turn on direct read path for parallel query
10355 Turn on direct read path for scans
10356 Turn on hint usage for direct read
10357 Turn on debug information for direct path
10359 Turn off updates to control file for direct writes
10360 Enable dbwr consistency checking
10365 Turn on debug information for adaptive direct reads
10370 Parallel query server kill event
10371 Disable TQ hint
10372 Parallel query server kill event proc
10373 Parallel query server kill event
10374 Parallel query server interrupt (validate lock value)
10375 Turn on checks for statistics rollups
10376 Turn on table queue statistics
10377 Turn off load balancing
10378 Force hard process/range affinity
10379 Direct read for rowid range scans (unimplemented)
10380 Kxfp latch cleanup testing event
10381 Kxfp latch cleanup testing event
10382 Parallel query server interrupt (reset)
10383 Auto parallelization testing event
10384 Parallel dataflow scheduler tracing
10385 Parallel table scan range sampling method
10386 Parallel SQL hash and range statistics
10387 Parallel query server interrupt (normal)
10388 Parallel query server interrupt (failure)
10389 Parallel query server interrupt (cleanup)
10390 Trace parallel query slave execution
10391 Trace PX granule allocation/assignment
10392 Parallel query debugging bits
10393 Print parallel query statistics
10394 Generate a fake load to test adaptive and load balancing
10395 Adjust sample size for range table queues
10396 Circumvent range table queues for queries
10397 Suppress verbose parallel coordinator error reporting
10398 Enable timeouts in parallel query threads
10399 Trace buffer allocation
10400 Turn on system state dumps for shutdown debugging
10401 Turn on IPC (ksxp) debugging
10402 Turn on IPC (skgxp) debugging
10403 Fake CPU number for default degree of parallelism
10404 Crash dbwr after write
10405 Emulate broken mirrors
10406 Enable datetime TIMESTAMP, INTERVAL datatype creation
10407 Enable datetime TIME datatype creation
10408 Disable OLAP builtin window function usage
10410 Trigger simulated communications errors in KSXP
10411 Simulate errors in IMR
10412 Trigger simulated errors in CGS/CM interface
10425 Enable global enqueue service open event trace
10426 Enable global enqueue service convert event trace
10427 Enable global enqueue service traffic controller event trace
10428 Enable tracing of global enqueue service distributed resource
10429 Enable tracing of global enqueue service IPC calls
10430 Enable tracing of global enqueue service AST calls
10431 Enable verification messages on pi consistency
10432 Enable tracing of global cache service fusion calls
10433 Global enqueue service testing event
10434 Enable tracing of global enqueue service muliple LMS
10435 Enable tracing of global enqueue service deadlock detetction
10450 Signal ctrl-c in kdddca (drop column) after n rows
10500 Turn on traces for SMON
10510 Turn off SMON check to offline pending offline rollback segment
10511 Turn off SMON check to cleanup undo dictionary
10512 Turn off SMON check to shrink rollback segments
10515 Turn on event to use physical cleanout
10550 Signal error during create as select/create index after n rows
10560 Block type ‘%s’
10561 Block type ‘%s’, data object# %s
10562 Error occurred while applying redo to data block (file# %s, block# %s)
10563 Test recovery had to corrupt data block (file# %s, block# %s) in order to proceed
10564 Tablespace %s
10565 Another test recovery session is active
10566 Test recovery has used all the memory it can use
10567 Redo is inconsistent with data block (file# %s, block# %s)
10568 Failed to allocate recovery state object: out of SGA memory
10570 Test recovery complete
10571 Test recovery canceled
10572 Test recovery canceled due to errors
10573 Test recovery tested redo from change %s to %s
10574 Test recovery did not corrupt any data block
10575 Give up restoring recovered datafiles to consistent state: out of memory
10576 Give up restoring recovered datafiles to consistent state: some error occurred
10577 Can not invoke test recovery for managed standby database recovery
10578 Can not allow corruption for managed standby database recovery
10579 Can not modify control file during test recovery
10580 Can not modify datafile header during test recovery
10581 Can not modify redo log header during test recovery
10582 The control file is not a backup control file
10583 Can not recovery file %s renamed as missing during test recovery
10584 Can not invoke parallel recovery for test recovery
10585 Test recovery can not apply redo that may modify control file
10586 Test recovery had to corrupt 1 data block in order to proceed
10587 Invalid count for ALLOW n CORRUPTION option
10588 Can only allow 1 corruption for normal media/standby recovery
10589 Test recovery had to corrupt %s data blocks in order to proceed
10590 Kga (argus debugger) test flags
10591 Kga (argus debugger) test flags
10592 Kga (argus debugger) test flags
10593 Kga (argus debugger) test flags
10594 Kga (argus debugger) test flags
10595 Kga (argus debugger) test flags
10596 Kga (argus debugger) test flags
10597 Kga (argus debugger) test flags
10598 Kga (argus debugger) test flags
10599 Kga (argus debugger) test flags
10600 Check cursor frame allocation
10601 Turn on debugging for cursor_sharing (literal replacement)
10602 Cause an access violation (for testing purposes)
10603 Cause an error to occur during truncate (for testing purposes)
10604 Trace parallel create index
10605 Enable parallel create index by default
10606 Trace parallel create index
10607 Trace index rowid partition scan
10608 Trace create bitmap index
10609 Trace for array index insertion
10610 Trace create index pseudo optimizer
10611 Causes migration to fail – testing only
10612 Prints debug information for auto-space managed segments
10613 Prints debug information for auto-space managed segments
10614 Operation not allowed on this segment
10615 Invalid tablespace type for temporary tablespace
10616 Operation not allowed on this tablespace
10617 Cannot create rollback segment in this tablespace
10618 Operation not allowed on this segment
10619 Avoid assertions when possible
10620 Operation not allowed on this segment
10621 Data block does not belong to the segment
10622 Test/trace online index (re)build
10623 Enable Index range scan Prefetch – testing only
10650 Disable cache-callback optimisation
10651 Incorrect file number block number specified
10666 Do not get database enqueue name
10667 Cause sppst to check for valid process ids
10690 Set shadow process core file dump type (Unix only)
10691 Set background process core file type (Unix only)
10700 Alter access violation exception handler
10701 Dump direct loader index keys
10702 Enable histogram data generation
10703 Simulate process death during enqueue get
10704 Print out information about what enqueues are being obtained
10705 Print Out Tracing information for every I/O done by ODSs
10706 Print out information about global enqueue manipulation
10707 Simulate process death for instance registration
10708 Print out Tracing information for skxf multi instance comms
10709 Enable parallel instances in create index by default
10710 Trace bitmap index access
10711 Trace bitmap index merge
10712 Trace bitmap index or
10713 Trace bitmap index and
10714 Trace bitmap index minus
10715 Trace bitmap index conversion to rowids
10716 Trace bitmap index compress/decompress
10717 Trace bitmap index compaction trace for index creation
10718 Event to disable automatic compaction after index creation
10719 Trace bitmap index dml
10720 Trace db scheduling
10721 Internal testing – temp table transformation
10722 Set parameters for CPU frequency calculation (debug)
10723 Internal testing – release buffer for buffer cache shrink
10730 Trace row level security policy predicates
10731 Dump SQL for CURSOR expressions
10740 Disables fix for bug 598861
10750 Test rollback segment blksize guessing for index array insert
10800 Disable Smart Disk scan
10801 Enable Smart Disk trace
10802 Reserved for Smart Disk
10803 Write timing statistics on cluster database recovery scan
10804 Reserved for ksxb
10806 Switch to 7.3 mode when detaching sessions
10807 Disable user id check when switching to a global transaction
10810 Trace snapshot too old
10811 Trace block cleanouts
10812 Trace Consistent Reads
10830 Trace group by sort row source
10841 Default un-inintialized charact set form to SQLCS_IMPLICIT
10850 Enable time manager tracing
10851 Allow Drop command to drop queue tables
10852 Enable dumping of the AQ statistics hash table
10853 Event for AQ statistics latch cleanup testing
10856 Disable AQ propagator from using streaming
10857 Force AQ propagator to use two-phase commit
10858 Crash the AQ propagator at different stages of commit
10859 Disable updates of message retry count
10860 Event for AQ admin disable new name parser
10861 Disable storing extended message properties
10862 Resolve default queue owner to current user in enqueue/dequeue
10900 Extent manager fault insertion event #%s
10902 Disable seghdr conversion for ro operation
10903 Force tablespaces to become locally managed
10904 Allow locally managed tablespaces to have user allocation
10905 Do cache verification (kcbcxx) on extent allocation
10906 Unable to extend segment after insert direct load
10907 Trace extent management events
10908 Trace temp tablespace events
10909 Trace free list events
10924 Import storage parse error ignore event
10925 Trace name context forever
10926 Trace name context forever
10927 Trace name context forever
10928 Trace name context forever
10929 Trace name context forever
10930 Trace name context forever
10931 Trace name context forever
10932 Trace name context forever
10933 Trace name context forever
10934 Reserved. Used only in version 7.x.
10935 Reserved. Used only in version 7.x.
10936 Trace name context forever
10937 Trace name context forever
10938 Trace name context forever
10939 Trace name context forever
10940 Trace name context forever
10941 Trace name context forever
10943 Trace name context forever
10944 Trace name context forever
10945 Trace name context forever
10975 Trace execution of parallel propagation
10976 Internal package related tracing
10977 Trace event for RepAPI
10979 Trace flags for join index implementation
10980 Prevent sharing of parsed query during Materialized View query generation
10981 Dscn computation-related event in replication
10982 Event to turn off CDC-format MV Logs
10983 Event to enable Create_Change_Table debugging
10984 Subquery materialized view-related event
10985 Event for NULL refresh of materialized views
10986 Do not use HASH_AJ in refresh
10987 Event for the support of caching table with object feature
10988 Event to get exclusive lock during materialized view refresh in IAS
10989 Event to internally create statistics MV
10999 Do not get database enqueue name
10999 End Pseudo-error debugging events

———————————- 事件编号和对应的描述 ———————————-

调优实践01–Oracle常见的等待事件及解决方案

Oracle常见的等待事件及解决方案
  1. 等待事件的相关知识:
    1. 等待事件主要可以分为两类,即空闲(IDLE)等待事件和非空闲(NON-IDLE)等待事件;
      1. 空闲等待事件指ORACLE正等待某种工作,在诊断和优化数据库的时候,不用过多注意这部分事件;
      2. 非空闲等待事件专门针对ORACLE的活动,指数据库任务或应用运行过程中发生的等待,这些等待事件是在调整数据库的时候需要关注与研究的;
      3. 在Oracle 10g中的等待事件有872个,11gR2中等待事件1152个;可以通过v$event_name视图来查看等待事件的相关信息;
    2. 查看等待事件的总个数:SELECT COUNT(*) FROM v$event_name;
    3. 查看等待事件每个分类的分布:SELECT wait_class#, wait_class_id, wait_class, COUNT(*) FROM v$event_name GROUP BY wait_class#, wait_class_id, wait_class ORDER BY wait_class#;                                                                                                        
    4. 相关的视图:
      1. V$SESSION:连接到数据库的会话信息;
      2. V$SESSION_WAIT:当前会话正在等待的资源,此视图已经与v$session视图合并了;
      3. V$SESSION_WAIT_HISTORY:是对V$SESSION_WAIT的简单增强,记录活动SESSION的最近10次等待;
      4. V$SYSTEM_EVENT:由于V$SESSION记录的是动态信息,和SESSION的生命周期相关,而并不记录历史信息,所以ORACLE提供视图V$SYSTEM_EVENT来记录数据库自启动以来所有等待事件的汇总信息;通过这个视图,用户可以迅速获得数据库运行的总体概况;
      5. V$SQL:查看某个session正在执行的sql语句(SELECT t1.sid, t2.sql_text FROM v$session t1 INNER JOIN v$sql t2 ON t1.sql_id = t2.sql_id;SELECT t1.sid, t2.sql_text FROM v$session t1 INNER JOIN v$sql t2 ON t1.sql_address = t2.address;);
      6. V$ACTIVE_SESSION_HISTORY:是ASH的核心,用以记录活动SESSION的历史等待信息,每秒采样一次,这部分内容记录在内存中,记录一个小时的内容;
      7. DBA_HIST_ACTIVE_SESS_HISTORY:通过这个视图进行ASH历史数据的访问;
    5. 可以从v$event_name视图中查看等待事件的类型(SELECT NAME, parameter1, parameter2, parameter3 FROM v$event_name;),v$session中P1-3表示等待的资源是什么;
  2. buffer busy waits:
    1. 从本质上讲,这个等待事件的产生仅说明了一个会话在等待一个Buffer(数据块),但是导致这个现象的原因却有很多种,常见的两种是:
      1. 当一个会话试图修改一个数据块,但这个数据块正在被另一个会话修改时;
      2. 当一个会话需要读取一个数据块,但这个数据块正在被另一个会话读取到内存中时;
    2. Oracle操作的最小单位是块(Block),即使你要修改一条记录,也需要对这条记录所在的这个数据块做操作;当你对这个数据块做修改时,其他的会话将被阻止对这个数据块上的数据做修改(即使其他用户修改的不是当前用户修改的数据),但是可以以一致性的方式读取这个数据块(使用UNDO构建CR块);当前的用户修改完这个数据块后,将会立即释放掉加在这个数据块上的排他锁,这样另一个会话就可以继续修改它;修改操作是一个非常短暂的时间,这种加锁的机制我们叫Latch;
    3. 当一个会话修改一个数据块时,是按照以下步骤来完成的:
      1. 以排他的方式获得这个数据块(Latch);
      2. 修改这个数据块;
      3. 释放Latch;
    4. Buffer busy waits等待事件常见于数据库中存在的热快的时候,当多个用户频繁地读取或者修改同样的数据块时,这个等待事件就会产生;如果等待的时间很长,我们在AWR或者statspack报告中就可以看到;
    5. 解决办法:
      1. 如果等待处于字段头部,应增加自由列(freelist)的组数,或者增加pctused到pctfree之间的距离;
      2. 如果等待处于回退段(undo)头部块,可以通过增加回滚段(rollback segment)来解决缓冲区的问题;
      3. 如果等待处于回退段(undo)非头部块上,就需要降低驱动一致读取的表中的数据密度,或者增大DB_CACHE_SIZE;
      4. 如果等待处于数据块,可以将数据移到另一数据块以避开这个”热”数据块,增加表中的自由列表或使用LMT表空间;
      5. 如果等待处于索引块,应该重建索引,分割索引或使用反向键索引;
    6. 等待事件的参数:
      1. File#:等待访问数据块所在的文件id号;
      2. Blocks:等待访问的数据块号;
  3. db file scattered read:
    1. 这是一个用户操作引起的等待事件,当用户发出每次I/O需要读取多个数据块这样的SQL操作时,会产生这个等待事件,最常见的两种情况是:
      1. 全表扫描(FTS: Full Table Scan);
      2. 索引快速扫描(IFFS: index fast full scan);
    2. 这个名称中的scattered(离散),可能会导致很多人认为它是以scattered的方式来读取数据块的,其实恰恰相反,当发生这种等待事件时,SQL的操作都是顺序地读取数据块的,比如FTS或者IFFS方式(如果忽略需要读取的数据块已经存在内存中的情况);
    3. 这里的scattered指的是读取的数据块在内存中的存放方式,它们被读取到内存中后,是以分散的方式存在在内存中,而不是连续的;
    4. 等待事件的参数:
      1. File#: 要读取的数据块所在数据文件的文件号;
      2. Block#: 要读取的起始数据块号;
      3. Blocks:需要读取的数据块数目;
  4. db file sequential read:
    1. 当Oracle需要每次I/O只读取单个数据块这样的操作时,会产生这个等待事件,最常见的情况:
      1. 索引的访问(除IFFS外的方式);
      2. 回滚操作;
      3. 以ROWID的方式访问表中的数据;
      4. 重建控制文件;
      5. 对文件头做DUMP等;
    2. 这里的sequential也并非指的是Oracle按顺序的方式来访问数据,和db file scattered read一样,它指的是读取的数据块在内存中是以连续的方式存放的;
    3. 等待事件的参数:
      1. File#:要读取的数据块锁在数据文件的文件号;
      2. Block#:要读取的起始数据块号;
      3. Blocks:要读取的数据块数目(这里应该等于1);
    4. 查找热点快的方法:SELECT owner, segment_name, segment_type FROM dba_extents WHERE file_id = &file_id AND &block_id BETWEEN block_id AND block_id + &blocks – 1;
  5. buffer latch:
    1. 内存中数据块的存放位置是记录在一个hash列表(cache buffer chains)当中的;当一个会话需要访问某个数据块时,它首先要搜索这个hash列表,从列表中获得数据块的地址,然后通过这个地址去访问需要的数据块,这个列表Oracle会使用一个latch来保护它的完整性;当一个会话需要访问这个列表时,需要获取一个Latch,只有这样,才能保证这个列表在这个会话的浏览当中不会发生变化;
    2. 产生buffer latch的等待事件的主要原因是:
      1. Buffer chains太长,导致会话搜索这个列表花费的时间太长,使其他的会话处于等待状态;
      2. 同样的数据块被频繁访问,就是我们通常说的热快问题;
    3. 解决办法:产生buffer chains太长,我们可以使用多个buffer pool的方式来创建更多的buffer chains,或者使用参数DB_BLOCK_LRU_LATCHES来增加latch的数量,以便于更多的会话可以获得latch,这两种方法可以同时使用;
    4. 等待事件的参数:
      1. Latch addr:会话申请的latch在SGA中的虚拟地址,通过以下的SQL语句可以根据这个地址找到它对应的Latch名称(SELECT * FROM v$latch a, v$latchname b WHERE a.addr = <latch addr> AND a.latch# = b.latch#;);
      2. chain#:buffer chains hash列表中的索引值,当这个参数的值等于0xfffffff时,说明当前的会话正在等待一个LRU latch;
  6. control file parallel write:
    1. 当数据库中有多个控制文件的拷贝时,Oracle需要保证信息同步地写到各个控制文件当中,这是一个并行的物理操作过程,因为称为控制文件并行写,当发生这样的操作时,就会产生control file parallel write等待事件;
    2. 控制文件频繁写入的主要原因:
      1. 日志切换太过频繁,导致控制文件信息相应地需要频繁更新;
      2. 系统I/O出现瓶颈,导致所有I/O出现等待;
    3. 解决办法:
      1. 当系统出现日志切换过于频繁的情形时,可以考虑适当地增大日志文件的大小来降低日志切换频率;
      2. 当系统出现大量的control file parallel write 等待事件时,可以通过比如降低控制文件的拷贝数量,将控制文件的拷贝存放在不同的物理磁盘上的方式来缓解I/O争用;
    4. 等待事件的参数:
      1. Files:Oracle要写入的控制文件个数;
      2. Blocks:写入控制文件的数据块数目;
      3. Requests:写入控制请求的I/O次数;
  7. control file sequential read:
    1. 当数据库需要读取控制文件上的信息时,会出现这个等待事件,因为控制文件的信息是顺序写的,所以读取的时候也是顺序的,因此称为控制文件顺序读;
    2. 控制文件频繁读取的主要原因:
      1. 备份控制文件;
      2. RAC环境下不同实例之间控制文件的信息共享;
      3. 读取控制文件的文件头信息;
      4. 读取控制文件其他信息;
    3. 等待事件的参数:
      1. File#:要读取信息的控制文件的文件号;
      2. Block#:读取控制文件信息的起始数据块号;
      3. Blocks:需要读取的控制文件数据块数目;
  8. db file parallel read:
    1. 这是一个很容易引起误导的等待事件,实际上这个等待事件和并行操作(比如并行查询,并行DML)没有关系;这个事件发生在数据库恢复的时候,当有一些数据块需要恢复的时候,Oracle会以并行的方式把他们从数据文件中读入到内存中进行恢复操作;
    2. 等待事件的参数:
      1. Files:操作需要读取的文件个数;
      2. Blocks:操作需要读取的数据块个数;
      3. Requests:操作需要执行的I/O次数;
  9. db file parallel write:
    1. 这是一个后台等待事件,它同样和用户的并行操作没有关系,它是由后台进程DBWR产生的,当后台进程DBWR想磁盘上写入脏数据时,会发生这个等待;
    2. DBWR会批量地将脏数据并行地写入到磁盘上相应的数据文件中,在这个批次作业完成之前,DBWR将出现这个等待事件;如果仅仅是这一个等待事件,对用户的操作并没有太大的影响,当伴随着出现free buffer waits等待事件时,说明此时内存中可用的空间不足,这时候会影响到用户的操作,比如影响到用户将脏数据块读入到内存中;
    3. 当出现db file parallel write等待事件时,可以通过启用操作系统的异步I/O的方式来缓解这个等待;当使用异步I/O时,DBWR不在需要一直等到所有数据块全部写入到磁盘上,它只需要等到这个数据写入到一个百分比之后,就可以继续进行后续的操作;
    4. 等待事件的参数:
      1. Requests:操作需要执行的I/O次数;
      2. Timeouts:等待的超时时间;
  10. Db file single write:
    1. 这个等待事件通常只发生在一种情况下,就是Oracle更新数据文件头信息时(比如发生Checkpoint);
    2. 当这个等待事件很明显时,需要考虑是不是数据库中的数据文件数量太大,导致Oracle需要花较长的时间来做所有文件头的更新操作(checkpoint);
    3. 等待事件的参数:
      1. File#:需要更新的数据块所在的数据文件的文件号;
      2. Block#:需要更新的数据块号;
      3. Blocks:需要更新的数据块数目(通常来说应该等于1);
  11. direct path read:
    1. 这个等待事件发生在会话将数据块直接读取到PGA当中而不是SGA中的情况,这些被读取的数据通常是这个会话私有的数据,所以不需要放到SGA作为共享数据,因为这样做没有意义;这些数据通常是来自与临时段上的数据,比如一个会话中SQL的排序数据,并行执行过程中间产生的数据,以及Hash Join,merge join产生的排序数据,因为这些数据只对当前的会话的SQL操作有意义,所以不需要放到SGA当中;
    2. 当发生direct path read等待事件时,意味着磁盘上有大量的临时数据产生,比如排序,并行执行等操作;或者意味着PGA中空闲空间不足;
    3. 等待事件的参数:
      1. Descriptor address:一个指针,指向当前会话正在等待的一个direct read I/O;
      2. First dba:descriptor address中最旧的一个I/O数据块地址;
      3. Block cnt:descriptor address上下文中涉及的有效的buffer数量;
  12. direct path write:
    1. 这个等待事件和direct path read正好相反,是会话将一些数据从PGA中直接写入到磁盘文件上,而不经过SGA;
      1. 使用临时表空间排序(内存不足);
      2. 数据的直接加载(使用append方式加载数据);
      3. 并行DML操作;
    2. 等待事件的参数:
      1. Descriptor address:一个指针,指向当前会话正在等待的一个direct read I/O;
      2. First dba:descriptor address中最旧的一个I/O数据块地址;
      3. Block cnt:descriptor address上下文中涉及的有效的buffer数量;
  13. enqueue:
    1. Enqueue这个词其实是lock的另一种描述语;
    2. 当我们在AWR报告中发现长时间的enqueue等待事件时,说明数据库中出现了阻塞和等待,可以关联AWR报告中的enqueue activity部分来确定是哪一种锁定出现了长时间等待;
    3. 等待事件的参数:
      1. Name:enqueue的名称和类型;
      2. Mode:enqueue的模式;
    4. 查看当前会话等待的enqueue名称和类型:SELECT chr(to_char(bitand(p1, -16777216)) / 16777215) || chr(to_char(bitand(p1, 16711680)) / 65535) “Lock”, to_char(bitand(p1, 65535)) “Mode” FROM v$session_wait WHERE event = ‘enqueue’;
    5. 模式代码及解释:
      1. 1-Null mode
      2. 2-Sub-Share
      3. 3-Sub-Exclusive
      4. 4-Share
      5. 5-Share/Sub-Exclusive
      6. 6-Exclusive
    6. Enqueue的缩写及解释;
  14. free buffer waits:
    1. 当一个会话将数据块从磁盘读到内存中时,它需要到内存中找到空闲的内存空间来存放这些数据块,当内存中没有空闲的空间时,就会产生这个等待;除此之外,还有一种情况就是会话在做一致性读时,需要构造数据块在某个时刻的前映像(image),此时需要申请内存来存放这些新构造的数据块,如果内存中无法找到这样的内存块,也会发生这个等待事件;
    2. 当数据库中出现比较严重的free buffer waits等待事件时,可能的原因是:
      1. Data buffer太小,导致内存空间不够;
      2. 内存中的脏数据太多,DBWR无法及时将这些脏数据写到磁盘中以释放空间
    3. 解决办法:
      1. 加大db_buffer_cache大小;
      2. 增加dbwr进程数量;
      3. 增加检查点或者物理磁盘的数量;
    4. 等待事件的参数:
      1. File#:需要读取的数据块所在的数据文件的文件号;
      2. Block#:需要读取的数据块块号;
  15. latch free:
    1. 在10g之前的版本里,latch free等待事件代表了所有的latch等待,在10g以后,一些常用的latch事件已经被独立了出来:所以latch free等待事件在10g以后的版本中并不常见,而是以具体的Latch等待事件出现;
    2. latch是一种低级排队机制(它们被准确地称为相互排斥机制),用于保护系统全局区域(SGA)中共享内存结构;latch就像是一种快速地被获取和释放的内存锁;latch用于防止共享内存结构被多个用户同时访问;如果latch不可用,就会记录latch释放失败;大多数latch 问题都与以下操作相关:
      1. 不能使用邦定变量(库缓存latch);
      2. 重复生成问题(重复分配latch);
      3. 缓冲存储器竞争问题(缓冲器存储LRU 链),以及缓冲存储器中的”热”块(缓冲存储器链);
      4. 也有一些latch等待与bug(程序错误)有关;
    3. 查看latch相关的等待事件:SELECT NAME FROM v$event_name WHERE NAME LIKE ‘latch%’;
    4. 查找事件热点对象的sql语句;
    5. latch问题的解决办法:
      1. Library Cache and Shared Pool(未绑定变量—绑定变量,调整shared_pool_size):每当执行SQL或PL/SQL存储过程,包,函数和触发器时,这个Latch即被用到.Parse操作中此Latch也会被频繁使用;
      2. Redo Copy(增大_LOG_SIMULTANEOUS_COPIES参数):重做拷贝Latch用来从PGA向重做日志缓冲区拷贝重做记录;
      3. Redo Allocation(最小化REDO生成,避免不必要提交):此Latch用来分配重做日志缓冲区中的空间,可以用NOLOGGING来减缓竞争;
      4. Row Cache Objects(增大共享池):数据字典竞争,过度parsing;
      5. Cache Buffers Chains(_DB_BLOCK_HASH_BUCKETS应增大或设为质数):”过热”数据块造成了内存缓冲链Latch竞争;
      6. Cache Buffers Lru Chain(调整SQL,设置DB_BLOCK_LRU_LATCHES,或使用多个缓冲区池):扫描全部内存缓冲区块的LRU(最近最少使用)链时要用到内存缓冲区LRU链Latch;太小内存缓冲区,过大的内存缓冲区吞吐量,过多的内存中进行的排序操作,DBWR速度跟不上工作负载等会引起此Latch竞争;
    6. 等待事件的参数:
      1. Address:会话等待的latch地址;
      2. Number:latch号,通过这个号,可以从v$latchname视图中找到这个latch的相关的信息(SELECT * FROM v$latchname WHERE latch# = NUMBER;);
      3. Tries:会话尝试获取Latch的次数;
  16. library cache lock:
    1. 这个等待时间发生在不同用户在共享中由于并发操作同一个数据库对象导致的资源争用的时候,比如当一个用户正在对一个表做DDL操作时,其他的用户如果要访问这张表,就会发生library cache lock等待事件,它要一直等到DDL操作完成后,才能继续操作;
    2. 该事件通常是由于执行多个DDL操作导致的,即在library cache object上添加一个排它锁后,又从另一个会话给它添加一个排它锁,这样在第二个会话就会生成等待;可通过到基表x$kgllk中查找其对应的对象;
    3. 查询引起该等待事件的阻塞者的sid,会话用户,锁住的对象的脚本;
    4. 等待事件的参数:
      1. Handle address:被加载的对象的地址;
      2. Lock address:锁的地址;
      3. Mode:被加载对象的数据片段;
      4. Namespace:被加载对象在v$db_object_cache视图中namespace名称;
  17. Library cache pin
    1. 这个等待事件和library cache lock一样是发生在共享池中并发操作引起的事件;通常来讲,如果Oracle要对一些PL/SQL或者视图这样的对象做重新编译,需要将这些对象pin到共享池中;如果此时这个对象被其他的用户特有,就会产生一个library cache pin的等待;
    2. P1,P2可与x$kglpn和x$kglob表相关:
      1. X$KGLOB (Kernel Generic Library Cache Manager Object);
      2. X$KGLPN (Kernel Generic Library Cache Manager Object Pins);
    3. 相关锁的查询sql;
    4. 等待事件的参数:
      1. Handle address:被加载的对象的地址;
      2. Lock address:锁的地址;
      3. Mode:被加载对象的数据片段;
      4. Namespace:被加载对象在v$db_object_cache视图中namespace名称;
  18. log file parallel write:
    1. 后台进程LGWR负责将log buffer当中的数据写到REDO文件中,以重用log buffer的数据;如果每个REDO LOG组里面有2个以上的成员,那么LGWR进程会并行地将REDO信息写入这些文件中;
    2. 如果数据库中出现这个等待事件的瓶颈,主要的原因可能是磁盘I/O性能不够或者REDO文件的分布导致了I/O争用,比如同一个组的REDO成员文件放在相同的磁盘上;
    3. 等待事件的参数:
      1. Files:操作需要写入的文件个数;
      2. Blocks:操作需要写入的数据块个数;
      3. Requests:操作需要执行的I/O次数;
  19. log buffer space:
    1. 当log buffer中没有可用空间来存放新产生的redo log数据时,就会发生log buffer space等待事件;如果数据库中新产生的redo log的数量大于LGWR写入到磁盘中的redo log数量,必须等待LGWR完成写入磁盘的操作,LGWR必须确保redo log写到磁盘成功之后,才能在redo buffer当中重用这部分信息;
    2. 如果数据库中出现大量的log buffer space等待事件,可以考虑如下方法:
      1. 增加redo buffer的大小;
      2. 提升磁盘的I/O性能;
  20. log file sequential read:
    1. 这个等待事件通常发生在对redo log信息进行读取时,比如在线redo的归档操作,ARCH进程需要读取redo log的信息,由于redo log的信息是顺序写入的,所以在读取时也是按照顺序的方式来读取的;
    2. 等待事件的参数:
      1. Log#:发生等待时读取的redo log的sequence号;
      2. Block#:读取的数据块号;
      3. Blocks:读取的数据块个数;
  21. log file single write:
    1. 这个等待事件发生在更新redo log文件的文件头时,当为日志组增加新的日志成员时或者redo log的sequence号改变时,LGWR都会更新redo log文件头信息;
    2. 等待事件的参数:
      1. Log#:发生等待时读取的redo log的sequence号;
      2. Block#:读取的数据块号;
      3. Blocks:读取的数据块个数;
  22. log file switch(archiving needed):
    1. 在归档模式下,这个等待事件发生在在线日志切换(log file switch)时,需要切换的在线日志还没有被归档进程(ARCH)归档完毕的时候;当在线日志文件切换到下一个日志时,需要确保下一个日志文件已经被归档进程归档完毕,否则不允许覆盖那个在线日志信息(否则会导致归档日志信息不完整);
    2. 出现这样的等待事件通常是由于某种原因导致ARCH进程死掉,比如ARCH进程尝试向目的地写入一个归档文件,但是没有成功(介质失效或者其他原因),这时ARCH进程就会死掉;如果发生这种情况,在数据库的alert log文件中可以找到相关的错误信息;
  23. log file switch(checkpoint incomplete):
    1. 当一个在线日志切换到下一个在线日志时,必须保证要切换到的在线日志上的记录的信息(比如一些脏数据块产生的redo log)被写到磁盘上(checkpoint),这样做的原因是,如果一个在线日志文件的信息被覆盖,而依赖这些redo信息做恢复的数据块尚未被写到磁盘上(checkpoint),此时系统down掉的话,Oracle将没有办法进行实例恢复;
    2. 在v$log视图里记录了在线日志的状态,在线日志有三种状态:
      1. Active:这个日志上面保护的信息还没有完成checkpoint;
      2. Inactive:这个日志上面保护的信息已完成checkpoint;
      3. Current:当前的日志;
    3. Oracle在做实例恢复时,会使用状态为current和Active的日志进行实例恢复;
    4. 如果系统中出现大量的log file switch(checkpoint incomplete)等待事件,原因可能是日志文件太小或者日志组太少,所以解决的方法是,增加日志文件的大小或者增加日志组的数量;
  24. log file sync:
    1. 这是一个用户会话行为导致的等待事件,当一个会话发出一个commit命令时,LGWR进程会将这个事务产生的redo log从log buffer里面写到磁盘上,以确保用户提交的信息被安全地记录到数据库中;会话发出的commit指令后,需要等待LGWR将这个事务产生的redo成功写入到磁盘之后,才可以继续进行后续的操作,这个等待事件就叫作log file sync;
    2. 当系统中出现大量的log file sync等待事件时,应该检查数据库中是否有用户在做频繁的提交操作;
    3. 这种等待事件通常发生在OLTP系统上,OLTP系统中存在很多小的事务,如果这些事务频繁被提交,可能引起大量的log file sync的等待事件;
    4. 等待事件的参数:
      1. Buffer#:redo buffer中需要被写入到磁盘中的buffer;
  25. SQL*Net相关的等待事件:
    1. SQL*Net break/reset to client:当出现这个等待事件时,说明服务器端在给客户端发送一个断开连接或者重置连接的请求,正在等待客户的响应,通常的原因是服务器到客户端的网络不稳定导致的;
    2. SQL*Net break/reset to dblink:这个等待事件和SQL*Net break/reset to client相同;不过它表示的是数据库通过dblink访问另一台数据库时,他们之间建立起一个会话,这个等待事件发生在这个会话之间的通信过程中,同样如果出现这个等待事件,需要检查两台数据库之间的通信问题;
    3. SQL*Net message from client:这个等待事件基本上是最常见的一个等待事件;当一个会话建立成功后,客户端会向服务器端发送请求,服务器端处理完客户端请求后,将结果返回给客户端,并继续等待客户端的请求,这时候会产生SQL*Net message from client 等待事件;很显然,这是一个空闲等待,如果客户端不再向服务器端发送请求,服务器端将一直处于这个等待事件状态;
    4. SQL*Net message from dblink:这个等待事件和SQL*Net message from client相同,不过它表示的是数据库通过dblink 访问另一个数据库时,他们之间会建立一个会话,这个等待事件发生在这个会话之间的通信过程中;这个等待事件也是一个空闲等待事件;
    5. SQL*Net message to client:这个等待事件发生在服务器端向客户端发送消息的时候; 当服务器端向客户端发送消息产生等待时,可能的原因是用户端太繁忙,无法及时接收服务器端送来的消息,也可能是网络问题导致消息无法从服务器端发送到客户端;
    6. SQL*Net message to dblink:这个等待事件和SQL*Net message to client相同,不过是发生在数据库服务器和服务器之间的等待事件,产生这个等待的原因可能是远程服务器繁忙,而无法及时接收发送过来的消息,也可能是服务器之间网络问题导致消息无法发送过来;
    7. SQL*Net more data from client:服务器端等待用户发出更多的数据以便完成操作,比如一个大的SQL文本,导致一个SQL*Net 数据包无法完成传输,这样服务器端会等待客户端把整个SQL 文本发过来在做处理,这时候就会产生一个SQL*Net more data from client等待事件;
    8. SQL*Net more data from dblink:在一个分布式事务中,SQL 分布在不同的数据库中执行,远程数据库执行完毕后将结果通过dblink返给发出SQL的数据库,在等待数据从其他数据库中通过dblink传回的过程中,如果数据在远程数据库上处理时间很久,或者有大量的结果集需要返回,或者网络性能问题都会产生SQL*Net more data from dblink 等待事件,它的意思是本地数据库需要等到所有的数据从远程处理完毕通过dblink传回后,才可以在本机继续执行操作;
    9. SQL*Net more data to client:当服务器端有太多的数据需要发给客户端时,可能会产生SQL*Net more data to client等待事件,也可能由于网络问题导致服务器无法及时地将信息或者处理结果发送给客户端,同样会产生这个等待;
    10. SQL*Net more data to dblink:这个等待事件和SQL*Net more data to client 等待时间基本相同,只不过等待发生在分布式事务中,即本地数据库需要将更多的数据通过dblink发送给远程数据库;由于发送的数据太多或者网络性能问题,就会出现SQL*Net more data to dblink等待事件;
    11. 它们的等待事件参数一致:
      1. Driver id:服务器端和客户端连接使用的协议信息;
      2. #bytes:服务器端通过dblink发送给另一个服务器消息的字节数;
———————- latch free:查找事件热点对象的sql语句 ———————-
&2值是v$session_wait中的P1RAW,x$bh中的字段Hladdr表示该block buffer在哪个cache buffer chain latch上,可以通过v$latch_children定位哪些segment是热点块;
SELECT a.hladdr, a.file#, a.dbablk, a.tch, a.obj, b.object_name
FROM x$bh a, dba_objects b
WHERE (a.obj = b.object_id OR a.obj = b.data_object_id) AND
a.hladdr = &2
UNION
SELECT hladdr, file#, dbablk, tch, obj, NULL
FROM x$bh
WHERE obj IN (SELECT obj
FROM x$bh
WHERE hladdr = &2
MINUS
SELECT object_id
FROM dba_objects
MINUS
SELECT data_object_id FROM dba_objects) AND
hladdr = &2
ORDER BY 4;
———————- latch free:查找事件热点对象的sql语句 ———————-
———————- 查询引起library cache lock等待事件的阻塞者的sid,会话用户,锁住的对象的脚本 ———————-
SELECT b.sid, a.user_name, a.kglnaobj
FROM x$kgllk a, v$session b
WHERE a.kgllkhdl IN (SELECT p1raw
FROM v$session_wait
WHERE wait_time = 0 AND
event = ‘library cache lock’) AND
a.kgllkmod <> 0 AND
b.saddr = a.kgllkuse;
———————- 查询引起library cache lock等待事件的阻塞者的sid,会话用户,锁住的对象的脚本 ———————-
———————- library cache lock等待事件相关锁的查询sql ———————-
— 查询X$KGLOB,可找到相关的object,其SQL语句如下(即把V$SESSION_WAIT中的P1raw与X$KGLOB中的KGLHDADR相关连);
SELECT kglnaown, kglnaobj
FROM x$kglob
WHERE kglhdadr = (SELECT p1raw FROM v$session_wait WHERE event = ‘library cache pin’);
— 查出引起该等待事件的阻塞者的sid;
SELECT sid
FROM x$kglpn, v$session
WHERE kglpnhdl IN (SELECT p1raw
FROM v$session_wait
WHERE wait_time = 0 AND
event LIKE ‘library cache pin%’) AND
kglpnmod <> 0 AND
v$session.saddr = x$kglpn.kglpnuse;
— 查出阻塞者正执行的SQL语句
SELECT sid, sql_text
FROM v$session, v$sqlarea
WHERE v$session.sql_address = v$sqlarea.address AND
sid = < 阻塞者的sid >;
———————- library cache lock等待事件相关锁的查询sql ———————-
———————- Enqueue缩写及解释 ———————-
BL:Buffer Cache management
BR:Backup/Restore
CF:Controlfile transaction
CI:Cross-instance Call Invocation
CU:Bind Enqueue
DF:Datafile
DL:Direct Loader Index Creation
DM:Database Mount
DR:Distributed Recovery Process
DX:Dirstributed Transaction
FP:File Object
FS:File Set
HW:High-water Lock
IN:Instance Number
IR:Instance Recovery
IS:Instance State
IV:Library Cache Invalidation
JI:Enqueue used during AJV snapshot refresh
JQ:Job Queue
KK:Redo Log “Kick”
KO:Multiple Object Checkpoint
L[A-p]:Library Cache Lock
LS:Log start or switch
MM:Mount Definition
MR:Media recovery
N[A-Z]:Library Cache bin
PE:Alter system set parameter =value
PF:Password file
PI:Parallel slaves
PR:Process startup
PS:Parallel slave synchronization
Q[A-Z]:Row Cache
RO:Object Reuse
RT:Redo Thread
RW:Row Wait
SC:System Commit Number
SM:SMON
SN:Sequence Number
SQ:Sequence Number Enqueue
SR:Synchronized replication
SS:Sort segment
ST:Space management transaction
SV:Sequence number Value
TA:Transaction recovery
TC:Thread Checkpoint
TE:Extend Table
TM:DML enqueue
TO:Temporary Table Object Enqueue
TS:Temporary Segement(also TableSpace)
TT:Temporary Table
TX:Transaction
UL:User-defined Locks
UN:User name
US:Undo segment, Serialization
WL:Being Written Redo Log
XA:Instance Attribute Log
XI:Instance Registration Lock
———————- Enqueue缩写及解释 ———————-

ORACLE中工具的使用09–COPY

COPY工具的使用:

1. COPY是sqlplus中的命令;
2. 在sqlplus中通过help copy查看帮助;
3. 一个表中只能包含一个long型字段,在数据字典中大量使用了long型字段;但是包含long类型的表不能使用CTAS语法创建新表;此时可以使用copy命令;
4. 比如dba_tab_cols视图是基于cols$表的,包含了一个LONG类型,如果直接创建:CREATE TABLE tbcols AS SELECT * FROM dba_tab_cols;
5. 使用copy命令创建:copy from system/ORACLE@orcl to system/ORACLE@orcl CREATE TBCOLS USING SELECT * FROM dba_tab_cols;

——————————- COPY的帮助文档 ——————————-
SQL> help copy

COPY
—-

Copies data from a query to a table in the same or another
database. COPY supports CHAR, DATE, LONG, NUMBER and VARCHAR2.

COPY {FROM database | TO database | FROM database TO database}
{APPEND|CREATE|INSERT|REPLACE} destination_table
[(column, column, column, …)] USING query

where database has the following syntax:
username[/password]@connect_identifier
——————————- COPY的帮助文档 ——————————-

ORACLE中工具的使用07–BBED

BBED工具的使用
  1. BBED工具介绍:
    1. Oracle BBED(Oracle Block Browser and Editor)工具是Oracle内部提供的数据块级别查看和修改的工具;通过这个工具,我们可以方便的查看Oracle块级别的存储信息,从而更好的了解Oracle Internal结构技术细节;
    2. Oracle不推荐使用此工具,它只用来给内部进行恢复处理使用,对外是不提供资料和相关文档的;所以当遇到故障时,优先采用备份恢复,最后再考虑使用此工具;
    3. 只有Linux/Unix平台下提供BBED工具,在Windows平台没有对应的版本;所以使用BBED的环境通常是命令行方式,而且BBED在Oracle内部是没有编译的,需要手工编译;
  2. Oracle10g下编译BBED(适合10g以前版本):
    1. BBED对应对象文件通常在$ORACLE_HOME/rdbms/lib目录下,所以先进入此目录:cd $ORACLE_HOME/rdbms/lib;
    2. 然后使用linux系统的make进行编译和连接,生成bbed可执行文件:make -f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed;                                     
    3. 为了使用方便,添加一个硬链接:link $ORACLE_HOME/rdbms/lib/bbed $ORACLE_HOME/bin/bbed;
    4. 查看此工具:which bbed;                                                   
  3. Oracle11g下编译BBED:
    1. 11g中直接编译后报错,缺少$ORACLE_HOME/rdbms/lib/ssbbded.o,$ORACLE_HOME/rdbms/lib/sbbdpt.o,$ORACLE_HOME/rdbms/mesg/bbedus.msb和$ORACLE_HOME/rdbms/mesg/bbedus.msg等文件;                                        
    2. 因为缺少必要的库文件,所以需要从10g环境中拷贝相应的文件到对应的目录; 从10g中拷贝文件到11g对应的目录中:scp oracle@singleton10g:/u01/app/oracle/product/10.2.0/db_1/rdbms/lib/ssbbded.o $ORACLE_HOME/rdbms/lib;scp oracle@singleton10g:/u01/app/oracle/product/10.2.0/db_1/rdbms/lib/sbbdpt.o $ORACLE_HOME/rdbms/lib;scp oracle@singleton10g:/u01/app/oracle/product/10.2.0/db_1/rdbms/mesg/bbedus.msb $ORACLE_HOME/rdbms/mesg;scp oracle@singleton10g:/u01/app/oracle/product/10.2.0/db_1/rdbms/mesg/bbedus.msg $ORACLE_HOME/rdbms/mesg;                          
    3. 然后进入$ORACLE_HOME/rdbms/lib目录进行编译:cd $ORACLE_HOME/rdbms/lib;make -f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed;                              
    4. 创建链接文件并查看:link $ORACLE_HOME/rdbms/lib/bbed $ORACLE_HOME/bin/bbed;which bbed;                                                   
  4. 使用bbed工具:
    1. 工具默认的密码是blockedit;
    2. 查看bbed工具参数:bbed help=yes;                                                              
    3. 查看bbed帮助:help all;                                     
    4. 指定数据库文件列表bbed.lst,通过SELECT file# || chr(9) || NAME || chr(9) || bytes FROM v$datafile;语句查看数据库文件信息;                   
    5. 编写bbed参数文件bbed.conf;                                                               
    6. 使用bbed:bbed parfile=bbed.conf;                                              
    7. tip:修改数据块之后,Oracle会认为它是坏块,需要重新计算checksum值,然后可以使用;
  5. BBED工具使用示例:
    1. 手动把bootstrap$表中line#=-1的记录从8.0.0.0.0修改为9.0.0.0.0导致系统无法正常启动;                                       
    2. 设置数据文件列表和参数文件,打开bbed工具;
    3. 我们知道,11g中bootstrap$位于file 1 block 520,所以使用find命令从这里开始搜索(find /c 9.0.0.0.0),最终搜索到的位置为file 1 block 521 offset 8179;
    4. 设置当前位置,并导出内容:set file 1 block 521 offset 8179;dump;
    5. 将此处的9修改为8:modify /c “8” offset 8179;                                            
    6. 修改之后,Oracle会认为该块已经损坏:verify;                                               
    7. 重新计算和应用校验位后,数据块可以恢复一致:sum apply;                                             
    8. 之后数据库可以正常启动;                                                
———————————– bbed工具参数 ———————————–
PASSWORD – Required parameter
FILENAME – Database file name
BLOCKSIZE – Database block size
LISTFILE – List file name
MODE – [browse/edit]
SPOOL – Spool to logfile [no/yes]
CMDFILE – BBED command file name
LOGFILE – BBED log file name
PARFILE – Parameter file name
BIFILE – BBED before-image file name
REVERT – Rollback changes from BIFILE [no/yes]
SILENT – Hide banner [no/yes]
HELP – Show all valid parameters [no/yes]
———————————– bbed工具参数 ———————————–
———————————– bbed的帮助文档 ———————————–
SET DBA [ dba | file#, block# ]
SET FILENAME ‘filename’
SET FILE file#
SET BLOCK [+/-]block#
SET OFFSET [ [+/-]byte offset | symbol | *symbol ]
SET BLOCKSIZE bytes
SET LIST[FILE] ‘filename’
SET WIDTH character_count
SET COUNT bytes_to_display
SET IBASE [ HEX | OCT | DEC ]
SET OBASE [ HEX | OCT | DEC ]
SET MODE  [ BROWSE | EDIT ]
SET SPOOL [ Y | N ]
SHOW [ <SET parameter> | ALL ]
INFO
MAP[/v] [ DBA | FILENAME | FILE | BLOCK ]
DUMP[/v] [ DBA | FILENAME | FILE | BLOCK | OFFSET | COUNT ]
PRINT[/x|d|u|o|c] [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ]
EXAMINE[/Nuf] [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ]
</Nuf>:
N – a number which specifies a repeat count.
u – a letter which specifies a unit size:
b – b1, ub1 (byte)
h – b2, ub2 (half-word)
w – b4, ub4(word)
r – Oracle table/index row
f – a letter which specifies a display format:
x – hexadecimal
d – decimal
u – unsigned decimal
o – octal
c – character (native)
n – Oracle number
t – Oracle date
i – Oracle rowid
FIND[/x|d|u|o|c] numeric/character string [ TOP | CURR ]
COPY [ DBA | FILE | FILENAME | BLOCK ] TO [ DBA | FILE | FILENAME | BLOCK ]
MODIFY[/x|d|u|o|c] numeric/character string
[ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ]
ASSIGN[/x|d|u|o] <target spec>=<source spec>
<target spec> : [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ]
<source spec> : [ value | <target spec options> ]
SUM [ DBA | FILE | FILENAME | BLOCK ] [ APPLY ]
PUSH [ DBA | FILE | FILENAME | BLOCK | OFFSET ]
POP [ALL]
REVERT [ DBA | FILE | FILENAME | BLOCK ]
UNDO
HELP [ <bbed command> | ALL ]
VERIFY [ DBA | FILE | FILENAME | BLOCK ]
CORRUPT [ DBA | FILE | FILENAME | BLOCK ]
———————————– bbed的帮助文档 ———————————–
———————————– bbed参数文件 ———————————–
BLOCKSIZE=8192
LISTFILE=bbed.lst
MODE=EDIT
PASSWORD=blockedit
LOGFILE=bbed.log
———————————– bbed参数文件 ———————————–

MySQL学习9–MySQL5.1的备份恢复

使用mysqldump工具备份
  1. mysql client is a backup program,it can be used to dump a database or a collection of databases for backup or for transferring the data to another SQL server(not necessarily a mysql server).The dump contains Sql statements to create the table or populate it, or both;
  2. 它可以导出所有的数据库,指定的一个或者几个数据库,或者一张表;
  3. mysqldump可以备份本地的或者远程的服务器,导出的文件包含CREATE TABLE和INSERT语句用于重新创建表,服务器发送表内容到mysqldump程序,它把文件写到客户端;
  4. 它可以备份各种引擎的表;
  5. 导出的文件是文本文件,所以有很强的灵活性,可以被用于在不同的服务器上;
mysqldump的参数
  1. -A,–all-databases:导出所有的数据库,跟使用–databases后面跟上所有的数据库是一样的;
  2. –add-drop-database:在创建数据库前添加drop database的语句;
  3. –add-drop-table:在创建表之前添加drop table语句;
  4. –add-locks:在插入语句前加锁;
  5. –allow-keywords:创建的列允许使用关键字;
  6. -i,–comments:写入附加信息,即添加注释;
  7. -c,–complete-insert:使用完全插入语句,个人觉得还是-e参数好,数据量小用-e,数据量大用-c;
  8. -B,–databases:备份多个数据库,把要备份的数据库跟在参数后面即可,当前数据库也会被包涵进来;
  9. –delete-master-logs:备份完成后删除主机日志,自动打开–master-data选项;
  10. -e,–extended-insert:使用multiple-row INSERT语句,即一个insert语句后面有多个值的列表,这是一种更高效的插入方式;
  11. -F,–flush-logs:开始备份前切换一下日志,如果你一次备份多个数据库(使用–databases或者–all-databases选项时),则在备份每个数据库前都会切换日志.当使用–lock-all-tables or –master-data时,日志只会被切换一次,因为此时所有的表都被锁住,数据库保持一致.所以当你想要备份和日志组切换同时发生时,要用–lock-all-tables or –master-data和–flush-logs一起使用;
  12. -h,–host=name:连接到主机;-u,–user-name:用户名;-p,–password:用户密码;
  13. –ignore-table=name:不备份指定的表,如果要指定多个表,则要数据库和表明一起指定,如:–ignore-table=database.table;
  14. -x,–lock-all-tables:会锁住所有数据库的表,会在备份期间加全局只读锁,自动关闭–single-transaction和–lock-tables选项;
  15. –master-data[=#]:使得二进制日志的位置和和名称被添加到输出文件中,如果等于1,会像CHANGE MASTER命令一样打印它,如果等于2,命令会以注释的形式出现.这个选项会打开–lock-all-table选项,除非–single-transaction选项也被指定(此时全局只读锁知会在开始备份时有效),可以通过show master status命令查看当前日志信息,在恢复和复制功能时有用.
  16. -n,–no-create-db:不包括创建数据库的语句;
  17. -t,–no-create-info:不包括创建表结构语句;
  18. -d,–no-data:只包含表定义,不包含表数据;
  19. –order-by-primary:使每个表中的记录按照主键排序,如果没有主键,则使用第一个唯一索引.当导出一个MyISAM表到一个InnoDB表时有用,但是会延长导出时间;
  20. –quick:不缓存query,直接导出到标准输出;
  21. -R,–routines:导出stored routines(存储过程和函数);
  22. –single-transaction:在一个事务中创建一个一致性的快照,只在支持多版本控制的引擎中起作用,目前只有innodb引擎.当–single-transaction进程工作时,为了保持数据一致性,则不能使用ALTER TABLE,DROP TABLE,RENAME TABLE,TRUNCATE TABLEY语句,此选项自动关闭–lock-tables选项;
  23. –opt:与同时指定–add-drop-table, –add-locks, –create-options, –quick, –extended-insert, –lock-tables, –set-charset, and –disable-keys相同.默认开启,要关闭使用–skip-opt;
  24. -w,–where=name:只导出选择的记录;
如何使用mysqldump备份
  1. 非事务表的一致备份:mysqldump –opt –lock-all-tables –master-data=2 -B db_name1 db_name2 > /tmp/backup.sql,备份时表是只读的;
  2. 事务表的一致备份:mysqldump –opt –single-transaction –master-data=2 -B db_name1 db_name2 > /tmp/backup.sql,备份时表是可读写的;
mysqlbinlog工具
  1. 服务器生成的binary log files是二进制文件,想要查看这些文件,必须使用mysqlbinlog工具.还可以使用mysqlbinlog工具读取复制功能slave服务器产生的relay log files,它和二进制日志有相同的结构;
  2. 用法:mysqlbinlog [options] log-files;
mysqlbinlog的参数
  1. -d,–database=name:列出某一个数据库的日志,只用于本地日志;
  2. -f,–force-read:如果mysqlbinlog读到它不能识别的二进制日志,会打印警告而忽略该事件并继续,如果没有该事件则停止;
  3. -o,–offset=#:忽略前N个实体;
  4. -R,–read-from-remote-server:从远程服务器读取二进制日志,如果没有指定此选项,则–host, –user, –password, –port, –protocal, –socket选项都被忽略;
  5. -r,–result-file=name:直接输出到给定的文件;
  6. –start-datetime=time:读取二进制日志的生成开始时间,可以使用任何mysql服务器的时间格式,datetime和timestamp类型,如:’YYYY-MM-DD HH24:MI:SS’;
  7. –stop-datetime=time:读取二进制日志的生成结束时间;
  8. -j,–start-position=#:读取二进制日志的生成开始位置,是一个整型参数;
  9. –stop-position=#:读取二进制日志的生成结束位置,一个整型参数;
  10. -t,–to-last-log:在mysql服务器中请求的二进制日志结尾处不停止,而是继续打印直到最后一个二进制日志的结尾,如果将输出发送给同一台mysql服务器,会导导致无限循环,要与–read-from-remote-server连用;
  11. -D,–disable-log-bin:禁用二进制日志,如果使用–to-last-logs选项将输出发送给同一台mysql服务器,可以避免无限循环,该选项在崩溃恢复也很有用,可以避免复制已经记录的语句;
binlog解读
  1. 二进制日志记录的方式与binlog_format参数有关;
  2. 查看binlog的语法:? binlog;
  3. 记录的内容有:时间戳, 主机server id, 时间结束位置, 时间对象, 时间标志位, 内部binlog命令和相关注释;
mysql数据库的备份与恢复
  1. 只备份routines(存储过程和函数,-R参数,在information_schema.routines表中)和events(作业,-E参数,在information_schema.events表中)信息:mysqldump -n -t -d -R -E > /tmp/routines.sql;
  2. 备份表结构,视图,函数,存储过程和作业的信息:mysqldump -d -R -E -S /mysql/logs/mysqld.sock –databases db_name > /tmp/objects.sql;
  3. 备份数据库test,包括视图信息:mysqldump –opt –lock-all-tables -R -E –master-data=2 -B test > /tmp/test_backup.sql;(查看当前二进制日志的名称和位置:show master logs;);                                                       
  4. 对表进行修改,然后删除:
    1. insert into t values(1, now());
    2. insert into t values(2, now());
    3. insert into t values(3, now());
    4. drop table t;
  5. 查看表删除的位置:mysql>show binlog events;如果要查询某一个日志文件中的内容使用:show binlog events in ‘binlog file name’;                     
  6. 查看表备份文件的位置:grep “CHANGE MASTER” /tmp/test_backup.sql;                           
  7. 还原数据库:mysql < /tmp/test_backup.sql;直接执行备份的脚本文件,还原到备份的状态;
  8. 恢复数据库(注意mysqlbinlog的版本,应该使用mysql basedir下的mysqlbinlog):mysqlbinlog –start-position=117 –stop-position=480 /path/mysql-bin.000001 | mysql; 可以使用–disable-log-bin:禁用二进制日志;                                                   
  9. 建议把备份的数据库恢复到测试服务器,然后把数据导入到生产环境;
表结构的复制
  1. 第一种做法是:CREATE TABLE table_name AS SELECT * FROM tb_name;
    1. 可以复制表接口和表中数据,如果只想要表接口可以加一个false的过滤;
    2. 但是会丢失表中列上面的属性(如自增属性)和索引(主外键);
  2. 第二种做法是:CREATE TABLE table_name(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY) SELECT * FROM table_name;
    1. 可以在创建表时指定所有的属性,并同步数据;
    2. 但是语法太麻烦;
  3. 第三种做法是:CREATE TABLE table_name LIKE table_name;
    1. 只复制表结构,而且保留列的属性和索引;
    2. 如果想要数据的话可以INSERT table_name SELECT * FROM table_name;

MySQL学习8–MySQL5.1的用户管理

用户管理:我们可以定义一个account访问和控制mysql服务器.在MYSQL服务器中,account包含两部分,用户名和主机名.也就是说,当连接到服务器时,除了要检查用户名还要检查连接进来的主机.一个隐式的概念就是说用户名相同但是主机名不同的account是不同的account;
Mysql可以支持的权限类型
  1. 管理权限
    1. CREATE TEMPORARY TABLES:创建临时表;
    2. CREATE USER:创建/删除/重命名账户;
    3. FILE:在sql语句中读写操作系统的文件;
    4. LOCK TABLES:锁表;
    5. PROCESS:查看进程的活动状态;
    6. RELOAD:重新加载,FLUSH OR RESET;
    7. REPLICATION CLIENT:作为复制功能的主机;
    8. REPLICATION SLAVE:作为复制功能的备机;
    9. SHOW DATABASES:查看数据库名称;
    10. SHUTDOWN:关闭服务器;
    11. SUPER:各种管理操作;
  2. 数据访问权限
    1. ALTER:修改表结构,alter table;
    2. ALTER ROUTINE:修改或者删除存储过程和函数;
    3. CREATE:创建数据库或者表;
    4. CREATE ROUTINE:创建存储过程或者函数;
    5. CREATE VIEW:创建视图;
    6. DELETE:删除表中数据;
    7. DROP:删除数据库或者表;
    8. EXECUTE:执行函数或者过程;
    9. GRANT OPTION:授权给其它账户;
    10. INDEX:创建/删除索引;
    11. INSERT:向表中插入记录;
    12. SELECT:查询表的记录;
    13. SHOW VIEW:查看视图定义,show create view;
    14. UPDATE:更新表的记录:
  3. 特殊的权限
    1. ALL and ALL PRIVILEGES:即’all privileges except grant option’,授予账户除了把权限赋予其它帐号外的所有权限;
    2. USAGE:即没有任何权限,但是它可以连接到数据库上,也在user表中生成一条记录.这类账户的存在就是为了执行向’show variables’ or ‘show status’这类的语句,也不能查看表的内容;
  4. 权限的级别
    1. 所有的权限都可以被授予全局的,一个账户拥有全局权限,它可以在任何数据库任何时间使用此权限.一般只授予管理员这样的权限;
    2. 一些权限可以被授予特定的数据库:ALTER, CREATE, CREATE TEMPORARY TABLES, CREATE VIEW, DELETE, DROP, GRANT OPTION, IDEX, INSERT, LOCK TABLES, SELECT, SHOW VIEW and UPDATE.一个数据库级别的权限可以应用于所有的tables和routines;
    3. 一些权限可以被授予特定的表:ALERT, CREATE, DELETE, DROP, GRANT OPTION, INDEX, INSERT, SELECT and UPDATE.一个标记别的权限可以应用于表中所有的列;
    4. 一些权限可以被授予表中的列:INSERT, SELECT and UPDATE;
    5. 一些权限可以被授予函数和存储过程:EXECUTE, ALTER ROUTINE and GRANT OPTION;
授权表
  1. 在mysql数据库中有几张授权表包含了服务器大部分的访问控制信息,它们包含了哪些是合法的账户和这些账户拥有的访问级别的信息;
  2. user:每一个账户在user表包含一条记录,它记录了用户拥有的全局的权限,也包含了一些其它信息,比如:使用资源的限制,客户端连接进来是否需要使用SSL链接;
  3. db:列出了账户对指定数据库的权限;
  4. tables_priv:列出了账户对指定表的权限;
  5. columns_priv:列出了账户对指定列的权限;
  6. procs_priv:列出了账户对存储过程和函数的权限;
  7. 服务器使用授权表中的信息决定是否允许客户端连接进来,也决定了客户端是否有权限执行某些语句,mysql服务器每次启动时都把授权信息载入到内存,以加快读取权限的速度,在一下两种情况下会刷新权限表的内存拷贝:
    1. 使用CREATE USER, GRANT, REVOKE or SET PASSWORD语句修改磁盘上的账户信息;
    2. 也可以显式的重新加载这些表使用FLUSH PRIVILEGES语句,执行mysqladmin flush-privileges or mysqladmin reload命令;
管理用户
  1. 查看当前的用户:
    1. select user();
    2. select current_user();
    3. show grants:查看当前用户权限信息;
    4. show grants for ‘user’@’host’:查看某个用户的权限信息;
    5. show processlist:查看当前连接进来用户的信息;
  2. create user创建一个用户(可选的指定密码,不指定的话为null),这个语句在user表中创建一条记录.它没有授予任何权限,可以之后使用grant语句.eg:create user ‘user’@’host’ identified by ‘password’;
  3. drop user回收一个账户的所有权限,并且删除这个账户.这会删除所有授权表中跟这个账户有关的信息,如果要收回用户权限而不删除用户要使用revoke语句.eg:drop user ‘user’@’host’;
  4. rename user改变一个现有账户的用那个户名,可以修改用户名或者主机名的任意一部分,或者两部分都修改.eg:rename user ‘user’@’host’ to ‘user’@’host’;
  5. 创建一个匿名账户,不需要用户名和密码即可登录,比较危险.eg:insert into user(host, user, password) values(‘%’, ”, ”);
  6. 修改用户的密码:set password for ‘u1’@’%’=password(‘u1’);
  7. 授权语句:grant privileges on objects to ‘user’@’host’ identified by ‘password’;
    1. on *.*:全局权限,所有的对象,eg:grant all privileges on *.* to ‘u1’@’%’ identified by ‘u1’ with grant option;
    2. on db_name.*:对数据库的权限,eg:grant select, update on test.* to ‘u1’@’localhost’;
    3. on db_name.tbl_name:数据库中表的权限,eg:grant select on mysql.user to ‘u1’@’localhost’;
    4. on db_name.tbl_name.col_name:数据库中表的列的权限,eg:grant select(host, user) on mysql.user to ‘u1’@’%’;
    5. on db_name.routine_name:数据库中routine的权限;
  8. 要添加用户并授权一般使用:grant 权限1,权限2,… on 数据库.表 to “username”@”host” identified by “password”;(创建用户的同时授予权限)
    1. grant all privileges on *.* to “user1″@”%” identified by “pwd”:表示对user1授予所有数据库中所有表的所有权限,并可以从任意客户端连接进来;
    2. grant select,insert,delete,update on mysql.user to “user1″@”192.168.0.1” identified by “pwd”:表示对用户user1授予mysql数据库的user表增删改查权限,并且只能从192.168.0.1客户端连接进来;
    3. host列为%表示可以从任意的客户端连接到服务器端;
    4. 一般在开发的时候使host为%,在生产环境修改host的地址;
  9. 回收权限:revoke prilileges on objects from ‘user’@’host’;
    1. 回收全局权限:revoke all privileges, grant option from ‘u1’@’%’;
    2. 回收数据库的权限:revoke select, grant option on mysql.* from ‘u1’@’%’;
    3. 回收表的权限:revoke select on mysql.user from ‘u1’@’%’;
    4. 回收列的权限:revoke select(host, user) on mysql.user from ‘u1’@’%’;
  10. 限制用户资源:默认情况下对客户端连进来的次数,查询次数等资源没有限制,grant语句可以对账户以下几个方面的资源做限制:
    1. 每个小时允许连到服务器的次数:max_connections;
    2. 每个小时允许查询的次数:max_questions;
    3. 每个小时允许更新的次数:max_updates;
    4. 用户的并发连接数:max_user_connections;
    5. 语句:grant all privileges on *.* to ‘u1’@’%’ identified by ‘u1’ with max_queries_per_hour 10 max_updates_per_hour 5 max_connections_per_hour 5 max_user_connections 8;
  11. 忘记用户密码
    1. Linux中的处理方法:
      1. 关闭服务器或者kill掉mysqld的进程;
      2. 使用–skip-grant-tables选项登录,启动服务器并跳过授权表
      3. 使用mysql登录,可以不用使用用户名和密码,并且有全部权限;
      4. 登录之后修改密码(set password for u1@’%’=password(‘pwd’)),或者直接更新mysql.user表密码字段为空即可;
    2. Windows中的处理方法:
      1. 停止mysql的服务:net stop mysql;
      2. 到mysql的bin目录下执行mysqld -nt –skip-grant-tables;
      3. 到新的命令行下执行mysqladmin -uroot flush-privileges password ‘pwd’;
      4. 然后关闭mysql服务:mysqladmin -uroot -p shutdown,此时输入刚刚设置的密码;
      5. 启动mysql服务:net start mysql;

MySQL学习7–MySQL5.1的存储引擎

MySql Storage Engines

  1. 存储引擎的概述
    1. MySql服务器管理的表都有一些相似之处:比如,数据库中每一个表在数据库目录都有一个format file(.frm),这个文件存储着表定义的结构,他是由服务器创建;
    2. 这些表也有一些不同之处:就是可以使用不同的存储引擎去管理表.每个存储引擎都有一系列的特点.比如每一个引擎都会创建一个额外的和.frm文件相对应的磁盘文件去管理数据和索引的存储.每个存储引擎也都会有自己的特点,比如有的会使用锁去管理查询竞争,有的会提供事务而有的没有事务.这些存储引擎属性都影响着查询的性能,并发和预防死锁.
  2. 如何使用CREATE TABLE语句显式指定存储引擎
    1. 查看CREATE TABLE的语法:? CREATE TABLE;
    2. 指定存储引擎:CREATE TABLE t (id integer) ENGINE=engine_name;
    3. 查看表使用了哪种引擎:
      1. 查询表结构:show create table table_name \G;
      2. 查询表信息:show table status like ‘table_name’ \G;
      3. 查询表所在数据库中所有表的信息:show table status from db_name \G;
      4. information_schema数据库存放了数据库的架构信息,可以查询tables表获得表的信息:use information_schema;select * from tables where table_name = ‘table_name’ \G;
    4. 查看服务器上支持的存储引擎
      1. show engines;
      2. show variables like ‘hava%’;
  3. MyISAM
    1. 在硬盘上MyISAM引擎用三种文件管理表,这些文件都在数据目录中
      1. .frm文件:存储表结构的定义;
      2. .MYD文件:存储表行的内容;
      3. .MYI文件:存储表的索引;
    2. 在操作系统上支持链接文件的特性,可以把数据文件和索引文件存放在不同的磁盘上以减小I/O;
      1. 查看当前服务器指定的默认存储引擎:show variables like ‘storage_engine’;
      2. 通过查看CREATE TABLE的帮助(? CREATE TABLE),我们可以看到,可以通过指定DATA DIRECTORY和INDEX DIRECTORY选项来把数据文件和索引文件存放在不同的目录;
        1. 创建存放数据文件和索引文件的目录:mkdir -p /tmp/mysql/data /tmp/mysql/index;
        2. 修改文件的权限:chown -R mysql:mysql /tmp/mysql;
        3. 创建表,并指定数据文件和索引文件的目录:CREATE TABLE t (id INTEGER) ENGINE=MyISAM DATA DIRECTORY=’/tmp/mysql/data’ INDEX DIRECTORY=’/tmp/mysql/index’;
        4. 此时就会在数据文件下创建真正数据文件和索引文件的链接;
        5. 有没有参数可以指定缺省的目录,每次创建表都去指定太费劲了吧;??????
        6. 分区表指定数据文件和索引文件;???????
    3. MyISAM与其它引擎相比具有最灵活的AUTO_INCREMENT COLUMN功能,自动增长列;
      1. 创建自动增长列:create table t(id integer auto_increment primary key, name varchar(50));
      2. 使用自动增长列(auto_increment),此列必须是主键或者是主键中的一列;
      3. 插入时可以指定id列也可以不指定,如果指定的话就插入指定的值,如果不指定则插入比当前最大值大1的值,即max(id)+1;
      4. 获得上次插入的id值使用last_insert_id()函数:select last_insert_id();
      5. 设置自动增长id的初始值:alter table table_name auto_increment=n;但是如果这是的n小于max(id)则不生效;
      6. 为一个已存在的表增加一个自增长列:alter table table_name add column col_name integer auto_increment not null, add primary key(id);
    4. 不支持事务
      1. 查看自动提交事务的选项:show variables like ‘autocommit’;
      2. 修改此选项:set session autocommit=0|1;
      3. 因为不支持事务,所以不管此选项为何值,都不能commit和rollback;
    5. MyISAM的表可以被转换成一个fast,compressed,read-only的表从而节省空间
      1. 使用myisampack工具:mysqlpack –help;
      2. 进入到数据文件目录:myisampack table_name;                                                          
      3. 观察发现压缩比例为90%,只剩下10%的数据量大小;对指定DATA DIRECTORY和INDEX DIRECTORY选项的表同样使用,亲测;
      4. 重启之后检测表(check table table_name)就会发生错误,表内数据丢失,对只读的性能支不好,如果使用的话,压缩完之后一定要备份;
    6. MyISAM支持FULLTEXT索引和spatial数据类型,全文索引和空间数据类型
      1. 对全文索引支持不够好,可以使用instr()函数去实现;
      2. 也可以使用第三方的插件去实现;
    7. MyISAM引擎对锁的支持
      1. MySql管理使用MyISAM引擎的表之间的查询竞争使用表级的锁,这使得查询的性能非常快,多个查询可以同时访问一张表.对于写操作,会使用一个exclusive的表级锁去阻止其它读写操作.虽然表级锁会影响点性能,但是不会发生死锁;
      2. 显式的对表加锁:lock table table_name lock_type; lock tables table_name1 lock_type, table_name2 lock_type;
      3. 解锁:unlock tables;
      4. 如果在session中加write锁,则本session可以进行读写操作,其它的session对表进行读和写就需要等待锁释放;
      5. 如果在session中加read锁,则本session和其它session都可以进行读操作,本session无法进行写操作,其它的session对表进行读和写就需要等待锁释放;
      6. 如果在session中加read local锁,即只锁住加锁前一时刻的表的数据,则本session可以进行读操作(查到的只是加锁前的数据),但是不能进行写操作,其它session可以进行插入操作(查到的是所有的数据),但是删除和更新操作需要等待锁释放;
    8. 可以通过LOW_PRIORITY和HIGHT_PRIORITY来影响MyISAM表的内部调度机制;可以通过INSERT DELAYED先把表中数据缓存到服务端,等到表不忙的时候再插入;
      1. 一般情况下在OLTP系统中,更新操作优先于查询操作,因为更新操作时间比较短,查询操作时间比较长(所以一般要提升查询操作的优先级,降低更新操作的优先级);要修改查询的优先级使用:SELECT HIGH_PRIORITY * FROM t;修改更新语句的优先级使用:INSERT INTO t VALUES(1);可以使用read local锁做实验,优先级低的无法插入,优先级高可以插入;
      2. 数据延迟插入:INSERT DELAYED INTO t VALUES(1);可以使用write锁来模拟这种情况,不实用delayed则等待,使用就马上返回成功,但是真正插入要等表不忙的时候;当有延迟操作时会产生一个延迟进程,它是一个共用的线程,只有一个;
      3. 查看当前链接到服务器的进程列表:show processlist;杀掉进程:kill id;
      4. 与延迟插入有关的全局变量:show global variables ‘%delayed%’;
        1. delayed_insert_limit:延迟插入时,插入多少条数据后检查是否有查询操作,如果有查询操作,则查询操作先执行;
        2. delayed_insert_timeout:限制延迟操作的等待时间;
        3. delayed_queue_size:定义延迟线程队列的大小,以行为单位;
      5. 与延迟插入有关的全局状态:show global status ‘%delayed%’;
        1. delayed_errors:记录延迟插入错误的次数;
        2. delayed_insert_threads:当前有多少线程在使用延迟操作;
        3. delayed_writes:使用延迟线程插入的记录行数;
    9. 数据表的存储格式是非常的轻便的,因此可以通过直接拷贝表所在的目录到其它的主机以实现对表的备份额迁移
      1. 拷贝时需要注意文件的权限和拥有者,一般指定cp -a选项;
      2. 拷贝表时可能会有缓存,最好能在关闭服务器的情况系进行,以保证数据完整性;(岂不是保障不了高可用性了?)
    10. 可以指定一个MyISAM表最少存储多少条记录,这允许MyISAM表去调整表内部行指针的大小,也可以配置缺省的表内部行指针大小供服务器使用
      1. 在创建表时使用MAX_ROWS和MIN_ROWS选项(? CREATE TABLE),这个值只是一个参考值,实际的数据行数可以大于也可以小于这个值;
      2. 配置系统默认大小使用myisam_data_pointer_size选项:show variables like ‘myisam_data_pointer_size’,这个选项是当创建表时没有使用MAX_ROWS选项时使用,默认为6,不能小于2也不能大于7.它代表可以用几个字节(一个字节是8位)去寻址,指定n,表示2的8n次方,即指定为2,3,4,5,6时依次代表可以存放64K,16M,4G,1T,256T的数据;
      3. 把max_rows设为5,myisam_data_pointer_size范围是2~7,2个字节就足够了(2^16),所以其实就是让myisam是用2个字节的指针,并不是说最多5行.如果把max_rows设置为大于2^16的值,就要用3个字节表示,所以myisam_data_pointer_size会设为3,此时最多存放2^24行.
      4. 如果创建表时指定了max_rows,那么表至受限于最大的行数;如果没有max_rows,则表受限于最大大小;
    11. 导入数据时,可以先禁用掉索引,等到导入数据后再打开索引,这样会加快导入数据的速度.当使用LOAD DATA [LOCAL] INFILE导入数据时,它会自动的禁用和启用索引,以加快导入速度
      1. 查看LOAD DATA [LOCAL] INFILE的帮助:? load data; load data [local] infile file_name into table table_name;
      2. 与LOAD DATA INFILE相对应的是SELECT … INTO OUTFILE,把表中的数据导入到文件中;
      3. 语法:select * from t into outfile ‘/tmp/t.txt’ fields terminated by ‘,’ enclosed by ‘”‘; 字段以[“]包围,字段之间以[,]号分割,默认每行之间以换行分割;
      4. 语法:load data infile ‘/tmp/t.txt’ into table t fields terminated by ‘,’ enclosed by ‘”‘;
    12. 向MyISAM表中添加数据时,如果磁盘空间不足时服务器会挂起操作,直到空间变为可用状态,然后继续完成操作;
    13. MyISAM表的行存储格式
      1. 查看表使用哪种行存储格式:与查看表使用引擎的方式一样,表信息的Row_format字段.
        1. 表中包含有可变长度的列,则表就是Dynamic的;
        2. 表中没有包含可变长度的列,表就是Fixed的;
      2. 固定行存储格式:
        1. 所有的行有固定的大小;
        2. 行存储的位置是在行长度的整数倍的位置,方便查找;
        3. 占用更多的存储空间;
      3. 动态行存储格式:
        1. 行占用动态的长度;
        2. 查看起来不是很高效;
        3. 节省空间;
        4. 更容易产生碎片;
      4. 压缩行存储格式:
        1. 表被压缩以节省空间;
        2. 优化的存储以加快检索;
        3. 表是只读的;
      5. 做实验时可以使用hexdump工具,查看数据文件中实际存放的数据,可以加上-C选项;
      6. 手动像数据表文件中添加数据后不可用,需要经历check table table_name; optimize table table_name; repair table table_name;三个过程,应该是在information_schema库中写入统计信息;
  4. InnoDB
    1. 每一个InnoDB的表在磁盘的数据目录下都有一个.frm文件和存储数据和索引的表空间,InnoDB的表空间是一个逻辑的单存储区域,这个区域由一个或者多个文件组成,还可以使用裸分区.缺省情况下,一个InnoDB的表空间存放所有的InnoDB的表的内容,这种表空间的存储是与机器无关的,根据此特性,我们可以把InnoDB表空间拷贝到其它机器上完成备份和迁移.单个表的最大尺寸可以达到操作系统支持的最大大小.同样可以配置InnoDB使得每个表使用单独的表空间(innodb_file_per_table);
      1. InnoDB引擎的操作需要主要需要两块磁盘资源,一个表空间用来存放数据和索引,一系列的日志文件用来记录当前活动的日志;
      2. 每个InnoDB表都有一个.frm文件,这一点与其它的存储引擎相同.然而不同的是,InnoDB存储数据和索引在共享表空间,这是一个或者多个单独的逻辑存储区域,所有的InnoDB表都存储在一个表空间中.这个表空间也包含一个rollback节,事务修改记录的信息和undo日志信息都存储在这个节中,这些信息用于回复失败的事务;
      3. 在共享表空间的文件可以设置为自动增长,因为共享表空间保存着所有数据库中所有的InnoDB表,所以共享表空间文件默认存放在服务器的数据目录下,而不是某一个数据库目录下;
      4. 如果不想使用共享表空间存储表的内容,可以打开innodb_file_per_table选项,这样,对于每一个InnoDB表都会生成一个.idb的文件存放数据和索引和一个.frm文件保存表结构.但是共享表空间仍然是必须的,因为它要保存InnoDB的数据字典和rollback节.使用此选项不影响以前创建在共享表空间中的表;
    2. InnoDB引擎支持事务,可以使用commit和rollback,它遵循ACID机制,由于多版本控制(Multi-versioning),每个事务之间是互补影响的;
      1. ACID
        1. Atomic:整个事务事务中的所有的操作要不全都成功,要不全都取消;
        2. Consistent:在事务开始之前和事务结束以后,数据的完整性约束没有被破坏;
        3. Isolated:两个事务的执行是互不干扰的;
        4. Durable:事务完成以后,该事务对数据库所有的操作便持久的保存在数据库中,不会被回滚;
      2. 事务模型
        1. 显式的关闭自动提交功能:set autocommit=0;
        2. 开启一个事务:start transaction;
    3. 当MySql服务器或者主机crash之后,InnoDB提供了自动回复机制;
    4. MySql管理InnoDB的查询竞争使用多版本控制和行级锁,多版本控制是的每个事务都有一个单独是数据库界面;而行级锁使得查询竞争减小到最小,这使得多查询写入的时候效率最高,但是会导致死锁;
    5. InnoDB支持外键和引用完整性,包括级联删除和更新;
      1. 使用外键的两个表都必须是InnoDB的表,而且不能是临时表;
      2. 在父表中,被引用的列必须是键.在字表中作为外键的列必须是索引或者是组合索引的第一个,如果他不存在,在创建索引的时候会自动被创建;
      3. 使用外键的列不支持索引前缀;
      4. 如果使用CONSTRAINT子句时,要保证对象名是全局唯一的;
      5. 查看索引:show index from table_name \G;
    6. 数据表的存储格式是非常的轻便的,因此可以通过直接拷贝表所在的目录到其它的主机以实现对表的备份额迁移;
    7. 配置一个InnoDB表空间
      1. 它包含一个或者多个文件;
      2. 表空间中的内个组件可以是一个一般的文件或者是裸设备,或者是两种文件都有;
      3. 表空间文件可以在不同的文件系统或者是物理磁盘上.这样使用的一个原因是使用分布式系统;
      4. 表空间的大小可以超过文件系统支持的最大文件大小,主要是有两个原因
        1. 表空间由一个或者多个文件组成,因此大于一个单独的文件;
        2. 表空间可以包含裸设备,它不受限于文件系统的大小,可以使用裸设备的所有的extent;
      5. 表空间的最后一个文件可以自动增长,也可以定义文件的增长大小;
      6. 指定配置文件中的innodb_data_file_path参数(通过show variables like ‘innodb_data_file_path’);
        1. 默认路径下指定:[innodb_data_file_path=ibdata1:10M;ibdata2:10M:autoextend]两个文件之间用[;]分割,最后一个文件可以指定自动增长;
        2. 指定InnoDB的路径:innodb_data_home_dir指示数据文件的路径,缺省是在数据目录下面,innodb_log_group_home_dir指示日志文件的路径;
    8. 配置InnoDB的缓冲区:InnoDB使用一个缓冲池去存放经常读取的物理表的信息,目的是为了减小IO,缓冲池越大越好.可以使用innodb_buffer_pool_size参数改变缓冲池的大小.
      1. innodb_buffer_pool_size:定义了在内存中缓存表和索引的大小,这个值越大,访问硬盘的IO越小.在一个专用的数据库服务器中,你可以设置它的大小为物理内存的80%,当然也不能设置的过大,否则就会使用到交换分区;
      2. innodb_additional_mem_pool_size:表示存放数据字典和其它数据表结构的信息的大小.表越多,这个空间分配的要越大.如果这个空间大小不够的话,就会从操作系统申请空间,并在error log中记录警告信息;
      3. innodb_max_dirty_pages_pct:配置dirty page的百分比,默认为75,当脏数据超过这个值的时候,进程就会把这些页从缓冲池写入到硬盘上;
      4. 查看innodb的状态变量show golbal status like ‘innodb_%’;innodb_page_size:是每一页的大小,一般为16k;Innodb_buffer_pool_pages_total:是一共有的页数;
  5. Merge
    1. MERGE表是一组MyISAM表的集合,每一个MERGE表在磁盘上都有2个文件,一个是.frm文件和一个包含组成MERGGE表的MyISAM表的名称的.MRG文件.这两个文件都存放在数据库目录下;
    2. 当对一个MERGE表操作时,相当于对组成MERGE表的所有的MyISAM表的操作;
    3. 一个MERGE表可以突破MyISAM表的最大大小的限制;
    4. MYSQL管理MERGE表的查询竞争使用表级锁,即锁住组成它的MyISAM表,所以不会产生死锁;
    5. 一个MERGE表是很轻便的,因为.MRG文件是一个文本文件;
    6. 可以进行增删改查操作,在插入操作时可以指定是往哪个表中插入数据;
    7. 当MERGE引擎要锁住一个MERGE表时,就会对组成它的所有MyISAM表加锁;
    8. 对MERGE表执行SEELCT操作时,对底层的表加read lock;
    9. 对MERGE表执行更新操作(delete, update)时,对底层的表加write lock;
    10. 对MERGE表的操作:
      1. 创建MyISAM表m1:create table m1(id int, name varchar(10)) engine=myisam;
      2. 创建MyISAM表m2:create table m2(id int, name varchar(10)) engine=myisam;
      3. 创建MERGE表:create table m(id int, name varchar(10)) engine=merge union=(m1, m2);
      4. 插入数据:insert into m1 values(1, ‘a’);insert into m1 values(1, ‘a’);
      5. 查询:select * from m;
      6. 创建MyISAM表m3:create table m3(id int, name varchar(10)) engine=myisam;
      7. 加入merge表:alter table m union=(m1, m2, m3);很灵活,可以互相组合;
      8. 修改表使得merge表可以插入数据,create table m(id int, name varchar(10)) engine=merge union=(m1, m2) insert_method=last;method_method=0:不允许插入;first:插入到union中的第一个表;last:插入到union中最后一个表;
    11. 可以通过直接修改.MRG文件来修改MERGE表,修改后使用flush tables;来刷新表缓存;
  6. Memory
    1. MEMORY表的.frm文件在数据库目录下,数据和索引都存储在内存中;
    2. 对MEMORY表的操作性能都很高;
    3. 在服务器重启之后,MEMORY表中的数据就不存在了,但是他的表结构还是存在的;
    4. 因为MEMORY表使用的是内存,所以不适用于大表;
    5. MEMORY表使用表级锁来处理查询竞争,所以不会发生死锁;
    6. MEMORY表不支持TEXT和BLOB类型;
    7. 它支持两种索引:HASH和BTREE
      1. 缺省使用HASH索引,这种索引算法使用唯一索引会非常高效,然而HASH索引只能用于比较运算符(=, <>);
      2. BTREE索引算法更适合于范围查找,例如>,<或者between;
    8. 可以使用创建表时的max_rows和服务器参数max_heap_table_size来限制MEMORY表的大小;
    9. 设置索引:
      1. hash:alter table table_name add index idx_name using hash(col_name);
      2. btree:alter table table_name add index idx_name using btree(col_name);
    10. 当不需要MEMORY表的内容时,要释放被MEMORY表使用的内存,使用DELETE FROM, TRUNCATE TABLE或者删除整个表DROP TABLE;
  7. Federated
    1. 它访问的是在远程数据库表中的数据,而不是本地的表,仅在-MAX版的MySql可用;
    2. 如果要使用需要在在configure时添加–with-federated-storage-engine选项;
    3. 创建一个FEDERATED表时,服务器在数据库目录创建一个.frm文件,没有表数据文件,因为实际数据在远程数据库上;
    4. 操作表的内容时需要MYSQL客户端API,读取数据通过SELECT * FROM table_name来初始化,然后通过mysql_fetch_row()的c函数去一行行读取;
    5. 创建一个FEDERATED表
      1. 假设在远程服务器上有一个表为tbl;
      2. 在本地创建表:create table federated_tbl(id int, name varchar(10)) engine=federated connection=’mysql://root@remote_host:3306/federated/tbl’;
      3. 其他CONNECTION的格式:
        1. CONNECTION=’mysql://username:password@hostname:port/database/tablename’;
        2. CONNECTION=’mysql://username@hostname/database/tablename’;
        3. CONNECTION=’mysql://username:password@hostname/database/tablename’;
    6. 局限性
      1. 远程服务器必须是一个MYSQL服务器;
      2. 不支持事务;
      3. 支持增删改查的操作和索引,但是不支持ALTER TABLE和DROP TABLE;
    7. 用途:可以跨服务器访问,不用创建DB LINK了;
  8. BDB
    1. 需要下载包含BDB版本的MYSQL(MySql-Max分发版支持BDB);
    2. 安装时在configure加入–with-berkeley-db选项;
    3. BDB启动选项
      1. –bdb-home:指定BDB表的基础目录,应该和–datadir相同;
      2. –bdb-lock-detect:BDB锁定检测方式,DEFAULT,OLDEST,RANDOM,YOUNGEST;
      3. –bdb-logdir=path:BDB日志文件目录;
      4. –bdb-no-recover:不在恢复模式启动Berkeley DB;
      5. –bdb-no-sync:不同步刷新BDB日志,使用–skip-sync-bdb-logs代替;
      6. –bdb-shared-data:以多处理模式启动Berkeley DB(初始化Berkeley DB之时,不要使用DB_PRIVATE);
      7. –bdb-tmpdir=path:BDB临时文件目录;
      8. –skip-bdb:禁止BDB存储引擎;
      9. –sync-bdb-logs:同步刷新BDB日志.这个选项默认被允许,请使用–skip-sync-bdb-logs来禁止它;
    4. 创建一个BDB表会有两个文件,一个是.frm文件,一个是存放表数据和索引的.db文件;
    5. 支持事务;
    6. 每一个BDB表都需要一个primary key,如果创建时不指定则会隐式创建一个;
    7. SELECT COUNT(*) FROM tbl_name对BDB表很慢,因为在该表中没有行计数被维持;
    8. 使用页面级别的锁;
    9. 使用mysql客户端是,应该使用–no-auto-rehash选项;
    10. BDB表的限制
      1. 每个BDB表在.db文件里存储文件被创建之时到该文件的路径,这个被做来允许在支持symlinks的多用户环境里检测锁定.因此,从一个数据库目录往另一个目录移动BDB表是不能的;
      2. 当制作BDB表的备份之时,你必须使用mysqldump要么做一个包含对每个BDB表的文件(.frm和.db文件)及BDB日志文件的备份.BDB存储引擎在它的日志文件存储未完成的事务以及要求它们在mysqld启动的时候被呈出来.BDB日志在数据目录里,具有log.XXXXXXXXXX(10位数字)形式名字的文件;
      3. 如果允许NULL值的列有唯一的索引,只有单个NULL值是被允许的,这不同于其它存储引擎;
  9. EXAMPLE
    1. EXAMPLE引擎是一个不做适合事情的存储引擎,主要用于MySql源码中一个例子用来演示如何开始编写一个新的存储引擎;
    2. 需要在configure时添加–with-example-storage-engine选项;
    3. EXAMPLE引擎不支持编译索引;
  10. Archive
    1. ARCHIVE引擎被用来以非常小的空间存储大量无索引数据;
    2. 要使用此引擎需要在configure时添加–with-archive-storage-engine选项;可以通过show variables like ‘have_archive’查看;
    3. 创建一个ARCHIVE表会有一个保存表结构的.frm文件,保存数据和元数据的.ARZ和.ARM文件,如果有优化操作的话还有一个.ARN文件;
    4. ARCHIVE引擎仅仅支持SELECT和INSERT操作,以除了几何数据类型外的所有数据类型;
    5. 存储:当inesrt数据时,archive引擎使用zlib无损数据压缩的方式压缩,optimize table可以分析表,并打包为更小的格式;
    6. 查询:在查询数据时,记录根据需要被加压缩,没有行缓存.SELECT操作执行完全表格扫描,当一个SELECT发生时,它找出当前有多少行可用,并读取行的数量;
  11. CSV
    1. CSV引擎使用逗号分隔值格式的文本文件存储数据(eg:[“1″,”aaa”]);
    2. 要想使用此引擎在configure时使用–with-csv-storage-engine选项;
    3. CSV引擎不支持null值,所以在创建时应加上not null选项;
    4. CSV引擎不支持索引;
    5. 创建CSV表会在数据库目录创建一个.frm文件,一个.CSV的文本文件用来存储数据和一个.CSM文件;
  12. Blackhole
    1. BLACKHOLE引擎就像黑洞一样,它接收数据但是是丢弃它而不是存储它,查询时总返回NULL;
    2. 创建BLACKHOLE引擎后会在数据库目录创建一个.frm文件,没有其它文件与之关联;
    3. 它支持所有的索引;
    4. 要想使用此引擎在configure时使用–with-blackhole-storage-engine选项;
    5. 用途:
      1. BLACKHOLE表不记录任何数据,如果二进制日志被允许,SQL语句被写入日志,可以用作重复器或者过滤器机制;
      2. 转储文件语法的验证;
      3. 来自二进制记录的开销测量,通过比较允许二进制日志功能的BLACKHOLE的性能与禁止二进制功能的BLACKHOLE的性能;
      4. 因为BLACKHOLE本质是一个no-op存储引擎,可以用来查找与引擎自身不相关的性能瓶颈;

MySQL学习6–MySQL5.1的体系架构

MySql体系架构:

Mysql各个模块执行的过程:
  1. 初始化模块:当服务器启动的时候,初始化模块就会解析控制文件和命令行参数,分配全局的缓存,初始化全局变量和结构,加载访问控制表和执行其它的初始化任务.一旦初始化工作完成,初始化模块转交控制权给连接管理器,它是以一个循环的方式接收客户端的连接;
  2. 连接管理模块:当客户端连接到数据库服务器,连接管理模块执行一些底层的网络命令并把控制权交给线程管理模块;
    1. max_connections:定义服务器最大的连接数;(show variables like ‘%connect%’)
    2. max_user_connections:定义服务器针对单个用户最大的连接数;
    3. Aborted_connects:失败的连接数;(show global status like ‘%connect%’);
    4. Connections:连接的次数;
    5. Max_userd_connections:最大使用连接数,最大的并发量;
    6. Threads_connected:当前连接了多少个进程,与show processlist的结果相同;
  3. 线程管理模块:线程管理模块会提供一个线程,可能是新建的,可能是从线程池中获得的,一旦线程建立好,就会把控制权交给用户验证模块;
  4. 用户验证模块:会验证连接的用户名,密码和客户端IP,验证通过之后就会接收客户端发送的命令,然后交给命令分发模块;
  5. 命令分发模块:
  6. 日志模块:每一个查询都会记录通用查询日志;
  7. 查询缓存模块:命令分发器把查询发送给查询缓存模块,查询缓存模块查看这个查询是否是可以缓存的类型,并且查找之前是否缓存过,如果查询命中,就会把纯纯的结果返回给用户,连接管理模块就会接到控制权并处理下一个命令;如果查询缓存模块没有命中,则查询给解析器,它决定了根据查询如何转交控制权;
  8. 命令解析器:命令解析器选择那种方式;
  9. 查询优化器:查询语句会使用查询优化器;
  10. 表变更模块:插入,删除,创建表,架构修改会使用条变成模块;
  11. 表维护模块:检查,修复,更新键统计会使用表维护模块;
  12. 复制模块:和复制相关的查询会使用复制模块;
  13. 状态模块:状态报告会使用状态报告模块;
  14. 访问控制模块:在这一步,通过检查命令解析器模块涉及到的表或者列是否有权限,验证之后把控制权交给表管理模块;
  15. 表管理模块:会执行表的打开和锁定,并调用具体的存储引擎接口;
  16. 存储引擎接口:存储引擎接口实行行级别的操作;
  17. 核心API:内存管理,数字函数,字符函数;
  18. 网络交互模块:网络监听,协议处理;

MySQL学习4–获得MySQL5.1的帮助

如何获得帮助

  1. 官方帮助文档(chm);
  2. 客户端工具(mysql>help);
    1. ?与help一样,获得帮助信息;
    2. clear:清除当前输入的语句,在错误的语句后面输入\c即可;
    3. connect:重新连接服务器,可以指定主机名和服务器,输入connect dbname host或或者\r dbname host即可;
    4. delimiter:语句分隔符,设置执行语句的符号,执行delimiter $$即可;
    5. edit:调用vi修改sql语句,在要修改的语句后面输入\e即可;
    6. go:发送命令到mysql服务器;
    7. pager:查询内容太多,分页显示,设置:>pager less,禁止:>nopager;
    8. tee:把查询结果输入到一个文件中:>tee /tmp/rst.txt,禁止notee,主要用于数据库的备份脚本输出;
    9. prompt:改变提示符,如:prompt royalwzy>;则每次输入命令是提示符变为royalwzy>字符串(可以在配置文件中定义,prompt=xxx);
    10. quit/exit:都是退出客户端,输入quit,exit和\q都行;
    11. source:执行一个sql脚本文件,文件名为参数,source /tmp/sql.txt;
    12. system:执行操作系统的命令,用法:system ls -l /tmp 或者\! ls -l /tmp;
    13. status:查看服务器信息的状态,输入status或者\s即可;
    14. use:改变使用的数据库,后面跟数据库的名称,eg:use mysql;
    15. charset:修改字符集,可以通过status查看当前使用的字符集,eg:charset latin1;
    16. warnings:开启警告信息,当输入的sql语句出错时,可以通过show warning或者show errors来打印警告或者错误信息,设置:warning或者\W,关闭:nowarning或者\w;
    17. rehash:设置客户端自动补全功能;
      1. 在服务器的配置文件中[mysql]节点下,默认使用no-auto-rehash选项;
      2. 注释no-auto-rehash选项,添加auto-rehash选项,reboot;
  3. 获得服务器端帮助:>help contents;
    1. 可以通过help cmd获得更详细的信息;
    2. 获得管理操作的命令:>help administration;
    3. 获得数据类型:>help data types;
    4. 获得show命令的帮助:help show; ? show;
    5. show variables:打印系统变量,类似oracle中的show parameter;
      1. 查询包含某一关键字的变量:show variables like ‘%buffer%’;
      2. 设置变量的值用set命令:set global|session key=value;
  4. show variables和show status的区别
    1. show variables:当服务器运行之后如果没有人工干预所有的参数不会发生改变;
    2. show status:显示服务器运行过程中的动态信息,值会动态改变;
  5. 获得表中前几行数据使用:select * from table_name limit n;

MySQL学习5–MySQL5.1的物理结构

Mysql的物理结构

  1. 日志文件
    1. error log:
      1. 记录mysql启动,关闭和运行时产生的重大的错误的信息;
      2. 如果mysqld警告一个表需要自动的检查或者修复,也会记录一个错误日志;
      3. 可以使用–log-error=file_name选项来指定错误日志文件,如果没有指定,则系统默认在data目录下生产一个hostname.err的文件;
      4. 也可以在配置文件中配置log_error变量;
      5. 查询log_error的位置:>show variables like ‘log_error’;查看主机名:>system hostname;
    2. binary log:
      1. 记录所有对数据库更新和潜在的更新语句(一个delete语句,但是没有影响的行),语句以事件(event)的方式存储,同时也包含了更新语句执行的时间信息;
      2. 它不记录那些不修改任何数据的语句,如果想要记录所有的语句,可以使用query log;
      3. 它主要的目的是在做还原操作时尽可能全的更新数据库,因为它包含在一次备份后的所有更新操作.它同样被用在master replication server中作为一个记录发送给slave servers;
      4. 打开二进制日志会损失1%的性能,但是它带来的好处远远超过这些;
      5. 查看二进制日志是否打开,需要查看log_bin参数是否是ON:>show variables like ‘binlog_format’;
      6. 命令行参数
        1. –log-bin=filename:记录二进制日志文件的位置,尽量指定路径名,如果不指定的话则保存在数据目录;
        2. –log-bin-index=file:记录二进制日志文件索引的位置,保存了日志文件名;
        3. –max_binlog_size:单个文件最大多少;
        4. –binlog-do-db=db_name:哪个数据库使用,只有这个数据库使用;
        5. –binlog-ignore-db=db_name:哪个数据库不使用,只有这个数据库不使用;
      7. 系统变量
        1. log_bin:日志的位置;
        2. binlog_cache_size:二进制日志缓存大小,是每一个连接进来的线程分配的大小,不是整个服务器的大小;
        3. max_binlog_cache_size:最大缓存大小;
        4. max_binlog_size:单个文件最大大小,超过此大小则再分配一个文件,但是一个事务必须在一个文件中,所以可能会稍大点;
        5. binlog_cache_use:当前连接使用的binlog缓存的事务的数量,使用show status like ‘binlog_cache_use’查看(show status命令显示了所有连接到mysql服务器的状态值);
        6. binlog_cache_disk_use:如果binlog_cache_use不够用,则在磁盘上缓存,应该尽量避免;
        7. binlog_do_db:设置master-slave时使用;
        8. binlog-ignore-db:设置哪个数据库不记录日志;
        9. sync_binlog:缓存与硬盘的同步频率(commit多少下同步一次,0表示服务器自动控制);
      8. 查看当前二进制文件的名称和大小,show binary/master logs;
      9. 如果不指定二进制日志文件的位置,默认存放在data文件夹下,日志文件是:mysql-bin.xxxxxxx,索引文件是mysql-bin.index;
      10. 如果要切换日志的话,执行flush logs命令;
      11. 初始化二进制日志系统,从新生成:reset master命令;
      12. 删除某个日志文件:purge binary logs [before ‘datetime’ / to ‘log_name’] 删除指定日期之前的和删除指定文件之前的日志文件;
      13. 设置日志文件的失效期:参数为expire_logs_days,set global expire_log_days=n,N天前的日志自动删除;
      14. 二进制日志的格式
        1. 查看格式:show [global] variables like ‘binlog_format’;
        2. 设置日志格式:set [global] binlog_format = statement|row|mixed;
        3. 使用mysqlbinlog程序打开;
    3. general query log:
      1. 一般查询日志记录服务器运行期间所有操作的日志.当客户端连接或者断开的时候服务器会记录信息到日志中,并记录所有从客户端接收到的sql语句,它对于在客户端中排错和查看是哪个客户端发送的命令很有帮助;
      2. mysqld是按照接收到命令的方式记录语句的,这可能跟它们执行的顺序不同(这与二进制日志是有区别的,二进制日志是执行后记录).
      3. 在mysql5.1.6中可以使用–log选项启动和使用–log-output选项指定日志输出的位置,也可以输出到”Server Log Tables”表中.在5.1.6之前,开启此功能是用–log=file_name or -l file_name选项(之后版本使用–general-log选项),如果没有指定file_name,默认是在data目录下生产一个hostname.log文件;
      4. 服务器重新启动和log flush不会产生一个新的文件;
      5. 默认此功能关闭,通过show variables like ‘log’/’general_log’,log与general_log意思相同;
      6. 设置打开一般查询日志:set global log=1;(两个变量会同时打开关闭,打开之后立即生效);
      7. 可以在启动的时候指定–general-file选项或者在配置文件中指定general_log=1,general_file_log=/path;
      8. 一半不打开此日志功能,数据量太大,如果打开可以放到单独的磁盘中.
      9. 备份切换一般日志文件:
        1. 先备份:>mv hostname.log hostname.log.bak
        2. 切换日志组:mysqladmin flush-logs;
    4. slow query log:
      1. 调优时使用,记录超出指定时间的sql语句;
      2. 慢查询日志主要记录执行时间超过long_query_time变量指定时间的sql语句,这个时间不包括获得锁的时间,只包含执行时间,系统默认时间是10s(long_query_time=10.0);
      3. 在mysql5.1.6版本可以指定mysqld的–long-slow-queries=file_name选项启动,在之后的版本使用–slow-query-log=0|1选项和–slow-query-file-log=file_name选项指定;
      4. 命令行参数:
        1. –log-slow-queries=file_name;指定慢查询日志文件
      5. 系统变量:
        1. low-query-log:开启慢查询功能,set global low-query-log =0|1;
        2. slow-query-file-log:指定慢查询日志文件,系统默认是在data目录下的hostname-slow.log文件;
        3. long_query_time:指定查询的最大时间,set global long_query_time=n;
        4. long_queries_not_using_indexes:不用索引的慢查询,默认是功能关闭的;
          1. 查看某个表是否有索引:> show index from t;
          2. 打开此功能:>set global long_queries_not_using_indexes =1;
          3. 查看变量:>show variables like ‘long_queries_not_using_indexes’;
      6. 分析慢日志文件的工具:mysqldumpslow,查看具体的帮助是用mysqldumpslow –help;
    5. innodb redo log;
      1. 与innodb数据引擎相关;
      2. 用来实现灾难恢复(crash recovery),突然断电会导致innodb表空间中的数据没有写到磁盘上,通过执行redo log能够重新执行这些操作来恢复数据;
      3. 提升innodb的i/o性能,innodb引擎把数据和索引都载入到内存中的缓冲池中,如果每次休息数据和索引都需要更新到磁盘,必定会增加i/o请求,而且因为每次更新的位置都是随机的,磁头需要频繁的定位导致效率很低,所以innodb每处理完一个事务后只添加一条日志log,另外有一个线程负责智能的读取日志文件并批量更新到磁盘上,实现最高效的磁盘写入;
      4. 系统变量:
        1. innodb_log_buffer_size:日志缓冲区的大小;
        2. innodb_log_file_size:日志文件的大小;
        3. innodb_log_files_in_group:一组日志中有几个文件:
          1. 文件名为ib_logfileX(X从0开始一次增加);
          2. 先关闭数据库服务:>mysqladmin shutdown(mysql.server stop);
          3. 把data目录下的ib_logfile*文件移动走:>mv ib_logfile* /tmp;
          4. 在配置文件中添加innodb_log_files_in_group=n的参数;
          5. 启动数据库服务:>mysqld –defaults-file=./my.cnf –user=mysql(mysql.server start);
          6. 可以查看error log文件观察启动过程;
        4. innodb_log_group_home_dir:日志存放的性对路径(相对于$MYSQL_HOME/mysql/data目录,即datadir目录);
          1. 关闭服务器;
          2. 在配置文件中添加此参数,并指定路径;
          3. 启动服务器;
        5. innodb_flush_log_at_trx_commit:根据不同的数据安全级别去设定.
          1. 0:日志缓冲每秒一次的被写入到日志文件,并且对日志文件做到磁盘操作的刷新,但是在一个事务提交不做任何修改;
          2. 1:每个事务提交时,日志缓冲被写到日志文件,对日志文件做到磁盘操作的刷新;
          3. 2:每个事务提交后,日志缓冲被写到日志文件,但不对日志文件做到磁盘操作刷新,对日志文件每秒刷新一次;
          4. 查看此变量:>show variables like ‘innodb_flush_log_at_trx_commit’;
        6. innodb_os_log_written:写入到文件日志的数据量,使用show status查询;
        7. innodb_os_log_fsyncs:写入到磁盘的次数,使用show status查询;
  2. 数据文件:MySql服务器使用磁盘空间有几种方式,主要是在服务器数据目录(datadir)下的数据库目录和文件,主要有以下几点:
    1. 数据库目录:每一个数据库对应一个数据目录(datadir)下的目录,不管你创建哪种类型的表.比如,一个数据库目录可以包含MYISAM引擎的表,INNODB引擎的表或者混合的表;
    2. .frm文件(Table Format Files):包含了表结构的描述信息,每一个表都有一个.frm文件在对应的数据库目录下.它与表使用的哪种引擎没有关系;
    3. .MYD/.MYI:由MYISAM存储引擎在适当的数据库目录下创建的数据库数据文件和索引文件.
    4. INNODB存储引擎有它自己的表空间和日志文件,表空间包含所有使用InnoDB引擎表的数据和索引信息,同样也包括了事务回滚所必须的undo logs.日志文件记录了提交过的事务的信息,用来防止数据丢失.默认情况下,表空间和日志文件保存在数据目录,默认的表空间文件名叫ibdata1,默认的日志文件名叫ib_logfile0和ib_logfile1.(可以为每一个使用InnoDB引擎的表配置一个表空间,这种情况下,InnoDB给指定的表创建表在表数据库目录创建表空间)
      1. 查询表空间模式:>show variables like ‘innodb_file_per_table’ ON:单独表空间,OFF:共享表空间;
      2. 如果要修改这个值的话要关闭服务器,修改配置文件,启动服务这几步;
      3. 如果使用单独表空间模式的话会在相应的数据库目录创建tablename.frm(表结构文件)和tablename.ibd文件(数据和索引文件);
    5. 服务器日志文件和状态文件:这些文件包含服务器上执行过的语句信息,日志被用于复制和数据恢复,获得优化查询性能的信息和误操作信息;
  3. Relication相关文件
  4. 其他小文件

MySQL学习3–MySQL5.1的启动和停止

Mysql启动的4种方法

  1. mysqld
    1. mysqld是MySql服务器进程;
    2. mysqld启动时读取配置文件中的[mysqld]和[server]节点
    3. 我们可以手动的调用mysqld(查看参数:mysqld –verbose –help),但是我们一般只在调试的时候才这么做,如果手动启动的话,错误消息会打印到终端屏幕上而不是错误日志文件中;
    4. 默认读取配置文件的顺序是:
      1. /etc/my.cnf;
      2. /etc/mysql/my.cnf;
      3. /usr/local/mysql/etc/my.cnf;
      4. ~/.my.cnf;
      5. 依次读取后面配置文件中的的项会覆盖掉前面;
    5. 启动方式:$MYSQL_HOME/libexec/mysqld –defaults-file=./my.cnf –user=mysql;
    6. 连接方式:
      1. mysql –defualts-file=./my.cnf
      2. mysql -S /tmp/mysql.sock
  2. mysqld_safe
    1. mysqld_safe读取配置文件的[mysqld],[server]和[mysqld_safe]节点,为了向后兼容,也会读取[safe_mysqld]节点,尽管你应该重命名[mysqld_safe]节点在MySql5.1的安装过程中;
    2. mysqld_safe是一个可以调用mysqld进程的shell脚本,它可以设置错误日志,然后调用并监控mysqld进程,如果mysqld进程异常终止(kill -9 pid)的话,则mysqld_safe可以重新启动它;
    3. 启动方式:$MYSQL_HOME/lib/mysqld_safe –defaults-file=./my.cnf –user=mysql &;
    4. 连接方式:
      1. mysql –defualts-file=./my.cnf
      2. mysql -S /tmp/mysql.sock
  3. mysql.server
    1. MySql的分发版本在Unix上包含了一个叫mysql.server的脚本,它可以用于像Linux和Solaris的OS,以至于能够使用System V-style的方式运行目录来启动和关闭系统服务.它同样可以被用于Mac OS X系统上MySql的开机项;
    2. 存放的目录有:
      1. $MYSQL_HOME/share/mysql/mysql.server
      2. mysql-VERSION/support-files/mysql.server
    3. mysql.server读取配置文件的[mysql.server]和[mysqld]节点,为了向后兼容,它也读取[mysql_server]节点,尽管你应该重命名此节点在使用MySql5.1时;
    4. 它会调用mysqld_safe进程;
    5. 启动方式:
      1. cd $MYSQL_HOME/share/mysql/mysql.server start(stop/restart/reload/force-reload/status)
      2. cp $MYSQL_HOME/share/mysql/mysql.server /etc/rc.d/init.d/mysql;chkconfig –add mysql;service mysql start;
    6. 连接方式:
      1. mysql –defualts-file=./my.cnf
      2. mysql -S /tmp/mysql.sock
  4. mysqld_multi
    1. mysqld_multi是用来管理多个在不同的Unix socket文件和TCP/IP端口监听的mysqld进程的,它可以启动,停止和报告它们当前的状态,MySql Instance Manager是一个具有选择意义的多实例管理服务;
    2. 配置方法:
      1. 创建多实例的数据文件(有几个实例创建几个数据文件目录):>mkdir $MYSQL_HOME/data2;
      2. 修改数据文件目录的访问权限:>chown -R mysql:mysql data2;
      3. 分别初始化各个实例:>mysql_install_db –basedir=$MYSQL_HOME –datadir=$MYSQL_HOME/data2 –user=mysql;(初始化时指定basedir和datadir而不是从配置文件中读取)
      4. 编辑配置文件:添加[mysqld_multi]节点和多个[mysqldxxxx]节点;
      5. 启动实例:>mysqld_multi –defaults-file=./my.cnf start 3306;
      6. 连接方式:
        1. mysql -u root -P 3306 –protocol=tcp;
        2. mysql -S /tmp/mysql3306.sock
      7. 添加有关闭服务权限的用户:>grant shutdown on *.* to “shutdown_user”@”localhost” identified by “pwd” with grant option;(查看授权语句:>show grants for root@localhost;)
      8. 停止服务:>mysqld_multi –defualts-file=./my.cnf stop 3306;
      9. 日志文件存放在:$MYSQL_HOME/share/mysqld_multi.log文件中(mysql5.5中$MYSQL_HOME/data/mysqld_multi.log文件中);
关闭mysql数据库服务器:>mysqladmin shutdown;
查看mysql服务器是否否启动:>mysqladmin ping;
连接MySql
  1. 交互协议
    1. TCP/IP:支持本地连接和远程连接,支持所有的操作系统,除非指定–skip-networking选项;
    2. Unix Socket File:仅支持本地连接,仅支持Unix系统;
    3. Named Pipe:仅支持本地连接,仅支持Windows系统,需要使用-nt的版本(mysql-nt or mysql-max-nt),此方式默认禁止,如果要开启Named Pipe方式连接必须启动-nt版本的服务器并加上–enable-named-pipe选项;
    4. Shared Memory:仅支持本地连接,仅支持Windows系统,默认禁止,如果要开启需要添加–share-memory选项;
  2. 客户端工具
    1. mysql:是一个向服务器发送SQL语句的一般用途的客户端工具,也包含了一些管理的功能;
    2. mysqladmin:是一个帮助管理服务器的管理命令行客户端;
    3. mysqlimport:提供一个LOAD DATA INFILE语句的接口,帮助导入数据;
    4. mysqldump:是一个倾倒数据库和表结构及内容的客户端,主要用于备份和拷贝数据库到其它的机器;
 
 
 
 
 
./my.cnf文件:
[mysqld_multi]
mysqld     = /usr/local/mysql/bin/mysqld_safe     — 启动服务的进程
mysqladmin = /usr/local/mysql/bin/mysqladmin    — 关闭服务的进程
user       = shutdown_user                        — 有关闭服务器权限的用户
password   = pwd                                  — 用户密码
 
[mysqld3306]
port      = 3306                                  — 监听端口号
socket    = /tmp/mysql3306.sock                   — socket文件
pid-file  = /tmp/mysql3306.pid                    — pid文件
basedir   = /usr/local/mysql                      — 实例基目录
datadir   = /usr/local/mysql/data                 — 实例数据文件目录
……                                            — 其它服务器参数

MySQL学习2–Linux下安装Mysql5.5数据库

Linux下安装Mysql5.5数据库
  1. 准备安装工具
    1. cmake:从Mysql5.5以后使用cmake编译,可以从www.cmake.org下载最新版本;
    2. GUN make:操作系统自带;
    3. gcc:操作系统自带;
    4. perl:操作系统自带;
    5. libncurses5-dev(ncurses-devel):运行cmake必须的包,如果没有安装会报错.
  2. 安装cmake:
    1. 解压压缩包:>tar -zxvf cmake-VERSION.tar.gz;
    2. 进入到cmake的解压缩目录,执行./configure命令生成makefile;
    3. 执行>make;make install;命令生成安装软件并安装cmake;
    4. 软件安装到了/usr/local/share/cmake-2.8/目录下,执行文件在/usr/local/bin目录下;
  3. 安装ncurses-devel插件
    1. 在Debian和Ubuntu上的包名是libncurses5-dev;
    2. 在RHEL和其它版本上是ncurses-devel,执行>rpm -ivh ncurses-devel-VERSION.rpm安装;
    3. 如果不安装会出现以下错误;                                                                           
  4. 创建mysql用户:>useradd mysql;                                 
  5. 解压缩mysql5.5的源码包:>tar -zxvf mysql-VERSION.tar.gz;
  6. 进入目录mysql-VERSION目录;
  7. 执行cmake命令生成makefile(MyISAM,MERGE,MEMBER和CSV四种引擎默认静态编译);
  8. 编译文件:>make;make install;mysql的安装目录下生成可执行文件,并自动创建了data文件(可以手动再创建一个logs目录,用来存放生成的日志文件,与数据目录不在同一块磁盘上,减小I/O并发),修改目录权限为mysql:>chown mysql:mysql data;                                      
  9. 拷贝配置文件:>cp ../mysql-VERSION/support-files/my-medium.cnf ./my.cnf                         
  10. 在配置文件下添加目录配置,指定数据文件的位置:                             
  11. 数据库的初始化,主要是数据库的创建,帮助文件的填充,用户文件的填充,执行:>./scripts/mysql_install_db –defaults-file=./my.cnf –user=mysql(在my.cnf配置文件中添加user参数,并且拷贝到/etc目录下就不用再加参数,执行>./scripts/mysql_install_db即可)           
  12. 启动服务器:>.bin/mysqld_safe –-user=mysql &;                         
  13. 修改MYSQL服务器root用户的密码:>./bin/mysqladmin –u root password ‘pwd’;            
  14. 登录:
    1. 如果没有设置root的密码,默认是空密码,使用>./bin/mysql就可以登录;
    2. 如果设置了root密码,则登录时要数据密码验证>./bin/mysql –uroot -p;
    3. 进入数据库后修改用户密码:update user set password=PASSWORD(‘123456′) where user=’root’;
  15. 把mysql添加到环境变量:
    1. 打开~root/.bash_profile文件;                                        
    2. 修改环境变量:>PATH=/usr/local/mysql/bin:$PATH,尽量把mysql的bin目录放在PATH的前面,使用mysql的工具的时候提高优先级,否则可能会使用系统预装的mysql的工具,造成版本不一致的错误,下图不准,修改时注意即可;                                                        
    3. 使环境变量立即生效:>. ./.bash_profile;                        
  16. 把配置文件放到默认读取的路径,并在配置文件中指定启动用户为mysql,添加开机启动:
    1. 拷贝文件到开机启动目录:cp /usr/local/mysql/support-files/mysql.server /etc/rc.d/init.d/mysqld;
    2. 添加开机启动项:chkconfig –add mysqld;chkconfig mysqld on;
    3. 启动/关闭mysql服务:service mysqld start/stop;
— 编译参数;
/usr/local/bin/cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_EXTRA_CHARSETS:STRING=utf8,gbk \
-DWITH_MYISAM_STORAGE_ENGINE=1 \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_FEDERATED_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_READLINE=1 \
-DENABLED_LOCAL_INFILE=1 \
-DMYSQL_TCP_PORT=3306
如果要使用其它字符集,要在安装完成后改变字符集:mysql>set names ‘gb2312’;
charset:gb2312 — collation:gb2312_chinese_cs

MySQL学习1–Linux下安装Mysql5.1数据库

1.创建mysql用户:>useradd mysql
graphic
2.解压缩mysql的源码安装包:>tar –zxvf mysql-VERSION.tar.gz (如果要校验完整性使用md5sum mysql-VERSION.tar.gz 把得到的md5值比较)
graphic
3.创建安装mysql软件的目录:>mkdir /usr/local/mysql
4.进入mysql源码包目录,并编译源码生成makefile文件(查看gcc的版本,使用gcc –version, 查看configure的命令可以进入mysql-VERSION目录使用./configure –help | less命令):
./configure –prefix=/usr/local/mysql \   — 安装路径
–without-debug \                         — 使用非DEBUG方式编译
–enable-thread-safe-client \             — 允许以客户端线程安全方式编译
–enable-assembler \                      — 允许使用汇编字符串处理函数
–enable-profiling \
–with-mysqld-ldflags=-all-static \       — 静态编译,把函数放在执行程序中
–with-client-ldflags=-all-static \
–with-charset=latin1 \                    — 系统默认字符集
–with-extra-charsets=utf8,gbk \          — 编译安装字符集
–with-mysqld-user=mysql \                — 指定运行mysqld的用户
–without-embedded-server \
–with-server-suffix=snda \               — 个性化定制,在系统版本后的后缀
–with-plugins=innobase,partition         —存储引擎
graphic
5.编译文件:>make;make install;mysql的安装目录下生成可执行文件
graphic
6.创建数据文件,并修改目录权限为mysql:mysql:>mkdir data;chown mysql:mysql data
graphic
7.拷贝配置文件:>cp ../mysql-VERSION/support-files/my-medium.cnf ./my.cnf
graphic
8.在配置文件下添加目录配置,指定数据文件的位置
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
graphic
9./var/run文件夹下创建mysqld目录并属于mysql:mysql
>cd /var/run
>mkdir mysqld
>chown mysql:mysql mysqld
graphic
10.数据库的初始化,主要是数据库的创建,帮助文件的填充,用户文件的填充,执行:>./bin/mysql_install_db –defaults-file=./my.cnf –user=mysql
graphic
11.启动服务器:>.bin/mysqld_safe –-user=mysql &
graphic
12.修改MYSQL服务器root用户的密码:>./bin/mysqladmin –u root password ‘pwd’
graphic
13.登录:
    1.如果没有设置root的密码,默认是空密码,使用>./bin/mysql就可以登录
    2.如果设置了root密码,则登录时要数据密码验证>./bin/mysql –uroot -p
graphic
mysql的稳定级别
1.alpha:表明发行包含大量未被彻底测试的新代码
2.beta:意味着该版本功能是完整的,并且所有的新代码被测试了,没有增加重要的新特征,应该没有已知的缺陷.当appha版本至少一个月没有出现报导的致命漏洞,并且没有计划增加导致已经实施的功能不稳定的新功能时,版本从alpha变为beta版本.
3.re:是发布代表,是一个发行了一段时间的beta版本,看起来应该运行正常,只增加了很小的修复.
4.ga:如果没有后缀,这意味着该版本已经在很多地方运行一段时间了,而且没有非平台特性的缺陷报告.
Mysql源码目录,主要包括客户端代码,服务端代码,测试工具和其他库文件
1.BUILD:各种平台的编译脚本,可以用来制作各种平台的二进制版本
2.client:客户端目录(mysql.cc, mysqadmin.ccl)
3.docs:文档目录
4.storage:存储引擎目录,实现了handler抽象接口,主要包含一下目录:
     1.innobase
     2.myisam
     3.myisammrg
     4.heap
     5.cvs
     6.archive
     7.federated
     8.ndb
     9.blackhole
5.mysys:mysql为了实现跨平台对系统库封装
6.sql:数据库主程序目录(sql_insert.cc, sql_update.cc, ..),存储引擎接口(handler.cc, handler.h)

Redis学习10–Java Drivers

Java驱动实践
  1. Redis的客户端有主要有三种:JDBC-Redis, JRedis和Jedis,推荐Jedis的方式;
  2. Jedis API Online Help:http://www.jarvana.com/jarvana/view/redis/clients/jedis/2.0.0/jedis-2.0.0-javadoc.jar!/index.html;
  3. Jredis使用总结:
    1. pipeline:starts a pipeline,which is a very efficient way to send lots of command and read all the responses when you finish sending them;即pipeline适用于批处理,当有大量的操作需要一次性执行的时候,可以用管道;
    2. 分布式的id生成器:因为redis-server是单线程处理client端的请求的,所以可以使用jedis.incr(“id_key”)来生成序列;
    3. 分布式锁watch/multi:可以用来实现跨jvm的同步问题;
      1. 方法1:Jedis.setnx(key, value),推荐的方法;
      2. 方法2:事务multi;
      3. 方法3:事务+监听;
    4. redis分布式:jedis里面通过MD5,MURMUR Hash(默认)两种方式实现了分布式,也可以自己实现redis.clients.util.Hashing接口;
  4. Jedis中Pool的问题:It seems like server has closed the connection;
    1. 原因:redis-server关闭了此客户端的连接,server端设置了maxidletime(默认是5分钟),服务端会不断循环检测clinet的最后一次通信时间(lastinteraction),如果大于maxidletime,则关闭连接,并回收相关资源,client在向该连接中写数据后就会由于server端已经关闭而出现broken pipe的问题;
    2. 错误的配置:在spring初始化时获取一次实例化jedisCommands,而后每次的redis的调用时并未从pool中获取;
    3. 解决办法;

———————– Pipeline ———————–

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
 
public class Redis
{
     public static void main(String[] args)
     {
           // 连接Redis 服务器;
          Jedis jedis = new Jedis( “192.168.10.112”, 6379);
           // 生成Pipeline;
          Pipeline pipeline = jedis.pipelined();
           // 管道操作,会把所有的操作发送给服务器端,然后一次性执行;
           // ……
          pipeline.incr( “key”);
           // 获得所有的结果;
          pipeline.sync();
     }
}
———————– Pipeline ———————–
———————– Jedis.setnx(key, value) ———————–
import java.util.Random;
import org.apache.commons.pool.impl.GenericObjectPool.Config;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
 
public class RedisLock
{
     // 加锁标志
     public static final String    LOCKED                  = “TRUE”;
     public static final long      ONE_MILLI_NANOS         = 1000000L;
     
     // 默认超时时间(ms )
     public static final long      DEFAULT_TIME_OUT   = 3000;
     public static JedisPool       pool;
     public static final Random    r                       = new Random();
     
     // 锁的超时时间(s),过期删除
     public static final int       EXPIRE                  = 5 * 60;
     static
     {
           pool = new JedisPool( new Config(), “host”, 6379);
     }
     
     private Jedis                 jedis;
     private String                key;
     
     // 锁状态标志
     private boolean                    locked                  = false;
     
     public RedisLock(String key)
     {
           this. key = key;
           this. jedis = pool.getResource();
     }
     
     public boolean lock( long timeout)
     {
           long nano = System. nanoTime();
          timeout *= ONE_MILLI_NANOS;
           try
          {
               while ((System. nanoTime() – nano) < timeout)
              {
                    if ( jedis.setnx( key, LOCKED) == 1)
                   {
                         jedis.expire( key, EXPIRE);
                         this. locked = true ;
                         return locked;
                   }
                    // 短暂休眠,nano避免出现活锁
                   Thread. sleep(3, r.nextInt(500));
              }
          }
           catch (Exception e)
          {
              e.printStackTrace();
          }
           return false;
     }
     
     public boolean lock()
     {
           return lock( DEFAULT_TIME_OUT);
     }
     
     // 无论是否加锁成功,必须调用
     public void unlock()
     {
           try
          {
               if ( locked)
              {
                    jedis.del( key);
              }
          }
           finally
          {
               pool.returnResource( jedis);
          }
     }
}
———————– Jedis.setnx(key, value) ———————–
———————– 事务multi ———————–
     public boolean lock_2( long timeout)
     {
           long nano = System. nanoTime();
          timeout *= ONE_MILLI_NANOS;
           try
          {
               while ((System. nanoTime() – nano) < timeout)
              {
                   Transaction t = jedis.multi();
                    // 开启事务,当server端收到 multi指令;
                    // 会将该client的命令放入一个队列,然后依次执行,直到收到 exec指令;
                   t.getSet( key, LOCKED);
                   t.expire( key, EXPIRE);
                   String ret = (String) t.exec().get(0);
                    if (ret == null || ret.equals(“UNLOCK”))
                   {
                         return true;
                   }
                    // 短暂休眠,nano避免出现活锁;
                   Thread. sleep(3, r.nextInt(500));
              }
          }
           catch (Exception e)
          {
          }
           return false;
     }
———————– 事务multi ———————–
———————– 事务+监听 ———————–
     public boolean lock_3( long timeout)
     {
           long nano = System. nanoTime();
          timeout *= ONE_MILLI_NANOS;
           try
          {
               while ((System. nanoTime() – nano) < timeout)
              {
                    jedis.watch( key);
                    // 开启watch之后,如果key的值被修改,则事务失败, exec方法返回null;
                   String value = jedis.get( key);
                    if (value == null || value.equals(“UNLOCK”))
                   {
                        Transaction t = jedis.multi();
                        t.setex( key, EXPIRE, LOCKED);
                         if (t.exec() != null)
                        {
                              return true;
                        }
                   }
                    jedis.unwatch();
                    // 短暂休眠,nano避免出现活锁;
                   Thread. sleep(3, r.nextInt(500));
              }
          }
           catch (Exception e)
          {
          }
           return false;
     }
———————– 事务+监听 ———————–
———————– redis分布式 ———————–
List<JedisShardInfo> hosts = new ArrayList<JedisShardInfo>();
// server1
JedisShardInfo host1 = new JedisShardInfo( “”, 6380, 2000);
// server2
JedisShardInfo host2 = new JedisShardInfo( “”, 6381, 2000);
hosts.add(host1);
hosts.add(host2);
 
ShardedJedis jedis = new ShardedJedis(hosts);
jedis.set(“key”, “”);
———————– redis分布式 ———————–
———————– 错误的配置 ———————–
<bean id=”jedisPoolConfig” class=”redis.clients.jedis.JedisPoolConfig”>
<property name=”maxActive”  value=”20″ />
<property name=”maxIdle” value=”10″ />
<property name=”maxWait” value=”1000″ />
</bean>

<!– jedis shard信息配置 –>
<bean id=”jedis.shardInfo” class=”redis.clients.jedis.JedisShardInfo”>
<constructor-arg index=”0″ value=”*.*.*.*” />
<constructor-arg index=”1″ value=”6379″ />
</bean>

<!– jedis shard pool配置 –>
<bean id=”shardedJedisPool” class=”redis.clients.jedis.ShardedJedisPool”>
<constructor-arg index=”0″ ref=”jedisPoolConfig” />
<constructor-arg index=”1″>
<list>
<ref bean=”jedis.shardInfo” />
</list>
</constructor-arg>
</bean>

<bean id=”jedisCommands” factory-bean=”shardedJedisPool” factory-method=”getResource” />

———————– 错误的配置 ———————–
———————– 解决办法 ———————–
<!– POOL配置 –>
<bean id=”jedisPoolConfig” class=”redis.clients.jedis.JedisPoolConfig”>
<property name=”maxActive”  value=”20″ />
<property name=”maxIdle” value=”10″ />
<property name=”maxWait” value=”1000″ />
<property name=”testOnBorrow”  value=”true”/>
</bean>

<!– jedis shard信息配置 –>
<bean id=”jedis.shardInfo” class=”redis.clients.jedis.JedisShardInfo”>
<constructor-arg index=”0″ value=”*.*.*.*” />
<constructor-arg index=”1″ value=”6379″ />
</bean>

<!– jedis shard pool配置 –>
<bean id=”shardedJedisPool” class=”redis.clients.jedis.ShardedJedisPool”>
<constructor-arg index=”0″ ref=”jedisPoolConfig” />
<constructor-arg index=”1″>
<list>
<ref bean=”jedis.shardInfo” />
</list>
</constructor-arg>
</bean>

———————– 解决办法 ———————–

Redis学习09–虚拟内存

Redis中的虚拟内存
  1. Redis中虚拟内存的概念:
    1. redis的虚拟内存与os的虚拟内存不是同一个概念,但是实现的方法和目的是相同的,就是暂时把不经常访问的数据从内存交换到磁盘中,从而腾出宝贵的内存空间用于其它需要访问的数据;
    2. 对于redis这样的内存数据库,内存总是不够用的,除了可以将数据分割到多个redis server外,另外的能够提高数据库容量的办法就是使用vm把那些不经常访问的数据交换的磁盘上;
    3. 总是有少部分数据被经常访问,大部分数据很少被访问,对于网站来说确实总是只有少量用户经常活跃,当少量数据被经常访问时,使用vm不但能提高单台redis server数据库的容量,而且也不会对性能造成太多影响;
  2. Redis没有使用os提供的虚拟内存机制而是自己在用户态实现了自己的虚拟内存机制,主要原因为:
    1. os的虚拟内存是以4k页面为最小单位进行交换的,而redis的大多数对象都远小于4k,所以一个os页面上可能有多个redis对象;
    2. 另外redis的集合对象类型如list,set可能存在与多个os页面上,最终可能造成只有10%的key被经常访问,但是所有os页面都会被os认为是活跃的,这样只有内存真正耗尽时os才会交换页面;
    3. 相比于os的交换方式,redis可以将被交换到磁盘的对象进行压缩,保存到磁盘的对象可以去除指针和对象元数据信息,一般压缩后的对象会比内存中的对象小10倍,这样redis的vm会比osvm能少做很多io操作;
  3. VM的配置:
    1. vm-enabled yes                     # 开启vm功能;
    2. vm-swap-file /tmp/redis.swap       # 交换出来的value保存的文件路径/tmp/redis.swap;
    3. vm-max-memory 1000000              # redis使用的最大内存上限,超过上限后redis开始交换value到磁盘文件中;
    4. vm-page-size 32                    # 每个页面的大小32个字节;
    5. vm-pages 134217728                 # 最多使用在文件中使用多少页面,交换文件的大小 = vm-page-size * vm-pages
    6. vm-max-threads 4                   # 用于执行value对象换入换出的工作线程数量,推荐设置为cpu的核心数,0表示不使用工作线程;
  4. 参数的解释:
    1. redis的vm在设计上为了保证key的查找速度,只会将value交换到swap文件中,所以如果是内存问题是由于太多value很小的key造成的,那么vm并不能解决;
    2. 和os一样redis也是按页面来交换对象的,redis规定同一个页面只能保存一个对象,但是一个对象可以保存在多个页面中;
    3. 在redis使用的内存没超过vm-max-memory之前是不会交换任何value的,当超过最大内存限制后,redis会选择较老的对象,如果两个,对象一样老会优先交换比较大的对象,精确的公式swappability = age log(size_in_memory);
    4. 对于vm-page-size的设置应该根据自己的应用将页面的大小设置为可以容纳大多数对象的大小,太大了会浪费磁盘空间,太小了会造成交换文件出现碎片;
    5. 对于交换文件中的每个页面,redis会在内存中对应一个1bit值来记录页面的空闲状态,所以像上面配置中页面数量(vm-pages 134217728)会占用16M(134217728/8/1024/1024)内存用来记录页面空闲状态;
    6. vm-max-threads表示用做交换任务的线程数量,如果大于0推荐设为服务器的cpu core的数量,如果是0则交换过程在主线程进行;
  5. vm的工作原理:
    1. 当vm-max-threads设为0时(Blocking VM):
      1. 换出:主线程定期检查发现内存超出最大上限后,会直接已阻塞的方式,将选中的对象保存到swap文件中,并释放对象占用的内存,此过程会一直重复直到下面条件满足
        1. 内存使用降到最大限制以下;
        2. swap文件满了;
        3. 几乎全部的对象都被交换到磁盘了;
      2. 换入:当有client请求value被换出的key时,主线程会以阻塞的方式从文件中加载对应的value对象,加载时此时会阻塞所有的client,然后处理client的请求;
    2. 当vm-max-threads大于0(Threaded VM):
      1. 换出:当主线程检测到使用内存超过最大上限,会将选中的要交换的对象信息放到一个队列中交由工作线程后台处理,主线程会继续处理client请求;
      2. 换入:如果有client请求的key被换出了,主线程先阻塞发出命令的client,然后将加载对象的信息放到一个队列中,让工作线程去加载,加载完毕后工作线程通知主线程,主线程再执行client的命令,这种方式只阻塞请求value被换出key的client;
    3. 总的来说blocking vm的方式总的性能会好一些,因为不需要线程同步,创建线程和恢复被阻塞的client等开销,但是也相应的牺牲了响应性;threaded vm的方式主线程不会阻塞在磁盘io上,所以响应性更好;如果应用不太经常发生换入换出,而且也不太在意有点延迟的话则推荐使用blocking vm的方式;
  6. 相关链接:
    1. http://antirez.com/post/redis-virtual-memory-story.html;
    2. http://redis.io/topics/internals-vm;