MySQL NDB Cluster API Developer Guide  /  ...  /  MGM API Event Handling with Multiple Clusters

3.6.2 MGM API Event Handling with Multiple Clusters

This example shown in this section illustrates the handling of log events using the MGM API on multiple clusters in a single application.

The source code for this program may be found in the NDB Cluster source tree, in the file storage/ndb/ndbapi-examples/mgmapi_logevent2/main.cpp.

Note

This file was previously named mgmapi_logevent2.cpp.

#include <mysql.h>
#include <ndbapi/NdbApi.hpp>
#include <mgmapi.h>
#include <stdio.h>
#include <stdlib.h>

/*
 * export LD_LIBRARY_PATH=../../../libmysql_r/.libs:../../../ndb/src/.libs
 */

#define MGMERROR(h) \
{ \
  fprintf(stderr, "code: %d msg: %s\n", \
          ndb_mgm_get_latest_error(h), \
          ndb_mgm_get_latest_error_msg(h)); \
  exit(-1); \
}

#define LOGEVENTERROR(h) \
{ \
  fprintf(stderr, "code: %d msg: %s\n", \
          ndb_logevent_get_latest_error(h), \
          ndb_logevent_get_latest_error_msg(h)); \
  exit(-1); \
}

int main(int argc, char** argv)
{
  NdbMgmHandle h1,h2;
  NdbLogEventHandle le1,le2;
  int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP,
		   15, NDB_MGM_EVENT_CATEGORY_CONNECTION,
		   15, NDB_MGM_EVENT_CATEGORY_NODE_RESTART,
		   15, NDB_MGM_EVENT_CATEGORY_STARTUP,
		   15, NDB_MGM_EVENT_CATEGORY_ERROR,
		   0 };
  struct ndb_logevent event1, event2;

  if (argc < 3)
  {
    printf("Arguments are <connect_string cluster 1>",
           "<connect_string cluster 2> [<iterations>].\n");
    exit(-1);
  }
  const char *connectstring1 = argv[1];
  const char *connectstring2 = argv[2];
  int iterations = -1;
  if (argc > 3)
    iterations = atoi(argv[3]);
  ndb_init();

  h1= ndb_mgm_create_handle();
  h2= ndb_mgm_create_handle();
  if ( h1 == 0 || h2 == 0 )
  {
    printf("Unable to create handle\n");
    exit(-1);
  }
  if (ndb_mgm_set_connectstring(h1, connectstring1) == -1 ||
      ndb_mgm_set_connectstring(h2, connectstring1))
  {
    printf("Unable to set connection string\n");
    exit(-1);
  }
  if (ndb_mgm_connect(h1,0,0,0)) MGMERROR(h1);
  if (ndb_mgm_connect(h2,0,0,0)) MGMERROR(h2);

  if ((le1= ndb_mgm_create_logevent_handle(h1, filter)) == 0) MGMERROR(h1);
  if ((le2= ndb_mgm_create_logevent_handle(h1, filter)) == 0) MGMERROR(h2);

  while (iterations-- != 0)
  {
    int timeout= 1000;
    int r1= ndb_logevent_get_next(le1,&event1,timeout);
    if (r1 == 0)
      printf("No event within %d milliseconds\n", timeout);
    else if (r1 < 0)
      LOGEVENTERROR(le1)
    else
    {
      switch (event1.type) {
      case NDB_LE_BackupStarted:
	printf("Node %d: BackupStarted\n", event1.source_nodeid);
	printf("  Starting node ID: %d\n", event1.BackupStarted.starting_node);
	printf("  Backup ID: %d\n", event1.BackupStarted.backup_id);
	break;
      case NDB_LE_BackupCompleted:
	printf("Node %d: BackupCompleted\n", event1.source_nodeid);
	printf("  Backup ID: %d\n", event1.BackupStarted.backup_id);
	break;
      case NDB_LE_BackupAborted:
	printf("Node %d: BackupAborted\n", event1.source_nodeid);
	break;
      case NDB_LE_BackupFailedToStart:
	printf("Node %d: BackupFailedToStart\n", event1.source_nodeid);
	break;

      case NDB_LE_NodeFailCompleted:
	printf("Node %d: NodeFailCompleted\n", event1.source_nodeid);
	break;
      case NDB_LE_ArbitResult:
	printf("Node %d: ArbitResult\n", event1.source_nodeid);
	printf("  code %d, arbit_node %d\n",
	       event1.ArbitResult.code & 0xffff,
	       event1.ArbitResult.arbit_node);
	break;
      case NDB_LE_DeadDueToHeartbeat:
	printf("Node %d: DeadDueToHeartbeat\n", event1.source_nodeid);
	printf("  node %d\n", event1.DeadDueToHeartbeat.node);
	break;

      case NDB_LE_Connected:
	printf("Node %d: Connected\n", event1.source_nodeid);
	printf("  node %d\n", event1.Connected.node);
	break;
      case NDB_LE_Disconnected:
	printf("Node %d: Disconnected\n", event1.source_nodeid);
	printf("  node %d\n", event1.Disconnected.node);
	break;
      case NDB_LE_NDBStartCompleted:
	printf("Node %d: StartCompleted\n", event1.source_nodeid);
	printf("  version %d.%d.%d\n",
	       event1.NDBStartCompleted.version >> 16 & 0xff,
	       event1.NDBStartCompleted.version >> 8 & 0xff,
	       event1.NDBStartCompleted.version >> 0 & 0xff);
	break;
      case NDB_LE_ArbitState:
	printf("Node %d: ArbitState\n", event1.source_nodeid);
	printf("  code %d, arbit_node %d\n",
	       event1.ArbitState.code & 0xffff,
	       event1.ArbitResult.arbit_node);
	break;

      default:
	break;
      }
    }

    int r2= ndb_logevent_get_next(le1,&event2,timeout);
    if (r2 == 0)
      printf("No event within %d milliseconds\n", timeout);
    else if (r2 < 0)
      LOGEVENTERROR(le2)
    else
    {
      switch (event2.type) {
      case NDB_LE_BackupStarted:
	printf("Node %d: BackupStarted\n", event2.source_nodeid);
	printf("  Starting node ID: %d\n", event2.BackupStarted.starting_node);
	printf("  Backup ID: %d\n", event2.BackupStarted.backup_id);
	break;
      case NDB_LE_BackupCompleted:
	printf("Node %d: BackupCompleted\n", event2.source_nodeid);
	printf("  Backup ID: %d\n", event2.BackupStarted.backup_id);
	break;
      case NDB_LE_BackupAborted:
	printf("Node %d: BackupAborted\n", event2.source_nodeid);
	break;
      case NDB_LE_BackupFailedToStart:
	printf("Node %d: BackupFailedToStart\n", event2.source_nodeid);
	break;

      case NDB_LE_NodeFailCompleted:
	printf("Node %d: NodeFailCompleted\n", event2.source_nodeid);
	break;
      case NDB_LE_ArbitResult:
	printf("Node %d: ArbitResult\n", event2.source_nodeid);
	printf("  code %d, arbit_node %d\n",
	       event2.ArbitResult.code & 0xffff,
	       event2.ArbitResult.arbit_node);
	break;
      case NDB_LE_DeadDueToHeartbeat:
	printf("Node %d: DeadDueToHeartbeat\n", event2.source_nodeid);
	printf("  node %d\n", event2.DeadDueToHeartbeat.node);
	break;

      case NDB_LE_Connected:
	printf("Node %d: Connected\n", event2.source_nodeid);
	printf("  node %d\n", event2.Connected.node);
	break;
      case NDB_LE_Disconnected:
	printf("Node %d: Disconnected\n", event2.source_nodeid);
	printf("  node %d\n", event2.Disconnected.node);
	break;
      case NDB_LE_NDBStartCompleted:
	printf("Node %d: StartCompleted\n", event2.source_nodeid);
	printf("  version %d.%d.%d\n",
	       event2.NDBStartCompleted.version >> 16 & 0xff,
	       event2.NDBStartCompleted.version >> 8 & 0xff,
	       event2.NDBStartCompleted.version >> 0 & 0xff);
	break;
      case NDB_LE_ArbitState:
	printf("Node %d: ArbitState\n", event2.source_nodeid);
	printf("  code %d, arbit_node %d\n",
	       event2.ArbitState.code & 0xffff,
	       event2.ArbitResult.arbit_node);
	break;

      default:
	break;
      }
    }
  }

  ndb_mgm_destroy_logevent_handle(&le1);
  ndb_mgm_destroy_logevent_handle(&le2);
  ndb_mgm_destroy_handle(&h1);
  ndb_mgm_destroy_handle(&h2);
  ndb_end(0);
  return 0;
}