poller_push_data_to_main() picks its upsert syntax from set.dbonupdate, which describes the local database, but every statement it builds is sent to the main database. When the two are different vendors the statement is rejected and the whole batch is lost.
util.c:984 and util.c:1146 (develop), util.c:855 and util.c:990 (1.2.x):
if (set.dbonupdate == 0) {
snprintf(suffix, BUFSIZE, " ON DUPLICATE KEY UPDATE snmp_sysDescr=VALUES(snmp_sysDescr), ...");
} else {
snprintf(suffix, BUFSIZE, " AS rs ON DUPLICATE KEY UPDATE snmp_sysDescr=rs.snmp_sysDescr, ...");
}
Three facts make this always the wrong connection:
set.dbonupdate is derived from the local server's banner (util.c:550-556), in the same function that calls get_cacti_version(&mysql, LOCAL). It is 1 for MySQL 8.x, 0 for MariaDB.
poller_push_data_to_main() is called from exactly one place, under if (set.poller_id > 1 && set.mode == REMOTE_ONLINE && !set.SQL_readonly) (spine.c:1071). It only ever runs on a remote poller.
- Both suffixes are appended to
sqlbuf and sent with db_insert(&mysqlr, REMOTE, sqlbuf) (util.c:1114, 1124, 1193, 1203). Every insert in the function goes to the main server.
So on a remote poller running MySQL 8 against a MariaDB main server, set.dbonupdate is 1, the row-alias form is selected, and MariaDB rejects VALUES ... AS rs as a syntax error. Host status and poller_item sync fail on every push cycle. The symptom a user sees is stale device status and graphs that stop advancing for everything behind that poller, not a message about SQL.
The reverse pairing is harmless today: a MariaDB remote poller against a MySQL 8 main server picks VALUES(), which MySQL 8 still accepts but has deprecated. That is the same deprecation #590 describes for poll_host(), and it is a warning rather than a failure.
config_t already carries rdbversion and rdbonupdate for exactly this distinction and nothing ever populates them. Populating rdbonupdate from the remote connection's banner is the real fix. Until then the portable VALUES() form is correct in this function, because it is the only one both vendors accept.
Note that putsetting() at util.c:238 keeps the branch correctly. It takes the connection as a parameter and its one caller passes LOCAL, so there set.dbonupdate really does describe the target.
Present on develop and 1.2.x. A fix and a structural regression test are in #597.
poller_push_data_to_main()picks its upsert syntax fromset.dbonupdate, which describes the local database, but every statement it builds is sent to the main database. When the two are different vendors the statement is rejected and the whole batch is lost.util.c:984andutil.c:1146(develop),util.c:855andutil.c:990(1.2.x):Three facts make this always the wrong connection:
set.dbonupdateis derived from the local server's banner (util.c:550-556), in the same function that callsget_cacti_version(&mysql, LOCAL). It is 1 for MySQL 8.x, 0 for MariaDB.poller_push_data_to_main()is called from exactly one place, underif (set.poller_id > 1 && set.mode == REMOTE_ONLINE && !set.SQL_readonly)(spine.c:1071). It only ever runs on a remote poller.sqlbufand sent withdb_insert(&mysqlr, REMOTE, sqlbuf)(util.c:1114,1124,1193,1203). Every insert in the function goes to the main server.So on a remote poller running MySQL 8 against a MariaDB main server,
set.dbonupdateis 1, the row-alias form is selected, and MariaDB rejectsVALUES ... AS rsas a syntax error. Host status andpoller_itemsync fail on every push cycle. The symptom a user sees is stale device status and graphs that stop advancing for everything behind that poller, not a message about SQL.The reverse pairing is harmless today: a MariaDB remote poller against a MySQL 8 main server picks
VALUES(), which MySQL 8 still accepts but has deprecated. That is the same deprecation #590 describes forpoll_host(), and it is a warning rather than a failure.config_talready carriesrdbversionandrdbonupdatefor exactly this distinction and nothing ever populates them. Populatingrdbonupdatefrom the remote connection's banner is the real fix. Until then the portableVALUES()form is correct in this function, because it is the only one both vendors accept.Note that
putsetting()atutil.c:238keeps the branch correctly. It takes the connection as a parameter and its one caller passesLOCAL, so thereset.dbonupdatereally does describe the target.Present on
developand1.2.x. A fix and a structural regression test are in #597.