18 August, 2019

Blog Series on 12cR1 RAC

A series of posts in 2017 on 12cR1 RAC :

1.  1. Grid  Infrastructure Install  (Dec-16)

2.  2. Convert AdminManaged Database to PolicyManaged   (Dec-16)

3.  3. Convert PolicyManaged Database back to AdminManaged   (Jan-17)

4.  4. Adding a Disk of a Different Size  (Jan-17)

5.  5. Relocating OCR and VoteDisk  (Jan-17)

6.  6. Running the Cluster Verification Utility  (Feb-17)

7.  7. OCR Commands  (Mar-17)

8.  8a. Setting Up Single Instance DG Standby for RAC  (Mar-17)

9.  8b. DUPLICATE DATABASE FOR STANDBY  (Mar-17)

10.  8c. Ignorable "Errors" During the DUPLICATE  (Mar-17)

11.  8d. Registering the two databases in DataGuard Broker  (Mar-17)

12.  8e. Redo Shipping and Apply (RAC to nonRAC)  (Apr-17)

13.  8f. Accessing Data in the PDB in the Standby  (Apr-17)

14.  8g. Switchover from RAC Primary to SingleInstance Standby  (Apr-17)

15.  8h. DataGuard Switchover (RAC to nonRAC) messages  (Apr-17)

16.  8i. Switchback from SingleInstance to RAC  (Apr-17)

17.  9. Adding a Service to a PDB in RAC  (Apr-17)

18.  10. Video on Database Startup  (May-17)



Basic Replication -- 2a : Elements for creating a Materialized View

The CREATE MATERIALIZED VIEW statement is documented here.  It can look quite complex so I am presenting only the important elements here.  In this post, I begin with only the basic elements.

(EDIT: These SQL operations, queries and results were in a 19c Database)

First, I recreate the SOURCE_TABLE properly, with a Primary Key :

SQL> drop table source_table;

Table dropped.

SQL> create table source_table
  2  (id  number not null,
  3   data_element_1 varchar2(15),
  4   data_element_2 varchar2(15),
  5   date_col date)
  6  /

Table created.

SQL> create unique index source_table_pk
  2  on source_table(id);

Index created.

SQL> alter table source_table
  2  add constraint source_table_pk
  3  primary key (id)
  4  /

Table altered.

SQL>


Then I create a Materialized View Log on SOURCE_TABLE.  This will capture all DML against this table and will be read by the target Materialized View to identify "changed" rows at every refresh.

SQL> create materialized view log on source_table;

Materialized view log created.

SQL>


I then identify the objects that were created.

SQL> select object_id, object_name, object_type
  2  from user_objects
  3  where created > sysdate-1
  4  order by object_id
  5  /

 OBJECT_ID OBJECT_NAME                    OBJECT_TYPE
---------- ------------------------------ -----------------------
     73055 SOURCE_TABLE                   TABLE
     73056 SOURCE_TABLE_PK                INDEX
     73057 MLOG$_SOURCE_TABLE             TABLE
     73058 RUPD$_SOURCE_TABLE             TABLE
     73059 I_MLOG$_SOURCE_TABLE           INDEX

SQL>
SQL> desc mlog$_source_table;
 Name                                                                     Null?    Type
 ------------------------------------------------------------------------ -------- -------------------------------------------------
 ID                                                                                NUMBER
 SNAPTIME$$                                                                        DATE
 DMLTYPE$$                                                                         VARCHAR2(1)
 OLD_NEW$$                                                                         VARCHAR2(1)
 CHANGE_VECTOR$$                                                                   RAW(255)
 XID$$                                                                             NUMBER

SQL> desc rupd$_source_table;
 Name                                                                     Null?    Type
 ------------------------------------------------------------------------ -------- -------------------------------------------------
 ID                                                                                NUMBER
 DMLTYPE$$                                                                         VARCHAR2(1)
 SNAPID                                                                            NUMBER(38)
 CHANGE_VECTOR$$                                                                   RAW(255)

SQL>


Interesting that the "CREATE MATERIAIZED VIEW LOG" statement created 3 database objects.

What happens after I perform DML on the SOURCE_TABLE ?

SQL> insert into source_table
  2  values (1,'First','One',sysdate);

1 row created.

SQL> insert into source_table
  2  values (2,'Second','Two',sysdate);

1 row created.

SQL> commit;

Commit complete.

SQL> delete source_table
  2  where id=2
  3  /

1 row deleted.

SQL>
SQL> commit;

Commit complete.

SQL> select * from mlog$_source_table;

        ID SNAPTIME$ D O
---------- --------- - -
CHANGE_VECTOR$$
------------------------------------------------------------------------------------------------------------------------------------
     XID$$
----------
         1 01-JAN-00 I N
FE
2.8158E+14

         2 01-JAN-00 I N
FE
2.8158E+14

         2 01-JAN-00 D O
00
2.5334E+15


SQL>
SQL> select * from rupd$_source_table;

no rows selected

SQL>


So the MLOG$_SOURCE_TABLE is the log that captures 2 INSERT statements and 1 DELETE statement.  (OR is it 2 INSERT *rows* and 1 DELETE *row* ??)
We don't know what the RUPD$_SOURCE_TABLE captures yet.

Let me create a Materialized View and then query MLOG$_SOURCE_TABLE (which is the "MV Log")

SQL> create materialized view
  2  mv_of_source
  3  refresh fast on demand
  4  as select * from source_table
  5  /

Materialized view created.

SQL> select * from mv_of_source
  2  /

        ID DATA_ELEMENT_1  DATA_ELEMENT_2  DATE_COL
---------- --------------- --------------- ---------
         1 First           One             18-AUG-19

SQL>
SQL> select * from mlog$_source_table;

no rows selected

SQL>


So, the CREATE MATERIALIZED VIEW statement has also done a cleanup of the MV Log entries with a SNAPTIME$ older than when it was created.

Let me insert two new rows and then refresh the Materialized View and check the MV Log again.

SQL> insert into source_table
  2  values (3,'Third','Three',sysdate);

1 row created.

SQL> insert into source_table
  2  values (4,'Fourth','Four',sysdate);

1 row created.

SQL> commit;

Commit complete.

SQL> select * from mlog$_source_table;

        ID SNAPTIME$ D O
---------- --------- - -
CHANGE_VECTOR$$
------------------------------------------------------------------------------------------------------------------------------------
     XID$$
----------
         3 01-JAN-00 I N
FE
1.6889E+15

         4 01-JAN-00 I N
FE
1.6889E+15


SQL>
SQL> execute dbms_mview.refresh('MV_OF_SOURCE');

PL/SQL procedure successfully completed.

SQL> select * from mlog$_source_table;

no rows selected

SQL> select * from mv_of_source;

        ID DATA_ELEMENT_1  DATA_ELEMENT_2  DATE_COL
---------- --------------- --------------- ---------
         1 First           One             18-AUG-19
         3 Third           Three           18-AUG-19
         4 Fourth          Four            18-AUG-19

SQL>


So, the 2 single-row INSERTs did create two entries in the MV Log and the REFRESH of the Materialized View did a cleanup of those two entries.

I haven't yet explored :
a.  UPDATEs
b. Multi-Row Operations

16 August, 2019

Basic Replication -- 1 : Introduction

Basic Replication, starting with Read Only Snapshots has been available in Oracle since  V7.   This was doable with the "CREATE SNAPSHOT" command.

In 8i, the term was changed from "Snapshot" to "Materialized View"  and the "CREATE MATERIALIZED VIEW" command was introduced, while "CREATE SNAPSHOT" was still supported.

Just as CREATE SNAPSHOT is still available in 19c,  DBMS_SNAPSHOT.REFRESH is also available.


























Not that I recommend that you use CREATE SNAPSHOT and DBMS_SNAPSHOT anymore.  DBAs and Developers should have been using CREATE MATERIALIZED VIEW and DBMS_REFRESH since 8i.

In the next few blog posts (this will be a very short series) I will explore Basic Replication.  Let me know if you want to see it in 11.2 and 12c as well.


EDIT :  As I had only presented a screen-shot earlier, I am pasting in the commands from an SQLPlus session here :

SQL*Plus: Release 18.0.0.0.0 - Production on Sun Aug 18 16:19:21 2019
Version 18.3.0.0.0

Copyright (c) 1982, 2018, Oracle.  All rights reserved.

Enter user-name: hemant/hemant@orclpdb1
Last Successful login time: Sun Aug 18 2019 16:17:48 +08:00

Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0

SQL> create table source_table as select * from dba_objects;

Table created.

SQL> create snapshot mv_of_source as select * from source_table;

Materialized view created.

SQL> select count(*) from source_table;

  COUNT(*)
----------
     72355

SQL> select count(*) from mv_of_source;

  COUNT(*)
----------
     72355

SQL> insert into source_table select * from source_table;

72355 rows created.

SQL> dbms_snapshot.refresh('MV_OF_SOURCE');
SP2-0734: unknown command beginning "dbms_snaps..." - rest of line ignored.
SQL> execute dbms_snapshot.refresh('MV_OF_SOURCE');

PL/SQL procedure successfully completed.

SQL> select  count(*) from mv_of_source;

  COUNT(*)
----------
    144710

SQL> select object_id, object_type from user_objects where object_name = 'MV_OF_SOURCE';

 OBJECT_ID OBJECT_TYPE
---------- -----------------------
     73051 TABLE
     73052 MATERIALIZED VIEW

SQL> drop materialized view mv_of_source;

Materialized view dropped.

SQL> select object_id, object_type from user_objects where object_name = 'MV_OF_SOURCE';

no rows selected

SQL>


As you can see, even if I use the "CREATE SNAPSHOT" command, the data dictionary shows that it is a Materialized View.  OBJECT_ID 73051 is the actual table created by Oracle to "store" the rows of the Materialized View while 73052 is the definition of the Materialized View.



08 August, 2019

2million PageViews


This blog has now achieved 2million PageViews :




(The "drop" at the end is the count for only the first week of August 2019).

Although this blog began in December 2006, the PageViews counts start with 8,176 in July 2010.  So, effectively, this blog has had 2million PageViews in 9years.

The first 1million PageViews were achieved in March 2015.

Unfortunately, the rate at which I have been publishing has declined since 2017 (36 posts in 2017, 30 in 2018 and only 8 so far this year).  I apologise for this.  Hopefully, I should be able to add more posts in the coming months.