ITPub博客

首页 > Linux操作系统 > Linux操作系统 > [20130701]db link与事务.txt

[20130701]db link与事务.txt

原创 Linux操作系统 作者:lfree 时间:2013-07-01 15:22:35 0 删除 编辑
[20130701]db link与事务.txt

昨天帮别人修复数据库,安全起见,我先启动read only模式,叫他们检查一些相关数据是否正常,但是在程序界面上出现:
ORA-16000: database open for read-only access。

我跟踪发现执行的实际上通过db_link访问远程数据库的语句,不是dml语句(注:实际上执行dml,发生的事务也在远端,不在本地)。按
照这个道理如果数据库在只读的情况下,是不能访问远端的数据库的。

google 发现如下链接:

我回来后在我的机器做一次测试,发现在11g与10g下存在不同。这也解开了我在生产系统看到的一些奇怪情况。

1.建立测试环境:
SQL> @ver
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

--建立db_link,并验证是否正确。
CREATE PUBLIC DATABASE LINK "TESTB.COM"
 CONNECT TO SCOTT
 IDENTIFIED BY 
 USING '192.168.XXX.YYY:1521/orcl';

--启动数据库到read only模式:
SQL> select open_mode from v$database ;
OPEN_MODE
--------------------
READ ONLY

2.开始测试:
$ cat viewredo.sql
SELECT b.NAME, a.statistic#, a.VALUE
  FROM v$mystat a, v$statname b
 WHERE b.NAME IN ('redo size', 'redo wastage','user commits') AND a.statistic# = b.statistic#;

SQL> @viewredo
NAME                 STATISTIC#      VALUE
-------------------- ---------- ----------
user commits                  6          0
redo size                   178          0
redo wastage                183          0

SQL> select XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK,UBAREC,STATUS,xid from v$transaction;
no rows selected

SQL> select sysdate from dual@testb.com;
SYSDATE
-------------------
2013-07-01 09:42:28
--奇怪,居然成功!

SQL> select XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK,UBAREC,STATUS,xid from v$transaction;
no rows selected

SQL> @viewredo
NAME                 STATISTIC#      VALUE
-------------------- ---------- ----------
user commits                  6          0
redo size                   178          0
redo wastage                183          0

--在11G下没有回滚段产生,没有redo产生。

SQL> select dbms_transaction.local_transaction_id()  x from dual ;
X
------------------------------
65535.0.599562215

SQL> select XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK,UBAREC,STATUS,xid from v$transaction;
    XIDUSN    XIDSLOT     XIDSQN     UBAFIL     UBABLK     UBAREC STATUS           XID
---------- ---------- ---------- ---------- ---------- ---------- ---------------- ----------------
        -1          0  599562215          0          0          0 IDLE             FFFF0000E797BC23

SQL> select * from FLASHBACK_TRANSACTION_QUERY where xid=hextoraw('FFFF0000E923393B');
no rows selected

SQL> @viewredo
NAME                 STATISTIC#      VALUE
-------------------- ---------- ----------
user commits                  6          0
redo size                   178          0
redo wastage                183          0

--奇怪,执行select dbms_transaction.local_transaction_id()  x from dual ;为什么会有事务回滚段。
--但是注意看xid*的信息很奇怪,XIDUSN=-1,UBAFIL,UBABLK,UBAREC都是0,按照这个信息,是不应该分配回滚段的。
-- 也就是并没有分配使用回滚段。这样应该也没有产生redo日志。

SQL> select * from dba_rollback_segs where segment_id=-1 ;
no rows selected

SQL> rollback ;
Rollback complete.

SQL> select dbms_transaction.local_transaction_id()  x from dual ;
X
------------------------------

--可以发现在11G(只读模式下)下通过db_link访问远端,没有redo size产生,不会报错。

3.在10G下测试,由于各种原因,我无法设置数据库在read only模式,不过还是能看出问题:
SQL> ver.sql
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi

SQL> column name format a30
SQL> @viewredo.sql

NAME                           STATISTIC#      VALUE
------------------------------ ---------- ----------
user commits                            4          0
redo size                             134          0
redo wastage                          136          0

SQL> select sysdate from dual@mid ;
SYSDATE
-------------------
2013-07-01 11:27:58

SQL> select XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK,UBAREC,STATUS,xid from v$transaction;
    XIDUSN    XIDSLOT     XIDSQN     UBAFIL     UBABLK     UBAREC STATUS           XID
---------- ---------- ---------- ---------- ---------- ---------- ---------------- ----------------
         5         67     414045          0          0          0 ACTIVE           050043005D510600

SQL> @viewredo.sql
NAME                 STATISTIC#      VALUE
-------------------- ---------- ----------
user commits                  4          0
redo size                   134        340
redo wastage                136          0

--很明显在10g下,要通过db_link访问远端数据库,要使用回滚段并且会产生redo。但是注意看UBAFIL,UBABLK,UBAREC都是0.

SQL> select * from FLASHBACK_TRANSACTION_QUERY where xid=hextoraw('050043005D510600');
XID               START_SCN START_TIMESTAMP     COMMIT_SCN COMMIT_TIMESTAMP    LOGON_USER UNDO_CHANGE# OPERATION  TABLE_NAME TABLE_OWNER ROW_ID UNDO_SQL
---------------- ---------- ------------------- ---------- ------------------- ---------- ------------ ---------- ---------- ----------- ---------------
050043005D510600 9672478702 2013-07-01 11:27:58                                XXXX                  1 BEGIN


--这个也是我们生产系统看到的情况。

4.在10G下如何实现不产生日志呢?可以设置回话事务的read only,来避免这个情况。不过估计没人会这么做!

SQL> @ver.sql
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi

SQL> set transaction read only;
Transaction set.

SQL> select XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK,UBAREC,STATUS,xid from v$transaction;
no rows selected

SQL> @viewredo.sql
NAME                 STATISTIC#      VALUE
-------------------- ---------- ----------
user commits                  4          0
redo size                   134          0
redo wastage                136          0

SQL> select sysdate from dual@mid ;
SYSDATE
-------------------
2013-07-01 11:42:00

SQL> @viewredo.sql
NAME                 STATISTIC#      VALUE
-------------------- ---------- ----------
user commits                  4          0
redo size                   134          0
redo wastage                136          0

SQL> select XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK,UBAREC,STATUS,xid from v$transaction;
no rows selected

SQL> select dbms_transaction.local_transaction_id()  c20 from dual ;
C20
--------------------
5.25.414049

SQL> select XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK,UBAREC,STATUS,xid from v$transaction;
    XIDUSN    XIDSLOT     XIDSQN     UBAFIL     UBABLK     UBAREC STATUS           XID
---------- ---------- ---------- ---------- ---------- ---------- ---------------- ----------------
         5         25     414049          0          0          0 ACTIVE           0500190061510600


5.回到11G,打开到read write模式:
SQL> select open_mode from v$database ;
OPEN_MODE
--------------------
READ WRITE

SQL> @viewredo
NAME                 STATISTIC#      VALUE
-------------------- ---------- ----------
user commits                  6          0
redo size                   178        724
redo wastage                183          0

SQL> select XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK,UBAREC,STATUS,xid from v$transaction;

no rows selected

SQL> select sysdate from dual@testb.com;
SYSDATE
-------------------
2013-07-01 12:04:05

SQL> select XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK,UBAREC,STATUS,xid from v$transaction;
    XIDUSN    XIDSLOT     XIDSQN     UBAFIL     UBABLK     UBAREC STATUS           XID
---------- ---------- ---------- ---------- ---------- ---------- ---------------- ----------------
         9         13      15788          0          0          0 ACTIVE           09000D00AC3D0000

SQL> @viewredo
NAME                 STATISTIC#      VALUE
-------------------- ---------- ----------
user commits                  6          0
redo size                   178        980
redo wastage                183          0

SQL> select dbms_transaction.local_transaction_id()  x from dual ;
X
------------------------------
9.13.15788

SQL> select * from FLASHBACK_TRANSACTION_QUERY where xid=hextoraw('09000D00AC3D0000');
XID               START_SCN START_TIMESTAMP     COMMIT_SCN COMMIT_TIMESTAMP  LOGON_USER UNDO_CHANGE# OPERATION  TABLE_NAME TABLE_OWNER ROW_ID UNDO_SQL
---------------- ---------- ------------------- ---------- ----------------- ---------- ------------ ---------- ---------- ----------- ------ --------
09000D00AC3D0000 3237659553 2013-07-01 12:04:04                              SCOTT                 1 BEGIN

--可以发现一样产生日志!

总结:

    DBLINK是远程连接到其他数据库进行访问,这个会涉及到一个事务的关系。但是在11g在read only模式下使用dblink是没有问题的。


    

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/267265/viewspace-765207/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
熟悉oracle相关技术,擅长sql优化,rman备份与恢复,熟悉linux shell编程。

注册时间:2008-01-03

  • 博文量
    2595
  • 访问量
    6371074