MySQL5.1新特性(一)日志的增强
对于MySQL,很多印象其实都是来自比较老的4.x版本,实际上MySQL在后续的5.0,5.1和6.0版本中还是做出了很多的改进,特别是原来一些动不动要重启的操作,慢慢的都可以在线做了,如果要做企业级数据库,在线操作的支持是必不可少的。由于我们在产品库中大量开始使用5.1,所以打算写一个系列短文,介绍一些个人觉得比较实用的新特性。因为MySQL这样的开源软件,版本分支比较多,所以每篇文章涉及的一些小版本可能不太一样。
MySQL有很多种日志,包括error log,general query log,binary log,slow query log等。在以前的版本,这些日志的开启或者关闭,都是需要重启服务器的,而且都是记录到日志文件。从MySQL5.1.6版开始,general query log和slow query log开始支持写到文件或者数据库表两种方式,并且日志的开启,输出方式的修改,都可以在Global级别动态修改。
如果说日志是写到文件还是表,对于DBA来说不是那么在乎的话,那么可以动态的开启关闭日志真的可以说是DBA们梦寐以求的。尤其是slow log query,以前一直在头疼,开启吧,可能影响性能,不开吧,对于一些性能差的SQL又没有其他好用的捕获方式。因为开还是不开,涉及到重启服务的问题。
下面演示一下通过设置几个Global级别参数来开启关闭general query log和slow log query的过程:
root@NinGoo>select version(); +---------------+ | version() | +---------------+ | 5.1.25-rc-log | +---------------+ 1 row in set (0.00 sec)
设置日志输出方式为文件
root@NinGoo>set global log_output=file; Query OK, 0 rows affected (0.00 sec)
设置general log和slow query log的日志文件路径
root@NinGoo>set global general_log_file='/tmp/general.log'; Query OK, 0 rows affected (0.00 sec) root@NinGoo>set global slow_query_log_file='/tmp/slow.log'; Query OK, 0 rows affected (0.00 sec)
开启general log和slow query log,相应的,关闭只要设置参数为off
root@NinGoo>set global general_log=on; Query OK, 0 rows affected (0.04 sec) root@NinGoo>set global slow_query_log=on; Query OK, 0 rows affected (0.02 sec)
如果设置log_output=table的话,则日志结果会记录到名为gengera_log和slow_log的两张表中,这两张表的默认引擎都是CSV,其实就是将日志保存为CSV文件格式了。当然,也可以将这两张表改为MyISAM引擎,这不是问题。
更多关于MySQL5.1日志的新特性,请参考MySQL 5.1 Reference Manual
Data Guard与nid
使用nid可以修改一个库的db_name和dbid。当然,如果dbid变更,则需要resetlogs才能打开数据库,因为oracle在内部其实是通过dbid来区分一个数据库的,而只修改db_name的话,则可以noresetlogs。
对于Data Guard环境来说,如果变更了主库的db_name,备库怎么处理?因为db_name不但存在于控制文件中,在每个数据文件的头部也有标识,而备库是不允许执行nid来更名的:
$ nid TARGET=/ DBNAME=test SETNAME=Y DBNEWID: Release 10.2.0.4.0 - Production on Mon Aug 18 13:25:50 2008 Copyright (c) 1982, 2007, Oracle. All rights reserved. Connected to database TEST (DBID=47959353) NID-00131: Control file is not current Change of database name failed during validation - database is intact. DBNEWID - Completed with validation errors.
但如果主库只是要变更db_name的话,备库是不必重做的,只要从主库重新生成备库控制文件即可。此时备库可以继续恢复主库传过来的归档,但是数据文件头部的某个位置还是会保留原来的db_name,只有在备库切换成主库的时候,才会根据控制文件去更新数据文件头。
主库从test更名为test2后,即使重建备库控制文件,备库的数据文件头中的db_name还是保持不变:
$ strings system.dbf | head -n 5
}|{z
TEST
SYSTEM
_SYSSMU1$
_SYSSMU2$
备库在切换成主库以后,文件头中的db_name更新成新的test2:
$ strings system.dbf | head -n 5
}|{z
TEST2
SYSTEM
_SYSSMU1$
_SYSSMU2$
这样虽然看起来不会有什么太大的问题,只是一个标识字段不一样,甚至主库的某个datafile损坏,一样可以复制备库的datafile过来替代。但主备库的数据文件的文件头中存在这么一个不一致,总是一个潜在的风险点,谁知道哪天又触发到oracle的什么bug了。
另外,原备库的临时文件需要重建,因为切换新的主库以后,tempfile的文件头不会根据控制文件修改成新的db_name。
最后附上使用nid修改db_name而不修改dbid的操作步骤(摘自Note:224266.1):
1. Backup the database
2. SHUTDOWN IMMEDIATE of the database
3. STARTUP MOUNT
4. Open one session and run NID with sysdba privileges
% nid TARGET=SYS/password@test_db DBNAME=test_db2 SETNAME=Y
- the value of DBNAME is the new dbname of the database
- SETNAME must be set to Y. The default is N and causes the DBID to be changed also.
5. shutdown IMMEDIATE of the database
6. Set the DB_NAME initialization parameter in the initialization parameter
file to the new database name
7. Create a new password file
8. Startup of the database(without resetlogs)
Oracle12G将不再支持裸设备?
一直以来,为了更好的IO性能,为了避免文件系统可能碰到的bug,可能很多DBA都倾向于在一些IO压力比较大的核心库上采用裸设备。毫无疑问,对比文件系统,裸设备的管理相对要复杂些,但其实一旦熟悉,基本上也相差不大。不过Oracle一直在存储和文件系统方面下功夫,ASM在OS层面不失为存储虚拟化的一个廉价解决方案,但是RAC的OCR和Voting Disk无法存放在ASM上,并且在稳定性,可靠性和可管理性还有待加强。在Oracle11g中,ASM已经有了不少的改进,并且有小道消息说Oracle准备将ASM发展成ASMFS,要是真的能实现,绝对具有吸引力。目前在淘宝的数据仓库环境中,RAC+ASM的组合还是比较让人满意的。至于OCFS,作为一个集群文件系统,应该说还有很长的路要走,而从Oracle11g来看,ASM才是Oracle力推的方式。
Oracle最近在Metalink上放出了一个文档(Note:578455.1 - Announcement of De-Support of RAW devices in Release 12G),号称在将来的12G版本中将放弃对裸设备的支持。当然,要实现这一目的,Oracle首先要提供一个足够说服客户的理由,比如未来ASM能够支持OCR和Voting disk,目前ASM还依赖CSS,肯定无法做到这一点,那么12g的ASM可能就是一个独立于整个clusterware的东西,这就无限接近于传说中的ASMFS了。
De-Support of Raw
This document is to announce the de-support of raw devices in a future Oracle 12 g release. This means customers can no longer keep their datafiles, OCR or Voting disks on raw devices in Oracle 12g.
If raw devices are not being used in the current release then there is nothing to be done. However if raw devices are being currently used, then planning should be done to migrate off the raw devices. There are many choices currently to replace raw devices, including ASM, OCFS, and other cluster file systems.
dba_indexes视图的性能
前端时间,在监控系统中加入了index的状态是否为unusable,以及其并行度是否有设置的监控:
select case when status='UNUSABLE' then
'alter index '||owner||'.'||index_name||' rebuild online compute statistics;'
when to_number(degree)>1 then
'alter index /* '||degree ||' */'||owner||'.'||index_name||' noparallel;'
end case
from (select * from dba_indexes where degree<>‘DEFAULT’) a
where status=’UNUSABLE’
or to_number(degree)>1
and owner not in (’SYS’,'SYSTEM’,'MANAGER’,'WMSYS’);
语句运行的速度很快,但是从statspack中发现这条语句的逻辑读单次高达26846。使用set autotrace比较了下9i和10g的执行计划和统计信息,发现9i查询这个视图的代价非常的高,而10g则有了一定的改善。在Oracle9i中,optimizer_mode默认是CHOOSE,所以查询数据字典使用了RBO,而Oracle10g则默认为ALL_ROWS,所以采用了CBO。
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production
PL/SQL Release 9.2.0.6.0 - Production
CORE 9.2.0.6.0 Production
TNS for IBM/AIX RISC System/6000: Version 9.2.0.6.0 - Production
NLSRTL Version 9.2.0.6.0 - Production
SQL> set autot trace
SQL> select * from dba_indexes;
1242 rows selected.
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 NESTED LOOPS (OUTER)
2 1 NESTED LOOPS (OUTER)
3 2 NESTED LOOPS
4 3 NESTED LOOPS
5 4 NESTED LOOPS (OUTER)
6 5 NESTED LOOPS
7 6 NESTED LOOPS (OUTER)
8 7 NESTED LOOPS
9 8 TABLE ACCESS (FULL) OF 'OBJ$'
10 8 TABLE ACCESS (BY INDEX ROWID) OF 'IND$'
11 10 INDEX (UNIQUE SCAN) OF 'I_IND1' (UNIQUE)
12 7 TABLE ACCESS (BY INDEX ROWID) OF 'OBJ$'
13 12 INDEX (UNIQUE SCAN) OF 'I_OBJ1' (UNIQUE)
14 6 TABLE ACCESS (BY INDEX ROWID) OF 'OBJ$'
15 14 INDEX (UNIQUE SCAN) OF 'I_OBJ1' (UNIQUE)
16 5 TABLE ACCESS (CLUSTER) OF 'USER$'
17 16 INDEX (UNIQUE SCAN) OF 'I_USER#' (NON-UNIQUE)
18 4 TABLE ACCESS (CLUSTER) OF 'USER$'
19 18 INDEX (UNIQUE SCAN) OF 'I_USER#' (NON-UNIQUE)
20 3 TABLE ACCESS (CLUSTER) OF 'USER$'
21 20 INDEX (UNIQUE SCAN) OF 'I_USER#' (NON-UNIQUE)
22 2 TABLE ACCESS (CLUSTER) OF 'SEG$'
23 22 INDEX (UNIQUE SCAN) OF 'I_FILE#_BLOCK#' (NON-UNIQUE)
24 1 TABLE ACCESS (CLUSTER) OF 'TS$'
25 24 INDEX (UNIQUE SCAN) OF 'I_TS#' (NON-UNIQUE)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
42924 consistent gets
0 physical reads
0 redo size
98000 bytes sent via SQL*Net to client
1558 bytes received via SQL*Net from client
84 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1242 rows processed