0
点赞
收藏
分享

微信扫一扫

insert statements with append hint in archive log

小月亮06 04-14 06:00 阅读 2
数据库

I have a insert statement with append hint in order to do bulk insert.My database is on archive log and force logging mode.I have examined archive logs but i could not any redo

entry for this insert statement. i wonder if i have a standby how will oracle synchronize two databases ?

  •  
    If your database is in FORCE logging, all operations in database will be silently logged and there won't be any exceptions. Any session level or object level NOLOGGING will be silently ignored.

    So your standby database is not impacted at all. It's still in sync with primary. It's standby database aware in an archivelog mode--so no additional care needs to be taken.

    By the way, regarding your statement "I have a insert statement with append hint in order to do bulk insert", I think you meant to say "do bulk insert in direct path load". Append just starts adding records from above the HWM of the table.



    SQL> set autotrace trace expl stat
    Now run the APPEND SQL
    SQL> set autotrace off

     

    SQL>  insert /*+ APPEND */ into t4 select * from dba_objects;

    50337 rows created.

    Statistics

    ----------------------------------------------------------

           1316   recursive calls

            721 db block gets

           5315         consistent gets

              0   physical reads

        5702380   redo size

            808   bytes sent via SQL*Net to client

            748   bytes received via SQL*Net from client

              3   SQL*Net roundtrips to/from client

             17   sorts (memory)

              0   sorts (disk)

          50337   rows processed 


    So as you can see from the above, it's apparent that your DIRECT LOAD statement generated tons of redo (5.7 million). So when the database is in FORCE logging, even if you set NOLOGGING attribute to any objects or if you do direct load, Oracle will ALWAYS generate redo, whatever be the case.

    Hope it's clear now
     

    @ *** ***

    Want to make use of the nologging option in direct-path-insert.

    1)
    a. create a table with attribute NOLOGGING
    b. insert /*+ append */ .....
    this results in a modified unrecoverable_time in v$datafile - as expected

    2)
    a. alter table test logging
    b. insert /*+ append nologging */ ... or ... insert /*+ append */ nologging
    Would have expected that unrecoverable_time had changed after issuing this command, but it didn't.
    Is No.2 really no NOLOGGING-Operation or is just unrecoverable_time not adjusted as it should.

    SOLUTION

    The above is expected behaviour.

    In a direct path insert, you can specify or rather control the logging by specifying the logging attribute of the table or the tablespace where the table resides.

    insert /*+ append */ nologging is wrong syntax -----> gives error
    insert /*+ append */ nologging into my_obj1 select * from dba_objects where rownum < 100
    *
    ERROR at line 1:
    ORA-00925: missing INTO keyword


    Please refer the following manual
    Database Concepts

    Direct-Path INSERT

    Relevant portion reproduced here.

    --QUOTE--
    "
    Direct-Path INSERT and Logging Mode
    Direct-path INSERT lets you choose whether to log redo and undo information during the insert
    operation.

    You can specify logging mode for a table, partition, index, or LOB storage at create time (in a
    CREATE statement) or subsequently (in an ALTER statement).
    If you do not specify either LOGGING or NOLOGGING at these times:
    The logging attribute of a partition defaults to the logging attribute of its table.
    The logging attribute of a table or index defaults to the logging attribute of the tablespace in
    which it resides.
    The logging attribute of LOB storage defaults to LOGGING if you specify CACHE for LOB storage. If
    you do not specify CACHE, then the logging attributes defaults to that of the tablespace in which
    the LOB values resides.
    You set the logging attribute of a tablespace in a CREATE TABLESPACE or ALTER TABLESPACE
    statements. "

    --UNQUOTE---

    There is no such hint mentioned for nologging in the direct path insert.

    You will have to define the logging attributes at partition level --> table level --> tablespace level etc.
    So, the case-2 is really a logging operation as the table is in logging mode.

PURPOSE

This bulletin describes how to tell if the 'direct-load insert' 
feature has been used when using the INSERT /*+ APPEND */ command.


SCOPE & APPLICATION

All users.


Both the serial and parallel version of:

INSERT /*+ APPEND */ INTO ... SELECT ...FROM ... 

uses the same quick interface as Direct Load under some conditions.
Conditions are listed in Concepts Guide.

How can one to tell if direct insert feature is used or not?

a)From the same session:

If after the INSERT /*+ APPEND */ ... statement but within the same 
transaction we try to select from the table, the ORA-12838 error should 
return:                                                          
                                    
insert /*+ APPEND */ into emp                                                   
  select empno, ename, job, mgr, hiredate, sal, comm, deptno+50                
   from emp where deptno<50;   

select count(*) from emp where rownum<10;                                                       
ERROR at line 1:                                                                
ORA-12838: cannot read/modify an object after modifying it in parallel          

                                                      
b) The table locks are different. 
If session A (session_id=10) executes an insert command:
insert  into emp                                                   
  select empno, ename, job, mgr, hiredate, sal, comm, deptno+50                
   from emp where deptno<50;   

Then from session B you can see:
select lock_type, mode_held  from dba_locks where session_id=10
LOCK_TYPE                  MODE_HELD
-------------------------- ----------------------------------------
Transaction                Exclusive
DML                        Row-X (SX)

If session A (session_id=10) executes an insert command:
insert /*+ APPEND */ into emp                                                   
  select empno, ename, job, mgr, hiredate, sal, comm, deptno+50                
   from emp where deptno<50;   

Then from session B you can see:
select lock_type, mode_held  from dba_locks where session_id=10
LOCK_TYPE                  MODE_HELD
-------------------------- -----------
Transaction                Exclusive
DML                        Exclusive


a) Any serial or parallel statements attempting to access a table that has 
already been modified by a direct-load INSERT (or parallel DML) within the 
same transaction are rejected with an error message. 

b) Locking Considerations 
In direct-load INSERT, exclusive locks are obtained on the table (or on all 
the partitions of a partitioned table) precluding any concurrent insert, 
update, or delete on the table. Concurrent queries, however, are supported and 
will see only the data in the table before the INSERT began. These locks also 
prevent any concurrent index creation or rebuild operations. This must be taken
into account before using direct-load INSERT because it affects table 
concurrency. 

Note that if the initialization parameter ROW_LOCKING=INTENT, then inserts 
will not be performed by direct-load path.
 

References
----------

ORA-12838: cannot read/modify an object after modifying it in parallel 代表生效了!!
 

SYMPTOMS

In 11.1 or later , using the /*+ APPEND */ or hint /*+ APPEND_VALUES */ to do direct path insert , TM Enqueue Contention occurs.

CHANGES

Upgraded to an 11.1 or later database

CAUSE

Change in the behavior  of the APPEND hint (Direct Path Insert) 
 

SOLUTION


It is explained in documentation that direct-path insert obtains exclusive locks on the table:
 

During direct-path INSERT, the database obtains exclusive locks on the table (or on all partitions of a partitioned table). As a result, users cannot perform any concurrent insert, update, or delete operations on the table, and concurrent index creation and build operations are not permitted. Concurrent queries, however, are supported, but the query will return only the information before the insert operation.
 


The behavior of /*+ APPEND */ hint has changed in the different versions of Oracle:

  • In Oracle 10g and previous releases the APPEND hint is ignored when specifying INSERT..VALUES. Thus even though stated, the insert will be done in conventional mode and not use direct-path insert into the buffer cache. When using INSERT..SELECT the hint will be honored.
     
  • On 11g Release 1, the APPEND hint will be honored for an INSERT with VALUES and the row will be inserted directly into datafiles, bypassing the buffer cache.
     
  • In 11g release 2, a new hint has been added, /*+ APPEND_VALUES */ that will load the data directly into the datafiles.

To summarize, there are now 2 different hints for direct-path load:

  • APPEND: Instructs Oracle to use direct-path INSERT with the subquery syntax of the INSERT statement.
  • APPEND_VALUES: Instructs Oracle to use direct-path INSERT with the VALUES clause.


The following examples clarify the behavior explained above:
 

INSERT .. VALUES and APPEND HINT

Version: 10.2.0.4

--SID=159: 
SQL> create table test_insert (id number, name varchar2(25)); 
SQL> insert /*+ APPEND */ into test_insert values (1,'Test1'); 
1 row created. 
 
SQL> select sid,type,id1,id2,lmode from v$lock where sid=159; 
SID        TY ID1        ID2        LMODE 
---------- -- ---------- ---------- ---------- 
159        TM 61245      0             3 
159        TX 262153     3571          6

APPEND hint ignored and lock mode=3 Row Exclusive

Version: 11.1.0.7

--SID=131:
SQL> create table test_insert (id number, name varchar2(25));
SQL> insert /*+ APPEND */ into  test_insert  values (1,'Test1');

1 row created.

SQL> select sid,type,id1,id2,lmode from v$lock where sid=131;


        SID TY        ID1        ID2      LMODE
---------- -- ---------- ---------- ----------
       131 TM      84239          0          6
       131 TX      65548       4981          6

APPEND hint honored and lock mode=6 Exclusive

Version: 11.2.0.3

--SID=59
SQL> create table test_insert (id number, name varchar2(25));
SQL> insert /*+ APPEND */ into  test_insert  values (1,'Test1');

1 row created.

select sid,type,id1,id2,lmode from v$lock where sid=59;

       SID TY        ID1        ID2      LMODE
---------- -- ---------- ---------- ----------
        69 TM      96843          0          3
        69 TX     196640       3301          6

APPEND hint ignored and lock mode=3 Row Exclusive

INSERT .. VALUES and APPEND_VALUES HINT

Version: 11.2.0.3

--SID=134
SQL> create table test_insert (id number, name varchar2(25));
SQL> insert /*+ APPEND_VALUES */ into  test_insert  values (1,'Test1');

1 row created.

SQL> select sid,type,id1,id2,lmode from v$lock where sid=134;

       SID TY        ID1        ID2      LMODE
---------- -- ---------- ---------- ----------
       134 TM      96843          0          6
       134 TX      65565       7849          6

New APPEND_VALUES  hint honored and lock mode=6 Exclusive

INSERT .. SELECT and APPEND HINT

All Versions

--SID=77
SQL> insert  /*+ APPEND */ into  test_insert select object_id,object_name from user_objects;

59 rows created.

SQL> select sid,type,id1,id2,lmode from v$lock where sid=77;

       SID TY        ID1        ID2      LMODE
---------- -- ---------- ---------- ----------
        77 TM      96843          0          6
        77 TX     589827       8029          6

APPEND hint honored and lock mode=6 Exclusive 代表生效

--------If the transaction begins using XA or OCI, it executes serially.

SYMPTOMS

Attempting to execute a parallel DML statement from an ODP.NET application using the APPEND or PARALLEL hint executes serially.

DML:
 

EXECUTE IMMEDIATE 'alter session enable parallel dml';
EXECUTE IMMEDIATE 'alter session enable parallel query';
INSERT /*+ APPEND PARALLEL */ into TABLE_DESTINATION SELECT /*+ PARALLEL*/ FROM TABLE_SOURCE


The same DML executes in Parallel when executed in SQL PLUS.

CHANGES

CAUSE

The Oracle Data Provider for .Net sets "Enlist=true" by default as a property of the connection string. This makes OCI calls which allows the the DML or transactions to become or be promoted to a distributed transaction (Oracle Services for Microsoft Transaction Server / XA ).

This is documented in: 

Oracle® Database Administrator's Guide11g Release 2 (11.2) documentation

under the section:

What Are Distributed Transactions?

It states the following restrictions:
 

DML and DDL Transactions
...
If the transaction begins using XA or OCI, it executes serially.


By default, the Oracle Data Provider for .Net sets Enlist=true as a property in the connection string.  This property forces the database to execute the DML serially even when the hints are present. By setting the property enlist=false in the connection string, the database executes the DML in parallel as expected.

SOLUTION

Set enlist=false as a property in the connection string.

举报

相关推荐

0 条评论