Capturing a database snapshot from a client application

You can capture database snapshots using the snapshot monitor API in a C, C++, or a COBOL application. In C and C++ a number of different snapshot request types can be accessed by specifying certain parameters in db2GetSnapshot().

Before you begin

You must have SYSADM, SYSCTRL, SYSMAINT, or SYSMON authority to use the db2MonitorSwitches API.

You must have an instance attachment to capture a database snapshot. If there is not an attachment to an instance, then a default instance attachment is created. To obtain a snapshot of a remote instance, you must first attach to that instance.

Procedure

  1. Optional: Set and check the status of the monitor switches.
  2. Include the following DB2® libraries: sqlmon.h and db2ApiDf.h. These are found in the include subdirectory under sqllib.
    #include <db2ApiDf.h>
    #include <sqlmon.h>
    
  3. Set snapshot buffer unit size to 100 KB.
    #define SNAPSHOT_BUFFER_UNIT_SZ 102400
    
  4. Declare the sqlca, sqlma, db2GetSnapshotData, and sqlm_collected structures. Also, initialize a pointer to contain the snapshot buffer, and establish the buffer's size.
    struct sqlma *pRequestedDataGroups;
    struct sqlca sqlca;
    memset (&sqlca, '\0', sizeof(struct sqlca));
    struct sqlm_collected collectedData;
    memset (&collectedData, '\0', sizeof(collectedData));
    db2GetSnapshotData getSnapshotParam;
    memset (&getSnapshotParam, '\0', sizeof(getSnapshotParam));
    
    static sqluint32 snapshotBufferSize = SNAPSHOT_BUFFER_UNIT_SZ;
    sqluint32 outputFormat;
    char *snapshotBuffer;
    
  5. Initialize the sqlma structure and specify that the snapshot to be captured is of database manager level information.
    pRequestedDataGroups = (struct sqlma *)malloc(SQLMASIZE(1));
    memset(pRequestedDataGroups, '\0', SQLMASIZE(1));
    pRequestedDataGroups->obj_num = 1;
    pRequestedDataGroups->obj_var[0].obj_type = SQLMA_DB2;
    
  6. Initialize the buffer which is to hold the snapshot output.
    snapshotBuffer = (char *)malloc(snapshotBufferSize);
    memset (snapshotBuffer, '\0', snapshotBufferSize);
    
  7. Populate the db2GetSnapshotData structure with the snapshot request type (from the sqlma structure), buffer information, and other information required to capture a snapshot.
    getSnapshotParam.piSqlmaData = pRequestedDataGroups;
    getSnapshotParam.poCollectedData = &collectedData;
    getSnapshotParam.poBuffer = snapshotBuffer;
    getSnapshotParam.iVersion = SQLM_DBMON_VERSION9_5;
    getSnapshotParam.iBufferSize = snapshotBufferSize;
    getSnapshotParam.iStoreResult = 0;
    getSnapshotParam.iNodeNumber = SQLM_CURRENT_NODE;
    getSnapshotParam.poOutputFormat = &outputFormat;
    getSnapshotParam.iSnapshotClass = SQLM_CLASS_DEFAULT;
    
  8. Capture the snapshot. Pass the db2GetSnapshotData structure, which contains the information necessary to capture a snapshot, as well as a reference to the buffer, where snapshot output is to be directed.
    db2GetSnapshot(db2Version810, &getSnapshotParam, &sqlca);
    
  9. Verify that the snapshot was successfully taken. If the db2GetSnapshotData API returns a negative sqlcode or a nonzero return code, then the snapshot failed. Check the user response for the error and take the appropriate corrective action.
  10. Include logic to handle buffer overflow. After a snapshot is taken, the sqlcode is checked for a buffer overflow. If a buffer overflow occurred the buffer is cleared and reinitialized, and the snapshot is taken again.
    while (sqlca.sqlcode == 1606)
    {
      free(snapshotBuffer);
      snapshotBufferSize = snapshotBufferSize +
      SNAPSHOT_BUFFER_UNIT_SZ;
      snapshotBuffer = (char *)malloc(snapshotBufferSize);
      if (snapshotBuffer == NULL)
      {
        printf("\nMemory allocation error.\n");
        return 1;
      }
      getSnapshotParam.iBufferSize = snapshotBufferSize;
      getSnapshotParam.poBuffer = snapshotBuffer;
      db2GetSnapshot(db2Version810, &getSnapshotParam, &sqlca);
    }
    
  11. Process the snapshot monitor data stream.
  12. Clear the buffer.
    free(snapshotBuffer);
    free(pRequestedDataGroups);