Friday, September 8, 2023

Script for creating a multitenant database with dbca

Prerequisites:
  • You have a valid Oracle 19c installation in a server
  • You have set your Oracle environment already, so that your PATH, ORACLE_SID etc already exists when you execute your script

    The script called run_dbca.sh:
    #!/bin/bash
    start=$(date +%s.%N)
    export GLOGFILE=run_dbca.log
    touch ${GLOGFILE}
    chmod 666 ${GLOGFILE}
    exec 1> ${GLOGFILE} 2>&1
    echo "Now running run_dbca.sh"
    echo "Resetting oratab..."
    echo '' > /etc/oratab
    if [ $? -ne 0 ]; then
     echo "Could not erase oratab. Exit."
     exit 1
    else
     echo "oratab erased. Continuing..."
    fi
    export instanceAlive=`ps -ef| grep pmon | grep -v grep |awk '{ print $8}' | cut -f 3 -d"_"`
    
    if [ ! -z ${instanceAlive} ]; then
     echo "Instance for database $ORACLE_SID is already running. Shut it down first"
     exit 1
    fi
    dbca -createDatabase -responsefile ./${ORACLE_SID}.rsp -silent
    echo "Finished running run_dbca.sh"
    dur=$(echo "$(date +%s.%N) - $start" | bc)
    printf "Total execution time for run_dbca.sh: %.6f seconds\n" $dur
    exit 0
    
    The response file can be seen below. I saved it in a file called cdb.rsp and put it in the same directory.

    I commented out most instructions, as they are not needed.

    The original template db_install.rsp is delivered by default with your oracle installation and resides in your $ORACLE_HOME/install/response.
    #-------------------------------------------------------------------------------
    # Do not change the responseFileVersion diretive!
    #-------------------------------------------------------------------------------
    responseFileVersion=/oracle/assistants/rspfmt_dbca_response_schema_v19.0.0
    gdbName=cdb.oric.no
    sid=cdb
    createAsContainerDatabase=true
    numberOfPDBs=1
    pdbName=pdb1
    useLocalUndoForPDBs=true
    pdbAdminPassword=mysecretpassword
    templateName=New_Database.dbt
    sysPassword=mysyspassword
    systemPassword=mysystempassword
    datafileDestination=/data01/oradata/cdb
    recoveryAreaDestination=/data02/fra
    characterSet=AL32UTF8
    initParams=max_pdbs=3,db_create_file_dest_size=1024GB
    memoryPercentage=75
    automaticMemoryManagement=false
    enableArchive=true
    redoLogFileSize=2048
    dbOptions=JSERVER:false,DV:false,ORACLE_TEXT:false,IMEDIA:false,CWMLITE:false,SPATIAL:false,OMS:false,APEX:false
    
    Execute the script like this:
    ./run_dbca.sh
    
    Follow the progression of the creation in the log run_dbca.log:
    tail -f run_dbca.log
    
    Sources:

    Oracle 19c documentation: About creating a database with dbca

    Oracle 19c documentation: Managing templates with dbca

    Oracle-Base.com: Multitenant : Create and Configure a Pluggable Database (PDB) in Oracle Database 12c Release 1 (12.1) - still a relevant and good source.

    Oracle-base.com: a dbca template

    Oracle-base.com: Database Configuration Assistant (DBCA) : Creating Databases in Silent Mode
  • Solution for [DBT-10317] Specified SID Name (SID) already exists when running dbca

    When running dbca, for example like this:
    dbca -createDatabase -responsefile ./cdb.rsp -silent
    [FATAL] [DBT-10317] Specified SID Name (cdb) already exists.
       ACTION: Specify a different SID Name that does not already exist.
    
    There are two potential reasons for the error:

    1. you have a /etc/oratab which has an entry, for example:
    cdb:/installedsw1/oracle/product/Ora19c:Y
    
    2. your instance is running.

    Solution to case 1: remove entry

    Solution to case 2: shutdown the instance

    Rerun dbca and it will now proceed as expected.

    Thursday, September 7, 2023

    Syntax for switching over a container database using data guard broker

    Here I am switching over a container database called cdb, to the standby server which is running a container database with unique name cdb_stby1.

    First, view the configuration:
    DGMGRL> show configuration
    
    Configuration - DGConfig1
    
      Protection Mode: MaxPerformance
      Members:
      cdb       - Primary database
        cdb_stby1 - Physical standby database
    
    Fast-Start Failover:  Disabled
    
    Configuration Status:
    SUCCESS   (status updated 84 seconds ago)
    
    Perform the switchover:
    DGMGRL> switchover to 'cdb_stby1';
    
    Typical output from a successful switchover:
    Performing switchover NOW, please wait...
    Operation requires a connection to database "cdb_stby1"
    Connecting ...
    Connected to "cdb_stby1"
    Connected as SYSDBA.
    New primary database "cdb_stby1" is opening...
    Operation requires start up of instance "cdb" on database "cdb"
    Starting instance "cdb"...
    Connected to an idle instance.
    ORACLE instance started.
    Connected to "cdb"
    Database mounted.
    Switchover succeeded, new primary is "cdb_stby1"
    
    If I wish to switch back, make sure you log on to whichever server is running your primary database at the time.
    (DO NOT use os authentication with dgmgrl / as sysdba, it will throw an error)
    dgmgrl sys@cdb_stby1 as sysdba
    DGMGRL for Linux: Release 19.0.0.0.0 - Production on Thu Sep 7 15:27:27 2023
    Version 19.20.0.0.0
    
    Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.
    
    Welcome to DGMGRL, type "help" for information.
    Password:
    Connected to "cdb_stby1"
    Connected as SYSDBA.
    DGMGRL> show configuration;
    
    Configuration - DGConfig1
    
      Protection Mode: MaxPerformance
      Members:
      cdb_stby1 - Primary database
        cdb       - Physical standby database
    
    Fast-Start Failover:  Disabled
    
    Configuration Status:
    SUCCESS   (status updated 46 seconds ago)
    
    DGMGRL> switchover to cdb
    Performing switchover NOW, please wait...
    Operation requires a connection to database "cdb"
    Connecting ...
    Connected to "cdb"
    Connected as SYSDBA.
    New primary database "cdb" is opening...
    Operation requires start up of instance "cdb" on database "cdb_stby1"
    Starting instance "cdb"...
    Connected to an idle instance.
    ORACLE instance started.
    Connected to "cdb_stby1"
    Database mounted.
    Switchover succeeded, new primary is "cdb"
    
    

    Thursday, August 31, 2023

    How to extract all datafile names without path using substr and instr functions

    select trim(
                substr(file_name,
                    (instr(file_name,'/', -1, 1) +1)
                    )
                   )  "file name"
    from  dba_data_files;
    
    Result:
    file name
    system01.dbf
    sysaux01.dbf
    undotbs01.dbf
    users01.dbf
    appl_data.dbf

    More on how to display the current container in a multitenant database

    My listener is listening for connections to a service called "myservice1", which runs out of the pluggable database "pdb1":
    lsnrctl status
    Service "pdb1" has 1 instance(s). <-- the default service for the pluggable database
      Instance "cdb", status READY, has 1 handler(s) for this service...
    
    Service "myservice1" has 1 instance(s). <-- service defined by the DBA
      Instance "cdb", status READY, has 1 handler(s) for this service...
    
    In the code snippet below, I am executing a script called disp_session.sql which will

  • connecting directly to a service served by the listener
  • switching schema within my session

    The following will display the username, current schema, and the service my connction is connecting to:
    alter session set current_schema=scott;
    set lines 200
    col service format a20
    col container format a20
    col username format a20
    col "container ID" format a20
    col schemaname format a20
    select sys_context ('userenv','SERVICE_NAME')   service,
           sys_context ('userenv','CON_NAME')       container,
           sys_context ('userenv','CON_ID')         "container ID",
           sys_context ('userenv','CURRENT_USER')   username,
           sys_context ('userenv','CURRENT_SCHEMA') schemaname
    from dual;
    
    oracle@server1.oric.no:[cdb]# sqlplus system@myservice1 @disp_session.sql
    
    Session altered.
    
    SERVICE              CONTAINER            container ID         USERNAME             SCHEMANAME
    -------------------- -------------------- -------------------- -------------------- --------------------
    myservice1           pdb1                 4                    SYSTEM               SCOTT
    
    Useful information when debugging client connections ;-)
  • Friday, August 25, 2023

    How to exchange a line in a text file with a different one, when using double quotation marks in the text itself?

    The following sed command will exchange the string
    initParams=
    
    with
    initParams=undo_tablespace=UNDOTBS1,sga_target=9GB,db_block_size=32768BYTES,control_files=\"\/u02\/oradata\/{DB_UNIQUE_NAME}\/control01.ctl\"\,\"\/recovery\/fra\/{DB_UNIQUE_NAME}\/control01.ctl\"),db_recovery_file_dest=\/recovery\/fra\/{DB_UNIQUE_NAME}
    
    in the file "myresponsefile.rsp":
    sed -i "s/initParams=/initParams=undo_tablespace=UNDOTBS1,sga_target=9GB,db_block_size=32768BYTES,control_files=\"\/u02\/oradata\/{DB_UNIQUE_NAME}\/control01.ctl\"\,\"\/recovery\/fra\/{DB_UNIQUE_NAME}\/control01.ctl\"),db_recovery_file_dest=\/u04\/recovery\/{DB_UNIQUE_NAME} /" myreponse_file.rsp
    
    Note that all double quotes (") and forward (/) slashes must be masked by the backslash charcater \ to be interpreted correctly.

    Tuesday, August 22, 2023

    Cause and solution to ORA-00058: DB_BLOCK_SIZE must be 8192 to mount this database (not 16384)

    You attempt to execute dbca silently, using a response file, as shown below:
    dbca -createDatabase -responsefile mydb01.rsp -silent
    
    But it errors out with the error:
    [WARNING] ORA-00058: DB_BLOCK_SIZE must be 8192 to mount this database (not 16384)
    and the instance is left running, with an unmounted database.

    Cause:

    This means you are using a pre-defined template for dbca that includes datafiles.

    When you do this, you cannot change the db_block_size. It is set to 8K, and carved in stone.

    Solution:

    Create your own, customized template and refer to that instead.

    Remember that templates ending with the extension .dbc contains database files, so they will be significantly faster to use, than custom made templates ending with the extension .dbt - the latter will have to go through the "CREATE DATABASE" statements from scratch.

    Templates that do not contain datafiles have the extension .dbt

    What you can do in order to have your cake and eat it, too, is to first create a database with a non-confirming db_block_size, then create a dbca template based on this new database, including its datafiles.

    I will see if I have time to write a blog post about how to do extactly this.