@@ -233,184 +233,86 @@ function syslog_partition_manage() {
233233}
234234
235235/**
236- * Validate tables that support partition maintenance.
237- *
238- * Any value added to the allowlist MUST match ^[a-z_]+$ so it is safe
239- * for identifier interpolation in DDL statements (MySQL does not support
240- * parameter binding for identifiers).
241- */
242- function syslog_partition_table_allowed ($ table ) {
243- if (!in_array ($ table , array ('syslog ' , 'syslog_removed ' ), true )) {
244- return false ;
245- }
246-
247- /* Defense-in-depth: reject values unsafe for identifier interpolation. */
248- if (!preg_match ('/^[a-z_]+$/ ' , $ table )) {
249- return false ;
250- }
251-
252- return true ;
253- }
254-
255- /**
256- * Create a new partition for the specified table.
257- *
258- * @return bool true on success, false on lock failure or disallowed table.
236+ * This function will create a new partition for the specified table.
259237 */
260238function syslog_partition_create ($ table ) {
261239 global $ syslogdb_default ;
262240
263- if (!syslog_partition_table_allowed ($ table )) {
264- return false ;
265- }
266-
267- /* Hash to guarantee the lock name stays within MySQL's 64-byte limit. */
268- $ lock_name = substr (hash ('sha256 ' , $ syslogdb_default . '.syslog_partition_create. ' . $ table ), 0 , 60 );
241+ /* determine the format of the table name */
242+ $ time = time ();
243+ $ cformat = 'd ' . date ('Ymd ' , $ time );
244+ $ lnow = date ('Y-m-d ' , $ time +86400 );
269245
270- / *
271- * 10-second timeout is sufficient: partition maintenance runs once per
272- * poller cycle (typically 5 minutes), so sustained contention is not
273- * expected. A failure is logged so monitoring can detect repeated misses.
274- */
275- $ locked = syslog_db_fetch_cell_prepared ( ' SELECT GET_LOCK(?, 10) ' , array ( $ lock_name ) );
246+ $ exists = syslog_db_fetch_row ( " SELECT *
247+ FROM `information_schema`.`partitions`
248+ WHERE table_schema=' " . $ syslogdb_default . " '
249+ AND partition_name=' " . $ cformat . " '
250+ AND table_name='syslog'
251+ ORDER BY partition_ordinal_position " );
276252
277- if ($ locked === null ) {
278- /* NULL means the GET_LOCK call itself failed, not just contention. */
279- cacti_log ("SYSLOG: GET_LOCK call failed for partition create on ' $ table' " , false , 'SYSTEM ' );
280- return false ;
281- }
253+ if (!cacti_sizeof ($ exists )) {
254+ cacti_log ("SYSLOG: Creating new partition ' $ cformat' " , false , 'SYSTEM ' );
282255
283- if ((int )$ locked !== 1 ) {
284- cacti_log ("SYSLOG: Unable to acquire partition create lock for ' $ table' " , false , 'SYSTEM ' );
285- return false ;
286- }
256+ syslog_debug ("Creating new partition ' $ cformat' " );
287257
288- try {
289- /* determine the format of the table name */
290- $ time = time ();
291- $ cformat = 'd ' . date ('Ymd ' , $ time );
292- $ lnow = date ('Y-m-d ' , $ time +86400 );
293-
294- $ exists = syslog_db_fetch_row_prepared ("SELECT *
295- FROM `information_schema`.`partitions`
296- WHERE table_schema = ?
297- AND partition_name = ?
298- AND table_name = ?
299- ORDER BY partition_ordinal_position " ,
300- array ($ syslogdb_default , $ cformat , $ table ));
301-
302- if (!cacti_sizeof ($ exists )) {
303- cacti_log ("SYSLOG: Creating new partition ' $ cformat' " , false , 'SYSTEM ' );
304-
305- syslog_debug ("Creating new partition ' $ cformat' " );
306-
307- /*
308- * MySQL does not support parameter binding for DDL identifiers
309- * or partition definitions. $table is safe because it passed
310- * syslog_partition_table_allowed() (two-value allowlist plus
311- * regex guard). $cformat and $lnow derive from date() and
312- * contain only digits, hyphens, and the letter 'd'.
313- */
314- syslog_db_execute ("ALTER TABLE ` " . $ syslogdb_default . "`.` $ table` REORGANIZE PARTITION dMaxValue INTO (
315- PARTITION $ cformat VALUES LESS THAN (TO_DAYS(' $ lnow')),
316- PARTITION dMaxValue VALUES LESS THAN MAXVALUE) " );
317- }
318- } finally {
319- syslog_db_fetch_cell_prepared ('SELECT RELEASE_LOCK(?) ' , array ($ lock_name ));
258+ syslog_db_execute ("ALTER TABLE ` " . $ syslogdb_default . "`.` $ table` REORGANIZE PARTITION dMaxValue INTO (
259+ PARTITION $ cformat VALUES LESS THAN (TO_DAYS(' $ lnow')),
260+ PARTITION dMaxValue VALUES LESS THAN MAXVALUE) " );
320261 }
321-
322- return true ;
323262}
324263
325264/**
326- * Remove old partitions for the specified table.
265+ * This function will remove all old partitions for the specified table.
327266 */
328267function syslog_partition_remove ($ table ) {
329268 global $ syslogdb_default ;
330269
331- if (!syslog_partition_table_allowed ($ table )) {
332- cacti_log ("SYSLOG: partition_remove called with disallowed table ' $ table' " , false , 'SYSTEM ' );
333- return 0 ;
334- }
335-
336- $ lock_name = substr (hash ('sha256 ' , $ syslogdb_default . '.syslog_partition_remove. ' . $ table ), 0 , 60 );
337-
338- $ locked = syslog_db_fetch_cell_prepared ('SELECT GET_LOCK(?, 10) ' , array ($ lock_name ));
339-
340- if ($ locked === null ) {
341- cacti_log ("SYSLOG: GET_LOCK call failed for partition remove on ' $ table' " , false , 'SYSTEM ' );
342- return 0 ;
343- }
344-
345- if ((int )$ locked !== 1 ) {
346- cacti_log ("SYSLOG: Unable to acquire partition remove lock for ' $ table' " , false , 'SYSTEM ' );
347- return 0 ;
348- }
349-
350270 $ syslog_deleted = 0 ;
271+ $ number_of_partitions = syslog_db_fetch_assoc ("SELECT *
272+ FROM `information_schema`.`partitions`
273+ WHERE table_schema=' " . $ syslogdb_default . "' AND table_name='syslog'
274+ ORDER BY partition_ordinal_position " );
351275
352- try {
353- $ number_of_partitions = syslog_db_fetch_assoc_prepared ("SELECT *
354- FROM `information_schema`.`partitions`
355- WHERE table_schema = ? AND table_name = ?
356- ORDER BY partition_ordinal_position " ,
357- array ($ syslogdb_default , $ table ));
358-
359- $ days = read_config_option ('syslog_retention ' );
276+ $ days = read_config_option ('syslog_retention ' );
360277
361- syslog_debug ("There are currently ' " . sizeof ($ number_of_partitions ) . "' Syslog Partitions, We will keep ' $ days' of them. " );
278+ syslog_debug ("There are currently ' " . sizeof ($ number_of_partitions ) . "' Syslog Partitions, We will keep ' $ days' of them. " );
362279
363- if ($ days > 0 ) {
364- $ user_partitions = sizeof ($ number_of_partitions ) - 1 ;
365- if ($ user_partitions >= $ days ) {
366- $ i = 0 ;
367- while ($ user_partitions > $ days ) {
368- $ oldest = $ number_of_partitions [$ i ];
280+ if ($ days > 0 ) {
281+ $ user_partitions = sizeof ($ number_of_partitions ) - 1 ;
282+ if ($ user_partitions >= $ days ) {
283+ $ i = 0 ;
284+ while ($ user_partitions > $ days ) {
285+ $ oldest = $ number_of_partitions [$ i ];
369286
370- cacti_log ("SYSLOG: Removing old partition ' " . $ oldest ['PARTITION_NAME ' ] . "' " , false , 'SYSTEM ' );
287+ cacti_log ("SYSLOG: Removing old partition ' " . $ oldest ['PARTITION_NAME ' ] . "' " , false , 'SYSTEM ' );
371288
372- syslog_debug ("Removing partition ' " . $ oldest ['PARTITION_NAME ' ] . "' " );
289+ syslog_debug ("Removing partition ' " . $ oldest ['PARTITION_NAME ' ] . "' " );
373290
374- syslog_db_execute ("ALTER TABLE ` " . $ syslogdb_default . "`.` $ table` DROP PARTITION " . $ oldest ['PARTITION_NAME ' ]);
291+ syslog_db_execute ("ALTER TABLE ` " . $ syslogdb_default . "`.` $ table` DROP PARTITION " . $ oldest ['PARTITION_NAME ' ]);
375292
376- $ i ++;
377- $ user_partitions --;
378- $ syslog_deleted ++;
379- }
293+ $ i ++;
294+ $ user_partitions --;
295+ $ syslog_deleted ++;
380296 }
381297 }
382- } finally {
383- syslog_db_fetch_cell_prepared ('SELECT RELEASE_LOCK(?) ' , array ($ lock_name ));
384298 }
385299
386300 return $ syslog_deleted ;
387301}
388302
389- /*
390- * syslog_partition_check is a read-only SELECT against information_schema.
391- * It does not execute DDL, so it does not need the named lock that
392- * syslog_partition_create and syslog_partition_remove acquire. External
393- * serialization is provided by the poller cycle calling
394- * syslog_partition_manage().
395- */
396303function syslog_partition_check ($ table ) {
397304 global $ syslogdb_default ;
398305
399- if (!syslog_partition_table_allowed ($ table )) {
400- return false ;
401- }
402-
403306 if (defined ('SYSLOG_CONFIG ' )) {
404307 include (SYSLOG_CONFIG );
405308 }
406309
407310 /* find date of last partition */
408- $ last_part = syslog_db_fetch_cell_prepared ("SELECT PARTITION_NAME
311+ $ last_part = syslog_db_fetch_cell ("SELECT PARTITION_NAME
409312 FROM `information_schema`.`partitions`
410- WHERE table_schema = ? AND table_name = ?
313+ WHERE table_schema=' " . $ syslogdb_default . " ' AND table_name='syslog'
411314 ORDER BY partition_ordinal_position DESC
412- LIMIT 1,1 " ,
413- array ($ syslogdb_default , $ table ));
315+ LIMIT 1,1; " );
414316
415317 $ lformat = str_replace ('d ' , '' , $ last_part );
416318 $ cformat = date ('Ymd ' );
0 commit comments