[ZBX-16467] The value of ZBX_IDS_SIZE is incorrect. Created: 2019 Aug 06  Updated: 2024 Apr 10  Resolved: 2019 Sep 17

Status: Closed
Project: ZABBIX BUGS AND ISSUES
Component/s: Proxy (P), Server (S)
Affects Version/s: 4.0.11
Fix Version/s: 4.0.13rc1, 4.2.7rc1, 4.4.0alpha3, 4.4 (plan)

Type: Problem report Priority: Trivial
Reporter: Kazuo Ito Assignee: Andrejs Kozlovs
Resolution: Fixed Votes: 0
Labels: ids, server
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Zabbix4.0.11


Team: Team A
Sprint: Sprint 56 (Sep 2019), Sprint 55 (Aug 2019)
Story Points: 0.125

 Description   

DCget_nextid() is called for a specific 10 tables.

zbx_uint64_t	DBget_maxid_num(const char *tablename, int num)
{
	if (0 == strcmp(tablename, "events") ||
			0 == strcmp(tablename, "event_tag") ||
			0 == strcmp(tablename, "problem_tag") ||
			0 == strcmp(tablename, "dservices") ||
			0 == strcmp(tablename, "dhosts") ||
			0 == strcmp(tablename, "alerts") ||
			0 == strcmp(tablename, "escalations") ||
			0 == strcmp(tablename, "autoreg_host") ||
			0 == strcmp(tablename, "task_remote_command") ||
			0 == strcmp(tablename, "task_remote_command_result"))
		return DCget_nextid(tablename, num);

	return DBget_nextid(tablename, num);
}

DCget_nextid() checks if it matches table_name of structure ZBX_DC_IDS.

/******************************************************************************
 *                                                                            *
 * Function: DCget_nextid                                                     *
 *                                                                            *
 * Purpose: Return next id for requested table                                *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 ******************************************************************************/
zbx_uint64_t	DCget_nextid(const char *table_name, int num)
{
	const char	*__function_name = "DCget_nextid";
	int		i;
	DB_RESULT	result;
	DB_ROW		row;
	const ZBX_TABLE	*table;
	ZBX_DC_ID	*id;
	zbx_uint64_t	min = 0, max = ZBX_DB_MAX_ID, nextid, lastid;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() table:'%s' num:%d",
			__function_name, table_name, num);

	LOCK_CACHE_IDS;

	for (i = 0; i < ZBX_IDS_SIZE; i++)
	{
		id = &ids->id[i];
		if ('\0' == *id->table_name)
			break;

		if (0 == strcmp(id->table_name, table_name))
		{
			nextid = id->lastid + 1;
			id->lastid += num;
			lastid = id->lastid;

			UNLOCK_CACHE_IDS;

			zabbix_log(LOG_LEVEL_DEBUG, "End of %s() table:'%s' [" ZBX_FS_UI64 ":" ZBX_FS_UI64 "]",
					__function_name, table_name, nextid, lastid);

			return nextid;
		}
	}

	if (i == ZBX_IDS_SIZE)
	{
		zabbix_log(LOG_LEVEL_ERR, "insufficient shared memory for ids");
		exit(EXIT_FAILURE);
	}

	table = DBget_table(table_name);

	result = DBselect("select max(%s) from %s where %s between " ZBX_FS_UI64 " and " ZBX_FS_UI64,
			table->recid, table_name, table->recid, min, max);

	if (NULL != result)
	{
		zbx_strlcpy(id->table_name, table_name, sizeof(id->table_name));

		if (NULL == (row = DBfetch(result)) || SUCCEED == DBis_null(row[0]))
			id->lastid = min;
		else
			ZBX_STR2UINT64(id->lastid, row[0]);

		nextid = id->lastid + 1;
		id->lastid += num;
		lastid = id->lastid;
	}
	else
		nextid = lastid = 0;

	UNLOCK_CACHE_IDS;

	DBfree_result(result);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s() table:'%s' [" ZBX_FS_UI64 ":" ZBX_FS_UI64 "]",
			__function_name, table_name, nextid, lastid);

	return nextid;
}

If they do not match, DBget_table() is called and the table name is set in the structure ZBX_DC_IDS.

ZBX_IDS_SIZE is now 8.

#define ZBX_IDS_SIZE	8
typedef struct
{
	char		table_name[ZBX_TABLENAME_LEN_MAX];
	zbx_uint64_t	lastid;
}
ZBX_DC_ID;

typedef struct
{
	ZBX_DC_ID	id[ZBX_IDS_SIZE];
}
ZBX_DC_IDS;

static ZBX_DC_IDS	*ids = NULL;

ZBX_IDS_SIZE is not 10, so there are two missing tables when called from DCget_nextid().
Is this the intended behavior?

I think it is better to have 8 tables or ZBX_IDS_SIZE to 10.



 Comments   
Comment by Andrejs Kozlovs [ 2019 Aug 06 ]

After task_remote_command and task_remote_command_result tables was added to DBget_maxid_num() function and total number of tables used in DCget_nextid() becomes 10, instead of 8 allowed. But fortunately looks update of task_remote_command and task_remote_command_result tables happens without autoincrement and no  DBget_maxid_num() is called for these tables. So, it is possible either increase ZBX_IDS_SIZE to 10 or remove both tables from DBget_maxid_num()

Comment by Vladislavs Sokurenko [ 2019 Aug 09 ]

Should remove both tables from DBget_maxid_num()

Comment by Andrejs Kozlovs [ 2019 Sep 05 ]

Fixed in:

  • 4.0.13rc1 6e1a2a607ae
  • 4.2.7rc1 ea5cc43c09e
  • 4.4.0alpha3 (master) c05e624e69f
Generated at Sat Apr 27 03:56:00 EEST 2024 using Jira 9.12.4#9120004-sha1:625303b708afdb767e17cb2838290c41888e9ff0.