Showing posts with label Oracle. Show all posts
Showing posts with label Oracle. Show all posts

Wednesday, October 9, 2019

Powerful Excel Utility for DBAs

Excel Utility for DBAs


This Excel utility has been very useful to all my colleagues at different places as well to my other DBA friends. Based on popular demand I am pleased to share this utility with a broader community of DBA team by sharing this to everyone.

This utility is pretty self explanatory. Due to privacy and security reason I have included sample database names. To begin validating this utility, you need to replace sample database names with your database name(s), which you can do by running a macro(ctrl+shift+T) which will read a TNSNames.ora file you provide as input.

Here is the usage included in the Excel file in the "Version" tab.


Usage: This WorkBook is useful for collecting information from multiple  Oracle  or  SQL Server databases in Excel WorkSheet. Initialization of macros  is very dependent on your current cursor (selected cell) position.  Query you enter in C2 and other cell should  NOT contain ";" at the end of the query string. Enhancement has been done to trim the trailing ";", if present. You should always validate that query you are going to execute against multiple database is syntactically correct.
There are couple macros in this WorkBook , most of them have shortcuts too. (Ref: List of Macros)
For collectData Macro:
You can enter multiple queries , one query in its own cell. Starting from C2, C3, C4, etc.
You can specify work sheet name for the  query results, if you omit it will autogenerate one for you. WorkSheetName must be specified in B2, B3, B4, etc. corresponding cells for the queries.
Queries must be followed by header line and then followed by Sr.No and Database Aliases (from your local TNSNAMES.ora file). Please refer to the "Sample" WorkSheet in this WorkBook.
Once ready with this setup press "Ctl+Shift+C" and will display Login Window for the common user name and password across all the databases. If you have separate username and/or password, use  column E and F to specify  username and password respectively. Select environment type; N => for Non Production, P => For production, A => For all environment. Once entered all this information this macro executes all the listed queries in the current WorkSheet for all the databases listed in the current WorkSheet only. All database must be consecutoive without any Blank lies and/or Sr.No.
WorkSheet containing result contains following additional information:
Date and Time in Cell A1.  Row 2 contains header name and Column A contains database name. Query executed is being stored as Comments for Cell A2.
Also, there will be text file generated in the directory where this Excel file with Macro is being stored, (e.g. DB2Excel4DP.xlsm.txt)  which can be used to watch the progress of the execution. It updates this file once it  completes execution for the databse (success/failure).




List of Macros:
MacroName ShortCut Description
collectData Ctl+Shift+C Execute queries and stores result in WorkSheets
compareResults Ctl+Shift+R Execute queries and stores result SideBySide
DeleteCNValidWrkSheet Ctl+Shift+D Delete CN Valid Worksheets (Autogenerated after each execution)
readTNSNamesAndList Ctl+Shift+T Reads TNSNames.ora file from the specified location and list all aliases in a new WorkSheet.

In order to get this file, as of now please feel free to send me email (patel.RiDham at GMail.com) I will share this file with you at the earliest feasible time.

Here is the permanent link to this Excel utility.

If you like this utility please feel free to leave your comments here as well as feel free to leave any suggestions/enhancements.


Monday, April 27, 2015

Change max value for Oracle Sequence

After data refresh/copy from one environment to another, usually developer realizes that they are using sequence and need to change the sequence's max value. To perform this I have developed this handy script:

This script assumes that the executor of this script has DBA (or DBA like privileges). Ability to select from DBA views and alter any sequence.

set serveroutput on

declare
   seq_owner  varchar2(30) := upper('&1');
   seq_name   varchar2(30) := upper('&2');
   desiredVal number := &3;
   oldIncrVal number;
   diff       number;
   newDiff    number;
   sqlStmt    varchar2(4000);
   currSeqVal number;
begin
   select INCREMENT_BY into oldIncrVal from dba_sequences where SEQUENCE_OWNER = seq_owner and SEQUENCE_NAME = seq_name;
   sqlStmt := 'select ' || seq_owner || '.' || seq_name || '.nextval from dual';
   dbms_output.put_line(sqlStmt);
   execute immediate sqlStmt into currSeqVal;
   diff := desiredVal - currSeqVal;
   dbms_output.put_line('alter sequence ' || seq_owner || '.' || seq_name || ' increment by ' || diff);
   execute immediate 'alter sequence ' || seq_owner || '.' || seq_name || ' increment by ' || diff;
   execute immediate sqlStmt into currSeqVal;
   newDiff := desiredVal - currSeqVal;
   dbms_output.put_line('alter sequence ' || seq_owner || '.' || seq_name || ' increment by ' || oldIncrVal);
   execute immediate 'alter sequence ' || seq_owner || '.' || seq_name || ' increment by ' || oldIncrVal;
end;
/


Wednesday, February 26, 2014

Database migration using SAN migration technique

We are planning migrating databases from one RAC to another RAC. For this purpose we are planning to use SAN migration technique.

This is a proof of concept (POC), I will update this BLOG as we make progress.

1. For POC, we will create a new diskgroup [san_poc] on existing RAC.

old01 $ kfod op=disks disks=raw
--------------------------------------------------------------------------------
 Disk          Size Path                                     User     Group
================================================================================
   1:      20473 Mb /dev/oracleasm/disks/ASM_0001            oracle   oinstall
   2:      20473 Mb /dev/oracleasm/disks/ASM_0002            oracle   oinstall
   3:      20473 Mb ORCL:ASM_0001                            <unknown> <unknown>
   4:      20473 Mb ORCL:ASM_0002                            <unknown> <unknown>
old02 $ asmcmd lsdg
State    Type    Rebal  Sector  Block       AU  Total_MB  Free_MB  Req_mir_free_MB  Usable_file_MB  Offline_disks  Voting_files  Name
MOUNTED  EXTERN  N         512   4096  1048576     61440    18734                0           18734              0             Y  DATA1/
MOUNTED  EXTERN  N         512   4096  1048576     40960    40455                0           40455              0             N  FRA1/
old01 $ asmcmd -p
ASMCMD [+] > mkdg '<dg name="san_poc" redundancy="external"><dsk string="/dev/oracleasm/disks/ASM_0001"/><dsk string="/dev/oracleasm/disks/ASM_0002"/></dg>'
ASMCMD [+] > lsdg
State    Type    Rebal  Sector  Block       AU  Total_MB  Free_MB  Req_mir_free_MB  Usable_file_MB  Offline_disks  Voting_files  Name
MOUNTED  EXTERN  N         512   4096  1048576     61440    18734                0           18734              0             Y  DATA1/
MOUNTED  EXTERN  N         512   4096  1048576     40960    40455                0           40455              0             N  FRA1/
MOUNTED  EXTERN  N         512   4096  1048576     40946    40894                0           40894              0             N  SAN_POC/
ASMCMD [+] >

Before we create a new database on this new disk group, we need to mount this new diskgroup on another node:

old02 $ asmcmd -p
ASMCMD [+] > lsdg
State    Type    Rebal  Sector  Block       AU  Total_MB  Free_MB  Req_mir_free_MB  Usable_file_MB  Offline_disks  Voting_files  Name
MOUNTED  EXTERN  N         512   4096  1048576     61440    18734                0           18734              0             Y  DATA1/
MOUNTED  EXTERN  N         512   4096  1048576     40960    40455                0           40455              0             N  FRA1/
ASMCMD [+] > mount san_poc
ASMCMD [+] > lsdg
State    Type    Rebal  Sector  Block       AU  Total_MB  Free_MB  Req_mir_free_MB  Usable_file_MB  Offline_disks  Voting_files  Name
MOUNTED  EXTERN  N         512   4096  1048576     61440    18734                0           18734              0             Y  DATA1/
MOUNTED  EXTERN  N         512   4096  1048576     40960    40455                0           40455              0             N  FRA1/
MOUNTED  EXTERN  N         512   4096  1048576     40946    40851                0           40851              0             N  SAN_POC/
ASMCMD [+] >

2. Create a database: Here I used dbca to create database quickly with all database files - redo log, control files, data files, temp files, etc. are on SAN_POC disk group.

Also, I created a new user and table with couple rows in it. This will help to validate the database status after migration for the end user objects. To keep this post concise, I am omitting details for these trivial tasks. 

For the new database, created a new service using following command:

old01 $ srvctl add service -d poc -s poc_svc -r poc1 -a poc2 -P PRECONNECT -y AUTOMATIC -q TRUE -e select -m basic -z 10 -w 5
old01 $ srvctl status service -d poc
Service poc_svc is not running.
old01 $ srvctl start service -d poc  -s poc_svc
old01 $ srvctl status service -d poc

Service poc_svc is running on instance(s) poc1


3. As a prep work, we can copy database initialization file and password file from ${ORACLE_HOME}/dbs directory to the new cluster. Also, need to create audit dump destination, archive or any other OS directory structure that's used by database.

4. Next step is to shutdown database and un-mount disk group from all the nodes.



srvctl stop database -d poc

ASMCMD [+] > umount san_poc

5. Worked with system admin to detach LUNs from the existing cluster and present them to the new cluster. In this process we identified that there were identical ASM LUN name on both the servers. To resolve this, we renamed LUN using asmlib on one of the existing cluster node. On the other node we used oracleasm scandisks command. DO NOT use "oracleasm deletedisk" command. System admin released LUNs from OS as well as through storage admin console.

LUNs released from the existing cluster were presented to the new cluster. On both the new cluster nodes execute "oracleasm scandisks".

Now, this was the new excitement phase...


6. I logged in to new cluster node. To validate disk is intact, I ran kfed command:

$ kfed dev=/dev/oracleasm/disks/ASM_0005 op=read cnt=1 blknum=0
kfbh.endian:                          1 ; 0x000: 0x01
kfbh.hard:                          130 ; 0x001: 0x82
kfbh.type:                            1 ; 0x002: KFBTYP_DISKHEAD
kfbh.datfmt:                          1 ; 0x003: 0x01
kfbh.block.blk:                       0 ; 0x004: blk=0
kfbh.block.obj:              2147483648 ; 0x008: disk=0
kfbh.check:                  2930213453 ; 0x00c: 0xaea7824d
kfbh.fcn.base:                        0 ; 0x010: 0x00000000
kfbh.fcn.wrap:                        0 ; 0x014: 0x00000000
kfbh.spare1:                          0 ; 0x018: 0x00000000
kfbh.spare2:                          0 ; 0x01c: 0x00000000
kfdhdb.driver.provstr: ORCLDISKASM_0005 ; 0x000: length=16
kfdhdb.driver.reserved[0]:   1598903105 ; 0x008: 0x5f4d5341
kfdhdb.driver.reserved[1]:    892350512 ; 0x00c: 0x35303030
kfdhdb.driver.reserved[2]:            0 ; 0x010: 0x00000000
kfdhdb.driver.reserved[3]:            0 ; 0x014: 0x00000000
kfdhdb.driver.reserved[4]:            0 ; 0x018: 0x00000000
kfdhdb.driver.reserved[5]:            0 ; 0x01c: 0x00000000
kfdhdb.compat:                168820736 ; 0x020: 0x0a100000
kfdhdb.dsknum:                        0 ; 0x024: 0x0000
kfdhdb.grptyp:                        1 ; 0x026: KFDGTP_EXTERNAL
kfdhdb.hdrsts:                        3 ; 0x027: KFDHDR_MEMBER
kfdhdb.dskname:            SAN_POC_0000 ; 0x028: length=12
kfdhdb.grpname:                 SAN_POC ; 0x048: length=7
kfdhdb.fgname:             SAN_POC_0000 ; 0x068: length=12

Hold my breath.... attempt to mount diskgroup.

mount san_poc

And I was successful. Repeated same step on another node. 

7. Now time to making sure that we can start database[POC] that was residing on this diskgroup. Before starting database, added database to the OCR by issuing following commands:

new01 $ srvctl add database -d poc  -o /oracle/orabase/product/11.2.0.3 -c RAC -y AUTOMATIC -p '+SAN_POC/poc/spfilepoc.ora' -a "SAN_POC"
new01 $ srvctl add instance -d poc -i poc1 -n new01
new01 $ srvctl add instance -d poc -i poc2 -n new02
new01 $ srvctl add service -d poc -s poc_svc -r poc1 -a poc2 -P PRECONNECT -y AUTOMATIC -q TRUE -e select -m basic -z 10 -w 5
new01 $ srvctl start database -d poc

I overjoyed this as database started without any issues!!! [Though, I had to create audit dump directory...]. 

8. "LISTENER" parameter needs to be modified in the database server parameter file.

SQL> alter system set remote_listener='new-scan1:1521' sid='*' scope=spfile;

System altered.

SQL> alter system set local_listener='(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=new02-vip)(PORT=1521))))' sid='poc2' scope=spfile;

System altered.

SQL> alter system set local_listener='(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=new01-vip)(PORT=1521))))' sid='poc1' scope=spfile;

Restarted database and was able to connect to this POC database from the remote client.

Summary:

Assumptions:

  • OS and Oracle software binaries are identical on existing as well as target cluster nodes.
  • ASM disk groups doesn't contain voting/OCR files
  • ASM disk groups - planned to migrate contains only database files.
  • ASM disk groups planned to migrate are self-contained within the disk groups being migrated.

Migration Steps:

  1. Identify databases are being migrated.
  2. Collect the database and related database service configuration.
  3. Prepare commands to recreate the services as well adding databases to the OCR on the target cluster.
  4. Copy password files from existing cluster nodes to target cluster nodes.
  5. Copy init files from the existing cluster nodes to the target cluster nodes.
  6. Create entries in /etc/oratab for the databases to be migrated
  7. Shutdown database(s) having files on the disk group being migrated.
  8. Unmount disk group - all the nodes of existing cluster. (umount <DiskGroupName>)
  9. SysAdmin detach SAN LUN from the existing cluster.
  10. SysAdmin presents same LUNs to the new target cluster nodes.
  11. ASM admin/DBA will mount the diskgroup by using asmcmd utility (mount <DiskGroupName>)
  12. Add database to the OCR using commands identified in Step#3.
  13. Start database using srvctl.
  14. Modify local_listener and remote_listener parameter [Node vip and scan name needs to be updated]
  15. Add database service(s), if any identified in Step#2 and Step#3
  16. Modify asm_diskgroups parameter in spfile for all the ASM instances to ensure that DISKGROUPS migrated through SAN migration gets mounted in case of node reboot.