/****************************************************************************
** (c) Copyright IBM Corp. 2007 All rights reserved.
**
** The following sample of source code ("Sample") is owned by International
** Business Machines Corporation or one of its subsidiaries ("IBM") and is
** copyrighted and licensed, not sold. You may use, copy, modify, and
** distribute the Sample in any form without payment to IBM, for the purpose of
** assisting you in the development of your applications.
**
** The Sample code is provided to you on an "AS IS" basis, without warranty of
** any kind. IBM HEREBY EXPRESSLY DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR
** IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Some jurisdictions do
** not allow for the exclusion or limitation of implied warranties, so the above
** limitations or exclusions may not apply to you. IBM shall not be liable for
** any damages you suffer as a result of using, copying, modifying or
** distributing the Sample, even if IBM has been advised of the possibility of
** such damages.
*****************************************************************************
**
** SOURCE FILE NAME: dbcfg.sqc
**
** SAMPLE: Configure database and database manager configuration parameters
**
** This sample demonstrates the use of the db2AutoConfig() API
** which configures database and database manager configuration
** parameters. The program configures the sample database in two
** scenarios determined by specifying "1" or "2" as the multinode
** command line parameter (any other value defaults to option "1").
** With option "1", the db2AutoConfig() API automatically configures
** the sample database. The recommendation and diagnostics are
** produced by this API and printed 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 partitions.
**
** DB2 APIs USED:
** db2AutoConfig -- AUTOCONFIG
** db2AutoConfigFreeMemory -- AUTOCONFIG FREE MEMORY
** sqlesetc -- SET CLIENT
** sqlaintp -- SQLCA MESSAGE
**
** SQL STATEMENTS USED:
** INCLUDE
** CONNECT
**
** STRUCTURES USED:
** sqle_conn_setting
** db2AutoConfigInterface
** db2AutoConfigArray
** db2AutoConfigOutput
** db2AutoConfigValues
** sqlca
**
**
*****************************************************************************
**
** For more information on the sample programs, see the README file.
**
** For information on developing embedded SQL applications see the Developing Embedded SQL Applications book.
**
** For information on using SQL statements, see the SQL Reference.
**
** For information on DB2 APIs, see the Administrative API Reference.
**
** For the latest information on programming, building, and running DB2
** applications, visit the DB2 Information Center:
** http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/index.jsp
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sql.h>
#include <sqlutil.h>
#include "db2AuCfg.h"
#include "utilemb.h"
#define NUMSETTINGS 3
#define CHCKERR(s) if (sqlca.sqlcode < 0) { print_err(&sqlca); return -1; }
EXEC SQL INCLUDE SQLCA;
EXEC SQL BEGIN DECLARE SECTION;
char dbName[16];
char userid[30];
char passwd[30];
EXEC SQL END DECLARE SECTION;
/* This procedure prints error information released by the APIs. */
void print_err(struct sqlca *ca)
{
char err[512];
printf("________________ERROR INFO_________________________\n");
/* get error message */
sqlaintp(err, sizeof(err), 80, ca);
printf("%s\n", err);
printf("SQLCODE : %d\n", ca->sqlcode);
printf("SQLERRMC: %s\n", ca->sqlerrmc);
printf("SQLERRP : %s\n", ca->sqlerrp);
printf("_______________END ERROR INFO______________________\n");
return;
} /* print_err */
/* This procedure prints diagnotic information released by the APIs. */
int print_info(db2AutoConfigDiags * Diag)
{
int i = 0;
printf("Token, Value\n");
while (i < (Diag->numElements))
{
printf("%5d %6d\n", (Diag->pElements[i]).token,
(Diag->pElements[i]).value);
i++;
}
return 0;
} /* print_info */
/* Procedure to produce db cfg recommendations produced by the API. */
int print_infodb(struct db2CfgParam *itemList, int num)
{
int i = 0;
printf("Token, Value\n");
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)
{
printf("%5d %6d\n", itemList[i].token, *(int *)itemList[i].ptrvalue);
}
i++;
}
return 0;
} /* print_infodb */
/* Procedure to produce dbm cfg recommendations produced by the API. */
int print_infodbm(struct db2CfgParam *itemList, int num)
{
int i = 0;
printf("Token, Value\n");
while (i < num)
{
int tok = itemList[i].token;
if (/* these are dbm cfg tokens */
tok == SQLF_KTN_NUM_POOLAGENTS || tok == SQLF_KTN_SHEAPTHRES)
{
printf("%5d %6d\n", itemList[i].token, *(int *)itemList[i].ptrvalue);
}
if (/* these are dbm cfg tokens */
tok == SQLF_KTN_ASLHEAPSZ)
{
printf("%5d %6d\n", itemList[i].token, *(short *)itemList[i].ptrvalue);
}
i++;
}
return 0;
} /* print_infodbm */
int main(int argc, char *argv[])
{
struct sqle_conn_setting connSetting[NUMSETTINGS];
SQL_API_RC rc;
struct sqlca sqlca;
db2AutoConfigInterface autoConfigInterface;
int inputCount = 2;
/* input to API */
db2int32 mem_percent; /* 250 percent of server memory used on dbm */
db2int32 workload; /* workload is mixed queries and transactions */
unsigned short token;
int i = autoConfigInterface.oResult.oNewDbmValues.numElements - 1;
if (argc != 5)
{
printf("dbcfg <dbname> <userid> <passwd> <1|2>\n");
return -1;
}
strcpy(dbName, argv[1]);
strcpy(userid, argv[2]);
strcpy(passwd, argv[3]);
printf("\nHOW TO CONFIGURE DATABASE AND DATABASE MANAGER CONFIGURATION ");
printf("PARAMETERS\n");
printf("\n______STARTING AUTOCONF TESTCASE ON INSTANCE "
"OWNING NODE (node 0)\n");
/* 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;
/* set client information */
sqlesetc(&connSetting[0], NUMSETTINGS, &sqlca);
printf("SQLESETC instance owning node\n");
CHCKERR("set client");
}
/* 2 CONNECT TO DATABASE */
EXEC SQL CONNECT TO:dbName USER:userid USING:passwd;
printf("______Connect\n");
CHCKERR("connect db");
/* 3 ENTER PARMS INTO CONFIG API AND INTERFACE */
/* allocate 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;
mem_percent = 25;
workload = 2;
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(db2Version970, &autoConfigInterface, &sqlca);
printf("______DB2AUTOCONFIG_________\n");
CHCKERR("db2autoconfig");
/* 5 PRINT RECOMMENDATION AND DIAGNOSTICS */
if (rc == DB2_SG_RC_OK)
{
printf("NUMBER OF DIAGNOSTICS: %d\n",
autoConfigInterface.oResult.oDiagnostics.numElements);
if (autoConfigInterface.oResult.oDiagnostics.numElements > 0)
{
/* print the diagnostic results */
printf("==> resource values are not optimizable, "
"diagnostics produced:\n");
print_info(&((autoConfigInterface.oResult).oDiagnostics));
printf("___________________\n");
}
if (autoConfigInterface.oResult.oOldDbValues.numElements > 0)
{
/* handle the configuration results */
printf("==> resource values are optimizable "
"recommendations produced:\n");
printf("==> NUMBER OF PRODUCED OLD DB CFG RECOMMENDATIONS: %d\n",
autoConfigInterface.oResult.oOldDbValues.numElements);
printf("==> PRODUCED VALUES\n");
print_infodb(autoConfigInterface.oResult.oOldDbValues.pConfigs,
autoConfigInterface.oResult.oOldDbValues.numElements);
printf("___________________\n");
}
if (autoConfigInterface.oResult.oNewDbValues.numElements > 0)
{
printf("==> NUMBER OF PRODUCED NEW DB CFG RECOMMENDATIONS: %d\n",
autoConfigInterface.oResult.oNewDbValues.numElements);
printf("==> PRODUCED VALUES\n");
print_infodb(autoConfigInterface.oResult.oNewDbValues.pConfigs,
autoConfigInterface.oResult.oNewDbValues.numElements);
printf("___________________\n");
}
if (autoConfigInterface.oResult.oOldDbmValues.numElements > 0)
{
printf("==> NUMBER OF PRODUCED OLD DBM CFG RECOMMENDATIONS: %d\n",
autoConfigInterface.oResult.oOldDbmValues.numElements);
printf("==> PRODUCED VALUES\n");
print_infodbm(autoConfigInterface.oResult.oOldDbmValues.pConfigs,
autoConfigInterface.oResult.oOldDbmValues.numElements);
printf("___________________\n");
}
if (autoConfigInterface.oResult.oNewDbmValues.numElements > 0)
{
printf("==> NUMBER OF PRODUCED NEW DBM CFG RECOMMENDATIONS: %d\n",
autoConfigInterface.oResult.oNewDbmValues.numElements);
printf("==> PRODUCED VALUES\n");
print_infodbm(autoConfigInterface.oResult.oNewDbmValues.pConfigs,
autoConfigInterface.oResult.oNewDbmValues.numElements);
printf("___________________\n");
}
/* 6 FREE MEMORY */
/* must free all the memory allocated by db2AutoConfig() */
db2AutoConfigFreeMemory(db2Version970, &autoConfigInterface, &sqlca);
}
else
{
/* handle error */
printf("ERROR in API CALL\n");
}
/* disconnect from node */
EXEC SQL CONNECT RESET;
printf("_____+CONNECT RESET\n");
CHCKERR("connect reset");
/* IF 5 ARGUMENTS SPECIFIED,
TREAT AS PARTITIONED DATABASE WITH A SECOND PARTITION */
if (atoi(argv[4]) == 2)
{
/* repeat for second partition (Node 1) */
printf("________ OPTION 2 CONFIGURING DATABASE PARTITION RESIDING "
"ON NON INSTANCE OWNING PARTITION (node 1)\n");
/* 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 from node on commit */
connSetting[2].type = SQL_DISCONNECT;
connSetting[2].value = SQL_DISCONNECT_AUTO;
/* set client information */
sqlesetc(&connSetting[0], NUMSETTINGS, &sqlca);
printf("______+SQLESETC 2nd node (NODE 1)\n");
CHCKERR("set client");
/* 2 CONNECT TO DATABASE */
EXEC SQL CONNECT TO :dbName USER :userid USING :passwd;
printf("____________++connect to db\n");
CHCKERR("connect to db");
/* 3 ENTER PARMS INTO API AND INTERFACE */
/* input to smartguide */
mem_percent = 45; /* percentage of memory for dbm server is 34% */
workload = 2; /* workload is mixed with queries and transactions */
inputCount = 2;
/* allocate 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 - this time the configuration parameters
*** are not 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(db2Version970, &autoConfigInterface, &sqlca);
printf("______+DB2AUTOCONFIG_________\n");
CHCKERR("db2 connect to sample");
/* 5 PRINT RECOMMENDATION AND DIAGNOSTITCS */
if (rc == DB2_SG_RC_OK)
{
printf("NUMBER OF DIAGNOSTICS: %d\n",
autoConfigInterface.oResult.oDiagnostics.numElements);
if (autoConfigInterface.oResult.oDiagnostics.numElements > 0)
{
/* handle the diagnostic results */
printf("==>resource values are not optimizable, "
"diagnostics produced: ");
print_info(&((autoConfigInterface.oResult).oDiagnostics));
printf("___________________\n");
}
if (autoConfigInterface.oResult.oOldDbValues.numElements > 0)
{
/* handle the configuration results */
printf("==> resource values are optimizable "
"recommendations produced:\n");
printf("==> NUMBER OF PRODUCED OLD DB CFG RECOMMENDATIONS: %d\n",
autoConfigInterface.oResult.oOldDbValues.numElements);
printf("==> PRODUCED VALUES\n");
print_infodb(autoConfigInterface.oResult.oOldDbValues.pConfigs,
autoConfigInterface.oResult.oOldDbValues.numElements);
printf("___________________\n");
}
if (autoConfigInterface.oResult.oNewDbValues.numElements > 0)
{
printf("==> NUMBER OF PRODUCED NEW DB CFG RECOMMENDATIONS: %d\n",
autoConfigInterface.oResult.oNewDbValues.numElements);
printf("==> PRODUCED VALUES\n");
print_infodb(autoConfigInterface.oResult.oNewDbValues.pConfigs,
autoConfigInterface.oResult.oNewDbValues.numElements);
printf("___________________\n");
}
if (autoConfigInterface.oResult.oOldDbmValues.numElements > 0)
{
printf("==> NUMBER OF PRODUCED OLD DBM CFG RECOMMENDATIONS: %d\n",
autoConfigInterface.oResult.oOldDbmValues.numElements);
printf("==> PRODUCED VALUES\n");
print_infodbm(autoConfigInterface.oResult.oOldDbmValues.pConfigs,
autoConfigInterface.oResult.oOldDbmValues.numElements);
printf("___________________\n");
}
if (autoConfigInterface.oResult.oNewDbmValues.numElements > 0)
{
printf("==> NUMBER OF PRODUCED NEW DBM CFG RECOMMENDATIONS: %d\n",
autoConfigInterface.oResult.oNewDbmValues.numElements);
printf("==> PRODUCED VALUES\n");
print_infodbm(autoConfigInterface.oResult.oNewDbmValues.pConfigs,
autoConfigInterface.oResult.oNewDbmValues.numElements);
printf("___________________\n");
}
/* 6 FREE MEMORY */
/* must free all the memory allocated by db2AutoConfig() */
db2AutoConfigFreeMemory(db2Version970, &autoConfigInterface, &sqlca);
}
else
{
/* handle error */
printf("ERROR in API CALL\n");
}
/* disconnect from node */
EXEC SQL CONNECT RESET;
printf("______CONNECT RESET\n");
CHCKERR("connect reset");
}
return 0;
} /* main */