AlephZarro has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks.

I'm using DBD::Oracle to make a connection to our Oracle databases. The connection definition includes multiple hosts and a LOAD_BALANCE=on directive (the tnsnames.ora definition follows)

prod_01 =
 (DESCRIPTION = (ADDRESS_LIST = 
     (ADDRESS = (PROTOCOL = TCP)(HOST = rac-host01)(PORT = 1521))
     (ADDRESS = (PROTOCOL = TCP)(HOST = rac-host02)(PORT = 1521))
     (ADDRESS = (PROTOCOL = TCP)(HOST = rac-host03)(PORT = 1521))
     (ADDRESS = (PROTOCOL = TCP)(HOST = rac-host04)(PORT = 1521))
     (ADDRESS = (PROTOCOL = TCP)(HOST = rac-host05)(PORT = 1521))
     (ADDRESS = (PROTOCOL = TCP)(HOST = rac-host06)(PORT = 1521))
     (ADDRESS = (PROTOCOL = TCP)(HOST = db0-vip-01)(PORT = 1521))
     (ADDRESS = (PROTOCOL = TCP)(HOST = db0-vip-02)(PORT = 1521))
     (ADDRESS = (PROTOCOL = TCP)(HOST = db0-vip-03)(PORT = 1521))
     (LOAD_BALANCE = yes))
   (CONNECT_DATA =(SERVICE_NAME = production.example.com)))

My connections complete successfully but I'm having intermittent failures with the query I'm running (the same query will fail roughly 1 in 9 times).

#!/usr/bin/perl -w use DBI; use DBD::Oracle qw(:ora_types); use Carp; use strict; my $dbh = DBI->connect( 'dbi:Oracle:prod_01', $ENV{PROD_DB_USER}, $ENV{PROD_DB_PASS} ) or croak "Unable to connect: $DBI::errstr"; my $sth = $dbh->prepare( "select * from prod.t_connection_ports order +by client_id" ); $sth->execute; printf( "\n%-15s %10s %10s %10s %-30s \n\n", "Client","Port","Client ID","Status","Machine ID"); while ( my $row = $sth->fetchrow_arrayref ) { printf( "%-15s %10s %10s %10s %-30s \n", @$row[3],@$row[2],@$row[0],@$row[4],@$row[1]); }

I'd like to interrogate the DBI database handle to identify which of the hosts in the definition list I've been connected to see if there's a correlation between a given host and the query failure.

Is there a way to identify the Oracle host to which I've been connected? I see nothing in DBI or DBD::Oracle docs which might give me this information.

Any pointers in the right direction would be greatly appreciated.

-- AZ

Replies are listed 'Best First'.
Re: Identify host connected to in DBD::Oracle connection?
by marto (Cardinal) on Sep 28, 2009 at 15:51 UTC

    Would doing something like select host_name from v$instance; be any help?

    Martin

      Doesn't seem to allow querying the v$ views
      DBD::Oracle::db prepare failed: ORA-00942: table or view does not exis +t (DBD ERROR: error possibly near <*> indicator at char 22 in 'select + host_name from <*>v$instance')

        You will need to get your DBA to grant read only access to v$. Something like:

        grant select on sys.v_$instance to yourusername

        Either get them to do it or consult the Oracle documentation

        Martin

Re: Identify host connected to in DBD::Oracle connection?
by kennethk (Abbot) on Sep 28, 2009 at 16:28 UTC
    I think you can get what you want from the Name attribute. From DBI:

    Holds the "name" of the database. Usually (and recommended to be) the same as the "dbi:DriverName:..." string used to connect to the database, but with the leading "dbi:DriverName:" removed.

    This can be accessed as:

    $handle->{Name}

    Update: Does not meet spec -> only accesses local value (see below).

      Hi.

      print "Name: $dbh->{Name}\n"; returns Name: prod_01 which is the database name.

      I'm hoping I might be able to determine the hostname used for the connection (which one of the nine hosts listed in the tnsnames.ora definition was used for this connection).

        That's what I get for reading too fast. How about trying a get_info call on SQL_SERVER_NAME? I've verified the following against an Oracle database I have access to, but not in a multiple hosts/load balance context.

        #!/usr/bin/perl use strict; use warnings; use DBI; use DBI::Const::GetInfoType; my $_db_name = 'host'; my $_db_user = 'name'; my $_db_pass = 'password'; my @_dbi_path = ("dbi:Oracle:$_db_name",$_db_user,$_db_pass); my $handle = DBI->connect( @_dbi_path, { PrintError => 1, RaiseError => 0, AutoCommit => 0 } ); #print join "\n", sort keys %GetInfoType; print $handle->get_info($GetInfoType{SQL_SERVER_NAME});

        See DBI::Const::GetInfoType and get_info in DBI.

        Update: Still no dice -> in DBD::Oracle, this is just a synonym for $handle->{Name}, as is SQL_DATA_SOURCE_NAME.