/******************************************************************************** ** Source File Name = autoconf.sqC ** ** Licensed Materials - Property of IBM ** ** (C) COPYRIGHT International Business Machines Corp. 1995, 2000 ** All Rights Reserved. ** ** US Government Users Restricted Rights - Use, duplication or ** disclosure restricted by GSA ADP Schedule Contract with IBM Corp. ** ** PURPOSE: This sample program demonstrates the use of the ** db2AutoConfig() API. The db2AutoConfig() API configures ** database and database manager configuration parameters. ** Within the sample program, a database is configured ** in two optional scenarios as determined by specifying "1" or ** "2" as the multinode command line paramter (any other value ** will default to option "1"). In the first case, the sample ** database is configured and applied automatically by ** db2AutoConfig() API. The recommendation/diagnostics are ** produced by the db2AutoConfig() API and printed out to ** standard output. By specifying "2" as the multinode command ** line parameter, the db2AutoConfig() API is used to generate ** optimized configuration recommendations for a database on two ** nodes. ** ** ** For more information about these samples see the README file. ** ** For more information on programming in C++, see the ** - "Programming in C and C++" section of the Application Development Guide ** ** For more information on Building C++ Applications, see the: ** - "Building C++ Applications" section of the Application Building Guide. ** ** For more information on the SQL language see the SQL Reference. ** ** ** APIs USED : ** AUTOCONFIG db2AutoConfig() ** AUTOCONFIG FREE MEMORY db2AutoConfigMemory() ** SET CLIENT sqlesetc() ** SQLCA MESSAGE sqlaintp() ** ** STRUCTURES USED : ** sqle_conn_setting ** db2AutoConfigInterface ** db2AutoConfigArray ** db2AutoConfigOutput ** db2AutoConfigValues ** sqlfupd ** sqlca ** ** internal : ** print_info : Displays a diagnostics of system ** print_infodb : Displays a recommendations for db cfg ** print_infodbm : Displays a recommendations for dbm cfg ** alloc_mem : Allocates the proper amount of memory for the ** GET DATABASE CONFIGURATION API to fill with ** data. ** ** external : ** utilemb.sqC Contains functions for error-checking and ** rolling back a transaction in case of error. ** This file must be compiled and its object file ** linked in to the "autoconf" program. ** ** ** EXTERNAL DEPENDENCIES : ** - Ensure existence of database for precompile purposes. ** - Compile and link with the DB2 supported C++ compiler on your platform. ** *********************************************************************************/ #include <stdio.h> #include <iostream.h> #include <iomanip.h> #include <stdlib.h> #include <string.h> #include <sql.h> #include <sqlutil.h> #include "db2AuCfg.h" #include "utilemb.h" EXEC SQL INCLUDE SQLCA; EXEC SQL BEGIN DECLARE SECTION; char dbName[16]; char userid[30]; char passwd[30]; EXEC SQL END DECLARE SECTION; #define NUMSETTINGS 3 #define CHCKERR(s) if (sqlca.sqlcode < 0){ cout << s << ": " <<endl; print_err(&sqlca); return -1; } /************************************************************** This procedure prints error information released by the APIs. **************************************************************/ void print_err(struct sqlca *ca) { cout<<"*****************ERROR INFO***********************"<<endl; char err[512]; sqlaintp(err, sizeof(err), 80, ca); cout << err << endl; cout<<"SQLCODE :"<< ca->sqlcode<<endl; cout<<"SQLERRMC :"<< ca->sqlerrml<<endl; cout<<"SQLERRP :"<< ca->sqlerrp <<endl; cout<<"*****************END ERROR INFO********************"<<endl; return; } /******************************************************************************** This procedure prints diagnostic information released by the db2AutoConfig API. *********************************************************************************/ int print_info(db2AutoConfigDiags *Diag ) { int i =0; cout << " Token, Value " << endl; while( i < Diag->numElements) { cout << (Diag->pElements[i]).token << " " <<(Diag->pElements[i]).value << endl ; i++; } return 0; } /************************************************************************* Procedure to print db cfg recommendations produced by db2AutoConfig API. **************************************************************************/ int print_infodb(struct sqlfupd *itemList, int num) { int i =0; cout << " Token, Value " << endl; while( i < num ) { int tok = itemList[i].token; if( // these are db cfg tokens tok == SQLF_DBTN_BUFF_PAGE || tok == SQLF_DBTN_CATALOGCACHE_SZ || tok == SQLF_DBTN_DFT_DEGREE ) { cout << itemList[i].token << " "<< *(int *)itemList[i].ptrvalue << endl; } i++; } return 0; } /************************************************************************** Procedure to print dbm cfg recommendations produced by db2Autoconfig API. ***************************************************************************/ int print_infodbm(struct sqlfupd *itemList, int num) { int i =0; cout << " Token, Value " << endl; while( i < num ) { int tok = itemList[i].token; if( // these are dbm cfg tokens tok == SQLF_KTN_NUM_POOLAGENTS || tok == SQLF_KTN_SHEAPTHRES ) { cout << itemList[i].token << " "<< *(int *)itemList[i].ptrvalue << endl; } if( // these are dbm cfg tokens tok == SQLF_KTN_ASLHEAPSZ ) { cout << itemList[i].token << " "<< *(short *)itemList[i].ptrvalue << endl; } i++; } return 0; } int main(int argc, char *argv[]) { struct sqle_conn_setting connSetting[NUMSETTINGS]; SQL_API_RC rc; struct sqlca sqlca; db2AutoConfigInterface autoConfigInterface; if ( argc != 5) { cout << "autoconf <dbname> <userid> <passwd> <1|2>" << endl; return -1; } strcpy(dbName, argv[1]); strcpy(userid, argv[2]); strcpy(passwd, argv[3]); cout << "************ STARTING AUTOCONF TESTCASE ON INSTANCE OWNING NODE (node 0) \n" << endl; /*1 set client */ if (atoi(argv[4]) == 2 ) /* need to connect and attach to node if MPP */ { /* attach to node 0 */ connSetting[0].type = SQL_ATTACH_NODE; connSetting[0].value = 0; /* connect to node 0 */ connSetting[1].type = SQL_CONNECT_NODE; connSetting[1].value = 0; /* disconnect from node on commit (implicit when connect reset) */ connSetting[2].type = SQL_DISCONNECT; connSetting[2].value = SQL_DISCONNECT_AUTO; sqlesetc(&connSetting[0], NUMSETTINGS,&sqlca); cout << "+++++++SQLESETC 1st node " << endl; CHCKERR("set client"); } /*2 connect to database */ EXEC SQL CONNECT TO :dbName USER :userid USING :passwd; cout << "+++++++Connect " << endl; CHCKERR("connect db"); /*3 ENTER PARMS INTO CONFIG API AND INTERFACE */ /* input to smartguide */ db2int32 mem_percent = 60; /* specify 60 percent of server memory used on dbm*/ db2int32 workload = 2; /* specify that our workload is mixed queries and transactions*/ int inputCount = 2; /* allocating memory for input parameters */ autoConfigInterface.iParams.pElements = (db2AutoConfigElement *) malloc(sizeof(db2AutoConfigElement) * inputCount); /* set up the interface for calling db2AutoConfig */ autoConfigInterface.iProductID = DB2_SG_PID_DEFAULT; strcpy(autoConfigInterface.iDbAlias, dbName); strcpy(autoConfigInterface.iProductVersion,"1.1"); /**** IMPORTANT: the recommendations are automatically applied to db/dbm cfg ****/ autoConfigInterface.iApply = DB2_SG_APPLY; autoConfigInterface.iParams.numElements = 2; autoConfigInterface.iParams.pElements[0].token = DB2_SG_MEMORY_PERCENTAGE; autoConfigInterface.iParams.pElements[0].value = mem_percent; autoConfigInterface.iParams.pElements[1].token = DB2_SG_WORKLOAD; autoConfigInterface.iParams.pElements[1].value = workload; /*4 AUTOCONFIG CALL */ rc = db2AutoConfig(db2Version710, &autoConfigInterface, &sqlca); cout << "++++++++DB2AUTOCONFIG+++++++++" <<endl; CHCKERR("db2autoconfig"); /*5 PRINT RECOMMENDATION AND DIAGNOSTITCS */ if (rc == DB2_SG_RC_OK) { cout << "NUMBER OF DIAGNOSTICS: " << autoConfigInterface.oResult.oDiagnostics.numElements << endl ; cout <<"==> NUMBER OF PRODUCED NEW DB CFG RECOMMENDATIONS: " << autoConfigInterface.oResult.oNewDbValues.numElements <<endl; cout <<"==> NUMBER OF PRODUCED NEW DBM CFG RECOMMENDATIONS: " << autoConfigInterface.oResult.oNewDbmValues.numElements <<endl; if (autoConfigInterface.oResult.oDiagnostics.numElements > 0) { /* handle the diagnostic results */ cout <<"==>resource values are not optimizable," <<" diagnostics produced: " <<endl; print_info(&((autoConfigInterface.oResult).oDiagnostics) ); cout << " ***************************** "<< endl; } if ( autoConfigInterface.oResult.oOldDbValues.numElements >0 ) { /* handle the configuration results */ cout <<"==> resource values are optimizable " <<" recommendations produced: " << endl; cout <<"==> NUMBER OF PRODUCED OLD DB CFG RECOMMENDATIONS: " << autoConfigInterface.oResult.oOldDbValues.numElements << endl; cout <<"==> PRODUCED VALUES " << endl; print_infodb( autoConfigInterface.oResult.oOldDbValues.pConfigs, autoConfigInterface.oResult.oOldDbValues.numElements ); cout << " ***************************** "<< endl; } if ( autoConfigInterface.oResult.oNewDbValues.numElements >0 ) { cout <<"==> NUMBER OF PRODUCED NEW DB CFG RECOMMENDATIONS: " << autoConfigInterface.oResult.oNewDbValues.numElements << endl; cout <<"==> PRODUCED VALUES " << endl; print_infodb( autoConfigInterface.oResult.oNewDbValues.pConfigs, autoConfigInterface.oResult.oNewDbValues.numElements ); cout << " ***************************** " << endl; } if ( autoConfigInterface.oResult.oOldDbmValues.numElements >0 ) { cout <<"==> NUMBER OF PRODUCED OLD DBM CFG RECOMMENDATIONS: " <<autoConfigInterface.oResult.oOldDbmValues.numElements <<endl ; cout <<"==> PRODUCED VALUES " << endl; print_infodbm( autoConfigInterface.oResult.oOldDbmValues.pConfigs, autoConfigInterface.oResult.oOldDbmValues.numElements ); cout << " ***************************** "<< endl; } if ( autoConfigInterface.oResult.oNewDbmValues.numElements >0 ) { cout <<"==> NUMBER OF PRODUCED NEW DBM CFG RECOMMENDATIONS: " << autoConfigInterface.oResult.oNewDbmValues.numElements << endl ; cout <<"==> PRODUCED VALUES " << endl; print_infodbm( autoConfigInterface.oResult.oNewDbmValues.pConfigs, autoConfigInterface.oResult.oNewDbmValues.numElements ); cout << " ***************************** "<< endl; } /*6 FREE MEMORY */ /* must free all the memory allocated by db2AutoConfig() */ db2AutoConfigFreeMemory(db2Version710,&autoConfigInterface,&sqlca); } else { // handle error cout <<(" ERROR in API CALL \n"); } /* DISCONNECT FROM NODE */ EXEC SQL CONNECT RESET; cout << "+++++++CONNECT RESET " << endl; CHCKERR("connect reset"); /* IF 5 ARGUMENTS SPECIFIED, TREAT AS PARTIONED DATABASE WITH A SECOND NODE */ if (atoi(argv[4]) == 2) { /************************************************/ /***********************************************/ /* REPEAT FOR SECOND NODE (Node 1) */ cout << "************ OPTION 2 CONFIGURING DATABASE PORTION RESIDING ON NON INSTANCE OWNING NODE (node 1) \n" << endl; /*1 set client */ /* ATTACH TO NODE 1 */ connSetting[0].type = SQL_ATTACH_NODE; connSetting[0].value = 1; /* CONNECT TO NODE 1 */ connSetting[1].type = SQL_CONNECT_NODE; connSetting[1].value = 1; /* DISCONNECT TO NODE ON COMMIT */ connSetting[2].type = SQL_DISCONNECT; connSetting[2].value = SQL_DISCONNECT_AUTO; sqlesetc(&connSetting[0], NUMSETTINGS,&sqlca); cout << "+++++++SQLESETC 2nd node (NODE 1)" << endl; CHCKERR("set client"); /*2 connect to database */ EXEC SQL CONNECT TO :dbName USER :userid USING :passwd; cout << "++++++++++++++connect to db" << endl; CHCKERR("connect to db"); /*3 ENTER PARMS INTO API AND INTERFACE */ /* input to smartguide */ mem_percent = 60; /* percentage of memory for dbm server is 60% */ workload = 2; /* workload is mixed with queries and transactions */ inputCount = 2; /* allocating memory for input parameters */ autoConfigInterface.iParams.pElements = (db2AutoConfigElement *) malloc(sizeof(db2AutoConfigElement) * inputCount); /* set up the interface for calling db2AutoConfig */ autoConfigInterface.iProductID = DB2_SG_PID_DEFAULT; strcpy(autoConfigInterface.iDbAlias, dbName); strcpy(autoConfigInterface.iProductVersion,"1.1"); /**** IMPORTANT - the configuration parameters **** are automatically applied *****/ autoConfigInterface.iApply = DB2_SG_APPLY; autoConfigInterface.iParams.numElements = 2; autoConfigInterface.iParams.pElements[0].token = DB2_SG_MEMORY_PERCENTAGE; autoConfigInterface.iParams.pElements[0].value = mem_percent; autoConfigInterface.iParams.pElements[1].token = DB2_SG_WORKLOAD; autoConfigInterface.iParams.pElements[1].value = workload; /*4 AUTOCONFIG CALL */ rc = db2AutoConfig(db2Version710, &autoConfigInterface, &sqlca); cout << "++++++++DB2AUTOCONFIG+++++++++" <<endl; CHCKERR("autoconfig"); /*5 PRINT RECOMMENDATION AND DIAGNOSTITCS */ if (rc == DB2_SG_RC_OK) { cout << "NUMBER OF DIAGNOSTICS: " << autoConfigInterface.oResult.oDiagnostics.numElements << endl ; if (autoConfigInterface.oResult.oDiagnostics.numElements > 0) { /* handle the diagnostic results */ cout <<"==>resource values are not optimizable," <<" diagnostics produced: " <<endl; print_info(&((autoConfigInterface.oResult).oDiagnostics) ); cout << " ***************************** "<< endl; } if ( autoConfigInterface.oResult.oOldDbValues.numElements >0 ) { /* handle the configuration results */ cout <<"==> resource values are optimizable " <<" recommendations produced: " << endl; cout <<"==> NUMBER OF PRODUCED OLD DB CFG RECOMMENDATIONS: " << autoConfigInterface.oResult.oOldDbValues.numElements << endl; cout <<"==> PRODUCED VALUES " << endl; print_infodb( autoConfigInterface.oResult.oOldDbValues.pConfigs, autoConfigInterface.oResult.oOldDbValues.numElements ); cout << " ***************************** "<< endl; } if ( autoConfigInterface.oResult.oNewDbValues.numElements >0 ) { cout <<"==> NUMBER OF PRODUCED NEW DB CFG RECOMMENDATIONS: " << autoConfigInterface.oResult.oNewDbValues.numElements << endl; cout <<"==> PRODUCED VALUES " << endl; print_infodb( autoConfigInterface.oResult.oNewDbValues.pConfigs, autoConfigInterface.oResult.oNewDbValues.numElements ); cout << " ***************************** " << endl; } if ( autoConfigInterface.oResult.oOldDbmValues.numElements >0 ) { cout <<"==> NUMBER OF PRODUCED OLD DBM CFG RECOMMENDATIONS: " << autoConfigInterface.oResult.oOldDbmValues.numElements <<endl ; cout <<"==> PRODUCED VALUES " << endl; print_infodbm( autoConfigInterface.oResult.oOldDbmValues.pConfigs, autoConfigInterface.oResult.oOldDbmValues.numElements ); cout << " ***************************** "<< endl; } if ( autoConfigInterface.oResult.oNewDbmValues.numElements >0 ) { cout <<"==> NUMBER OF PRODUCED NEW DBM CFG RECOMMENDATIONS: " <<autoConfigInterface.oResult.oNewDbmValues.numElements <<endl ; cout <<"==> PRODUCED VALUES " << endl; print_infodbm( autoConfigInterface.oResult.oNewDbmValues.pConfigs, autoConfigInterface.oResult.oNewDbmValues.numElements ); cout << " ***************************** "<< endl; } /*6 FREE MEMORY */ /* must free all the memory allocated by db2AutoConfig() */ db2AutoConfigFreeMemory(db2Version710,&autoConfigInterface,&sqlca); } else { // handle error cout <<(" ERROR in API CALL \n"); } EXEC SQL CONNECT RESET; cout << "+++++++CONNECT RESET " << endl; CHCKERR("connect reset"); } return 0; }