IBM / db2-samples

Db2 application code, configuration samples, and other examples
https://www.ibm.com/analytics/developing-with-db2
Apache License 2.0
85 stars 86 forks source link

IBM DB2 is giving wrong database against db2inst2 if there two instances are present on the DB2 11.5 #70

Closed hsc2013 closed 1 year ago

hsc2013 commented 1 year ago

Hello, I have a DB2 system that has two instances. After loading /opt/ibm/db2/V11.5/lib64/libdb2.so, I use db2DbDirOpenScan followed by db2DbDirGetNextEntry to get the database against each instance. An example is shown below.

db2inst1 -> DB1, DB2 database names

db2inst2 -> IDB1, IDB2 database names

We always get database "DB1, DB2" against db2inst2, which is incorrect.

When we tested the aforementioned method on db2 version 11.1, it worked well. It is not compatible with db2 version 11.5.

Do we have any idea what the problem could be with 11.5 or if something has changed in db2 11.5 to retrieve a list of databases in relation to db2DbDirOpenScan and db2DbDirGetNextEntry?

kdrodger commented 1 year ago

Can you describe the scenario a bit more -- are there two databases or four, in total across the two instances?

I'm wondering if there are four DBs, two created in each instance and no additional CATALOG statements issued? Or, are you saying that you have just two databases in total, where both instances have cataloged the two DBs?

Which version number are you passing to each of those APIs? Can you also show the results of a LIST DB DIRECTORY from the Db2 CLP on each instance? Thanks

hsc2013 commented 1 year ago

Hello, Below is output for list db directory

`db2inst1

db2 => list db directory

System Database Directory

Number of entries in the directory = 2

Database 1 entry:

Database alias = DB2 Database name = DB2 Local database directory = /home/db2inst1 Database release level = 15.00 Comment = Directory entry type = Indirect Catalog database partition number = 0 Alternate server hostname = Alternate server port number =

Database 2 entry:

Database alias = DB1 Database name = DB1 Local database directory = /home/db2inst1 Database release level = 15.00 Comment = Directory entry type = Indirect Catalog database partition number = 0 Alternate server hostname = Alternate server port number =

db2inst2 db2 => list db directory

System Database Directory

Number of entries in the directory = 2

Database 1 entry:

Database alias = IDB1 Database name = IDB1 Local database directory = /home/db2inst2 Database release level = 15.00 Comment = Directory entry type = Indirect Catalog database partition number = 0 Alternate server hostname = Alternate server port number =

Database 2 entry:

Database alias = IDB2 Database name = IDB2 Local database directory = /home/db2inst2 Database release level = 15.00 Comment = Directory entry type = Indirect Catalog database partition number = 0 Alternate server hostname = Alternate server port number = ` We have four DBs, and two created in each instance. Further, we have not added any data into DB. We are passing version number db2Version11580 or db2Version1056 but results is same. Also, problem exist only on linux platform.

kdrodger commented 1 year ago

The version passed in should always reflect the version of the client and SDK that were used when the application was built, which may be different than the Db2 client level where it's later executed, and of course distinct from the server which could be remote.

Just experimenting, are you using the 'V9' versions of the API structures (those are the latest), and does your code do something roughly like this?

int main( void )
{
   int rc = 0;

   SQL_API_RC                 apiRc       = 0;
   db2DbDirOpenScanStruct     openStruct  = { 0 };
   db2DbDirNextEntryStructV9  nextEntry   = { 0 };
   db2DbDirCloseScanStruct    closeStruct = { 0 };
   sqlca                      sqlca       = { 0 };

   db2DbDirInfoV9           * dirInfo     = NULL;

   openStruct.piPath = NULL;
   apiRc = db2DbDirOpenScan( db2Version11580, &openStruct, &sqlca );
   nextEntry.iHandle = openStruct.oHandle;

   for (int i=0; i < openStruct.oNumEntries; ++i )
   {
      apiRc = db2DbDirGetNextEntry( db2Version11580, &nextEntry, &sqlca );
      dirInfo = nextEntry.poDbDirEntry;

      printf( "\n" );
      printf( " ALIAS: %.*s\n", sizeof dirInfo->alias, dirInfo->alias );
      printf( "DBNAME: %.*s\n", sizeof dirInfo->dbname, dirInfo->dbname );
      printf( " DRIVE: %.*s\n", sizeof dirInfo->drive, dirInfo->drive );
   }

   closeStruct.iHandle = openStruct.oHandle;
   apiRc = db2DbDirCloseScan( db2Version11580, &closeStruct, &sqlca );

   return rc;
hsc2013 commented 1 year ago

Yes, the code structure is the same as you described. I used the V9 API today, but the results remained the same. it did not solve the issue.

kdrodger commented 1 year ago

You may want to open a support case to get this resolved more quickly, especially if you're certain that your application is always connecting the correct instance, you're sourcing the db2profile for the intended instance, and $DB2INSTANCE is set correctly.

It might be interesting the run a quick experiment to know for sure if the 'I' is somehow being dropped, or if you're retrieving data from the other instance unexpectedly. If you're getting drive data that makes sense and is unique to the instance, maybe you know that already.