之前有朋友问过如果知道SQL语句,可不可以不通过查询数据字典就能算出这条语句的SQL_ID。
之前我的回答是,不能,Oracle没有提供这样的方法或者函数。
但是任何事情都是可能的,Slavik Markovich写了一个Python脚本来通过SQL Text计算SQL_ID和SQL_HASH_VALUE。
而在Oracle10g中SQL_ID和之前SQL_HASH_VALUE的关系可以参看Tanel Poder的文章。
12122 items (12122 unread) in 19 feeds
Blog
(67 unread)
Google
(2118 unread)
Oracle
(3670 unread)
OracleERP
(1645 unread)
ReadBlog
(1890 unread)
nix
(386 unread)
OpenSource
(370 unread)
TechNews
(1829 unread)
Design
(147 unread)
之前有朋友问过如果知道SQL语句,可不可以不通过查询数据字典就能算出这条语句的SQL_ID。
之前我的回答是,不能,Oracle没有提供这样的方法或者函数。
但是任何事情都是可能的,Slavik Markovich写了一个Python脚本来通过SQL Text计算SQL_ID和SQL_HASH_VALUE。
而在Oracle10g中SQL_ID和之前SQL_HASH_VALUE的关系可以参看Tanel Poder的文章。
近期在客户处将原先的4节点RAC扩充到8节点。期间碰到一些问题,总结一下。
系统环境:
Redhat Enterprise Server 4,Oracle RAC 10.2.0.4,OCFS2
一。现象:
往CRS中添加节点时运行rootaddnode.sh会报PRKC-1044错误。
PRKC-1044 – FAILED TO CHECK REMOTE COMMAND EXECUTION
原因:
在配置ssh对等性的时候,设置的passphrase非空。
解决方法:
重新配置ssh对等性,在Enter passphrase (empty for no passphrase): 时直接回车,不要输入任何密码。
二。现象:
在使用dbca往RAC中添加新节点时报TNS-04602错误。
TNS-04414: File Error caused by: TNS-04602: Invalid syntax error: Expected “LITERAL” before or at…
原因:
数据库中没有设置remote_listener参数。
解决方法:
alter system set remote_listener='LISTENERS_RAC' scope=both;
三。总结
分别使用CRS_HOME和ORACLE_HOME中的addNode.sh脚本往CRS和RAC中添加节点是方便高效的。
如果要修改Private Interface的实际IP地址,必须要在操作系统级别修改,比如通过ifconfig命令以及修改/etc/hosts文件等,而为了避免发生node evictions,需要保证CRS stack down。在修改完IP地址以后,再重新让CRS stack up,才可以使用oifcfg命令修改保存在OCR中的信息。
在10gR2以前起停CRS Stack使用init.crs。
#init.crs stop #init.crs start
在10gR2以后可以使用crsctl命令。
#crsctl stop crs #crsctl start crs
1. 检查当前的网络资源配置
% $ORA_CRS_HOME/bin/oifcfg getif
2. 删除原先的Private Interface设置
% $ORA_CRS_HOME/bin/oifcfg delif –global eth1
3. 添加新的Private Interface设置(此处例子仅仅修改subnet,如果修改了eth1,就是修改了interface name)
% $ORA_CRS_HOME/bin/oifcfg setif –global eth1/192.168.1.0:cluster_interconnect
4. 再次检查网络资源配置确认已经修改成功
% $ORA_CRS_HOME/bin/oifcfg getif
5. 重新启动数据库实例,以确认RAC使用了正确的Private Interface作Cache Fusion。在告警日志中检查如下输出:
Cluster communication is configured to use the following interface(s) for this instance 192.168.1.1
在Oracle10g之后,提供了DBMS_ADVANCED_REWRITE包,具有强大的查询重写功能,可以让我们在数据库层面实现很多微妙的调整。假设我们有一个应用,但是现在无法直接修改应用程序的编码,但是又想能够让应用程序的某些SQL产生我们想要的变化,那么就可以使用DBMS_ADVANCED_REWRITE包。
drop table t; create table t as select object_id,object_name from dba_objects; drop table t1; create table t1 as select object_id,object_name from dba_objects where 1=0;
SQL> select count(*) from t;
COUNT(*)
----------
16636
SQL> select count(*) from t1;
COUNT(*)
----------
0
现在我们有表T和T1,表结构相同,但是表T中有1.6万记录,而表T1中没有记录,如果说我们的应用中有一个SQL多次地查询表T的总记录数,占用了大量的CPU和逻辑读,而这样的count记录数又是完全没有用处的,但是我们无法修改应用程序去掉这个SQL,那么我们就可以通过DBMS_ADVANCED_REWRITE包来讲查询表T的SQL转变为查询表T1,这样就大大减少了这条SQL的逻辑读。
首先DBMS_ADVANCED_REWRITE包的执行权限必须显式赋给需要的用户。
CONN sys/password AS SYSDBA
GRANT EXECUTE ON DBMS_ADVANCED_REWRITE TO kamus;
CONN kamus/password
BEGIN
SYS.DBMS_ADVANCED_REWRITE.declare_rewrite_equivalence (
name => 't_rewrite',
source_stmt => 'SELECT count(*) FROM t',
destination_stmt => 'SELECT count(*) FROM t1',
validate => FALSE,
rewrite_mode => 'TEXT_MATCH');
END;
/
然后需要设置会话层面的QUERY_REWRITE_INTEGRITY参数,该参数默认值为ENFORCED,表示只有重写后的SQL输出结果跟原结果完全一样时,查询才会被真正重写,在这里需要修改为TRUSTED。
SQL> ALTER SESSION SET QUERY_REWRITE_INTEGRITY = TRUSTED;
SQL> set autot on
SQL> select count(*) from t;
COUNT(*)
----------
0
Execution Plan
----------------------------------------------------------
Plan hash value: 238181912
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 13 | 2 (0)| 00:00:01 |
| 1 | VIEW | | 1 | 13 | 2 (0)| 00:00:01 |
| 2 | SORT AGGREGATE | | 1 | | | |
| 3 | TABLE ACCESS FULL| T1 | 1 | | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
3 consistent gets
0 physical reads
0 redo size
417 bytes sent via SQL*Net to client
416 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> ALTER SESSION SET QUERY_REWRITE_INTEGRITY = ENFORCED;
SQL> select count(*) from t;
COUNT(*)
----------
16636
Execution Plan
----------------------------------------------------------
Plan hash value: 2966233522
-------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 22 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| T | 16639 | 22 (0)| 00:00:01 |
-------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
69 consistent gets
0 physical reads
0 redo size
420 bytes sent via SQL*Net to client
416 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL>
可以看到在重写之后,执行计划中显示直接去查询表T1,而consistent gets也从查询表T需要的69减少为3。
可以从[USER|ALL|DBA]_REWRITE_EQUIVALENCES视图中获得查询重写的信息。
SQL> select * from user_rewrite_equivalences; OWNER NAME SOURCE_STMT DESTINATION_STMT REWRITE_MO ------ ---------- ------------------------- ------------------------- ---------- KAMUS T_REWRITE SELECT count(*) FROM t SELECT count(*) FROM t1 TEXT_MATCH
DBMS_ADVANCED_REWRITE包也有限制,不可以重写牵涉到SYS用户对象的SQL。
drop table t1; create table t1 as select * from all_tables where 1=0; SQL> BEGIN 2 SYS.DBMS_ADVANCED_REWRITE.declare_rewrite_equivalence ( 3 name => 't_rewrite', 4 source_stmt => 'SELECT count(*) FROM all_tables', 5 destination_stmt => 'SELECT count(*) FROM t1', 6 validate => FALSE, 7 rewrite_mode => 'TEXT_MATCH'); 8 END; 9 / BEGIN * ERROR at line 1: ORA-30354: Query rewrite not allowed on SYS relations ORA-06512: at "SYS.DBMS_ADVANCED_REWRITE", line 29 ORA-06512: at "SYS.DBMS_ADVANCED_REWRITE", line 185 ORA-06512: at line 2
在测试中,如果destination_stmt中包含SYS用户对象,是可以成功创建查询重写的,但是在执行SQL的时候却会报ORA-03113错误,后台出现ORA-07445错误,无法正常执行。
SQL> BEGIN
2 SYS.DBMS_ADVANCED_REWRITE.declare_rewrite_equivalence (
3 name => 't_rewrite',
4 source_stmt => 'SELECT count(*) FROM t1',
5 destination_stmt => 'SELECT count(*) FROM all_tables',
6 validate => FALSE,
7 rewrite_mode => 'TEXT_MATCH');
8 END;
9 /
PL/SQL procedure successfully completed.
SQL> select * from user_rewrite_equivalences;
OWNER NAME SOURCE_STMT DESTINATION_STMT REWRITE_MO
------ ---------- ------------------------- ------------------------- ----------
KAMUS T_REWRITE SELECT count(*) FROM t1 SELECT count(*) FROM all_ TEXT_MATCH
tables
SQL> ALTER SESSION SET QUERY_REWRITE_INTEGRITY = TRUSTED;
Session altered.
SQL> select count(*) from t1;
select count(*) from t1
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel
Process ID: 8360
Session ID: 135 Serial number: 22
在尝试使用SQL Developer用SYSDBA连接数据库时总是报ORA-01017错误。
ORA-01017: invalid username/password; logon denied
实际上用户名密码是正确的,并且在数据库服务器上使用SQL*Plus通过监听连接也是正常的。
C:\Users\Kamus>sqlplus "sys/oracle@orcl11g as sysdba" SQL*Plus: Release 11.1.0.7.0 - Production on Fri Mar 12 12:17:01 2010 Copyright (c) 1982, 2008, Oracle. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - Production With the Partitioning, OLAP and Real Application Testing options SQL>
真正的问题是因为数据库密码文件缺失了。在windows下,Oracle数据库密码文件是储存在%ORACLE_HOME%\database目录下,命名为PWD%SID%.ora。
密码文件不存在,数据库实例完全可以正常启动,只是在尝试通过监听登陆SYSDBA的时候就会报ORA-01017错误。
那么为什么在本地使用SQL*Plus是正常的,这实际上是一个错觉,因为在Windows中Oracle默认安装以后会在sqlnet.ora文件中设置SQLNET.AUTHENTICATION_SERVICES = (NTS),这表示支持“Windows NT native authentication”方式登陆数据库,也就是属于OSDBA组的Windows用户不用提供密码也可以通过SYSDBA登陆数据库。sqlnet.ora文件位于%ORACLE_HOME%\network\admin目录下。
我们随便使用一个不存在的用户名密码都是可以登录数据库的。
C:\Users\Kamus>sqlplus "NotExist/nopassword@orcl11g as sysdba" SQL*Plus: Release 11.1.0.7.0 - Production on Fri Mar 12 13:10:49 2010 Copyright (c) 1982, 2008, Oracle. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - Production With the Partitioning, OLAP and Real Application Testing options SQL>
修改SQLNET.AUTHENTICATION_SERVICES参数为NONE之后。
SQLNET.AUTHENTICATION_SERVICES = (NONE)
再次测试用SQL*Plus登陆,报ORA-01031错误,即使提供正确的SYS用户密码也会报同样的错误,因为此时密码文件不存在,不能通过密码文件校验SYS用户密码是否正确,而又不允许通过NTS方式登陆数据库。
C:\Users\Kamus>sqlplus "NotExist/nopassword@orcl11g as sysdba" SQL*Plus: Release 11.1.0.7.0 - Production on Fri Mar 12 13:14:07 2010 Copyright (c) 1982, 2008, Oracle. All rights reserved. ERROR: ORA-01031: insufficient privileges Enter user-name:
重新创建密码文件,保持sqlnet.ora文件中SQLNET.AUTHENTICATION_SERVICES = (NONE)。
orapwd file=D:\oracle\product\11.1.0\db_1\database\PWDorcl11g.ora password=oracle
这样就只能通过正确的SYS用户和密码才可以用SYSDBA登陆数据库了。
C:\Users\Kamus>sqlplus / as sysdba SQL*Plus: Release 11.1.0.7.0 - Production on Fri Mar 12 13:18:32 2010 Copyright (c) 1982, 2008, Oracle. All rights reserved. ERROR: ORA-01031: insufficient privileges Enter user-name: C:\Users\Kamus> C:\Users\Kamus>sqlplus sys/oracle as sysdba SQL*Plus: Release 11.1.0.7.0 - Production on Fri Mar 12 13:18:44 2010 Copyright (c) 1982, 2008, Oracle. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - Production With the Partitioning, OLAP and Real Application Testing options SQL>
同样在这种配置下,SQL Developer也可以正常用SYSDBA登陆数据库了。
有感于国外Oracle用户组的发达,我跟eygle从今年开始尝试组建中国的Oracle用户组,All China Oracle User Group。我们的站点是acoug.org。
我们希望能够为全中国的Oracle技术爱好者提供一个交流与活动的平台,我们希望能够激发更多人对于Oracle技术以及相关知识的兴趣,我们希望沉浸在这些技术中的人员获得更多的乐趣。这是我跟eygle一直以来的一个理想,但愿我们能为此付出并且有所回报。
我们认识到中国目前掌握Oracle技术的人员广度和深度都跟美国、欧洲甚或是印度存在着较大差距,这需要我们更有热情的去付出,但愿在不久的将来ACOUG在全球Oracle用户组中占据一席之地。
ACOUG计划定期举行线下活动,而线下活动也将是ACOUG未来工作的重点,邀请著名的业内人士(不仅限于国内)来进行主题演讲,并围绕相关主题进行广泛的讨论从而使更多人获益。
eygle的文章有关于ACOUG更多的阐述,请猛击这里。
预计在这个月的3月20日(周六)开展ACOUG第一次线下活动,详细的地点、场地以及演讲主题还未确定,但是请有兴趣的朋友时刻关注ACOUG网站,欢迎参加。
现在个人要注册并且使用一个cn域名,手续需要:
1. 购买域名,付费
2. 付费成功之后提供审核资料(包括一些打印件和身份证的扫描件)
3. 审核通过之后去工信部备案网站中自行备案
4. 备案成功之后域名开通
为此条款我特地致电了国内某域名注册商的客服。
Q:费用计费是从什么时候开始的?
A:从成功付费以后。
Q:那如果工信部备案拖了我几个月都备案不成功,这段时间如何补偿?
A:没有补偿。
Q:如果备案不成功怎么办?
A:那你就重复提交备案申请,总会成功的。
Q:如果我厌倦了备案的繁琐,决定放弃这个域名,既然你们自从我注册了这个域名之后就没有提供任何服务,可以退款吗?
A:抱歉,一旦付费成功了,就无法退款。
cao你大爷,贵国真是威武。老子惹不起总躲得起,本来一直说cn域名还代表咱是中国人,用着挺爱国的,但是从今以后决定不再注册任何cn域名。
做出这个决定,就好比方鸿渐老爹抱怨的那样“他爱国而国不爱他,大有青年守节的孀妇不见宠于翁姑的怨抑”,又跟五折叔说的那样怎么老是有种挥之不去的忧郁感呢?日你个麻哟。
最后看一眼工信部备案管理网站糟糕至极的用户体验。
1. “建议使用:1024 * 768 分辨率”,这种土掉渣的提示应该在进入21世纪以后就很少看到了吧。
2. “刷新验证码”这个链接是假的,毫无用处。不偷工减料会死啊。
3. 每个新网站必须要重新注册新用户才可以备案,即使登陆备案网站是通过用户名而不是网站名。也就是一个名下有10个网站的主办者需要注册10次才可以,这是什么脑子思考出来的模式?
4. 作为一个互联网域名备案的网上办公系统,毫无专业性。为什么“典型问题指南”是用弹出窗口这样被用户诟病了多年的方式来表达?为什么在用户登陆之后页面左侧的树状结构在Firefox和Chrome浏览器里面一团糟完全没法正常使用?
不知道这个网站用了多少钱造出来的,我只想说在如今这个年代大概再差劲的架站初学者应该也会比这个做的好看吧。