Rsyslog MySQL Tabellen partitionieren

Wenn sehr viele Daten in Syslog und MySQL geschrieben werden, ist es manchmal sinnvoll die Tabellen zu partitionieren.

Die Tabelle SystemEvents wird dabei in viele kleine Tabellen aufgeteilt.

Nachfolgende Schema ist aber nur dann sinnvoll, wenn im Syslog die Meldungen hauptsächlich für bestimmte Hosts gesucht werden. Das bedeutet, Sie verwenden fast immer die Bedingung "WHERE FromHost = 'some.host.tld'".

CREATE TABLE `SystemEvents` (
  `ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `CustomerID` bigint(20) DEFAULT NULL,
  `ReceivedAt` datetime DEFAULT NULL,
  `DeviceReportedTime` datetime DEFAULT NULL,
  `Facility` smallint(6) DEFAULT NULL,
  `Priority` smallint(6) DEFAULT NULL,
  `FromHost` varchar(60) DEFAULT NULL,
  `Message` text,
  `NTSeverity` int(11) DEFAULT NULL,
  `Importance` int(11) DEFAULT NULL,
  `EventSource` varchar(60) DEFAULT NULL,
  `EventUser` varchar(60) DEFAULT NULL,
  `EventCategory` int(11) DEFAULT NULL,
  `EventID` int(11) DEFAULT NULL,
  `EventBinaryData` text,
  `MaxAvailable` int(11) DEFAULT NULL,
  `CurrUsage` int(11) DEFAULT NULL,
  `MinUsage` int(11) DEFAULT NULL,
  `MaxUsage` int(11) DEFAULT NULL,
  `InfoUnitID` int(11) DEFAULT NULL,
  `SysLogTag` varchar(60) DEFAULT NULL,
  `EventLogType` varchar(60) DEFAULT NULL,
  `GenericFileName` varchar(60) DEFAULT NULL,
  `SystemID` int(11) DEFAULT NULL,
  PRIMARY KEY (`ID`,`FromHost`),
  KEY `FromHost` (`FromHost`),
  KEY `SyslogTag` (`SysLogTag`),
  KEY `DeviceReportedTime` (`DeviceReportedTime`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
PARTITION BY KEY(FromHost)
PARTITIONS 16;

Wenn Sie nun einen Houskeeping Job laufen lassen, der alte Logs löscht, dann haben Sie mit diesem Partitionierungschema nichts gewonnen, eher im Gegenteil. MySQL muss alle Tabellen durchscannen.

Legen Sie eine Tabelle und einen Trigger, an Informationen für das effiziente Houskeeping vorbereitet.

drop table FromHosts;
create table FromHosts
(FromHost varchar(60) NOT NULL,
LogCount int(13),
LastUpdate datetime,
UNIQUE KEY `FromHost` (`FromHost`)
)ENGINE=InnoDB DEFAULT CHARSET=latin1;

DELIMITER |
CREATE TRIGGER update_FromHost AFTER INSERT ON SystemEvents
	FOR EACH ROW BEGIN
        INSERT INTO FromHosts (FromHost,LogCount,LastUpdate) VALUES(NEW.FromHost,1,NOW())
          ON DUPLICATE KEY UPDATE LogCount=LogCount+1;
	END;
|
DELIMITER ;

Aufräumen

#!/bin/sh
HOSTS=$(mysql Syslog -e "select FromHost from FromHosts")
for HOST in $HOSTS
do
    echo "Housekeeping for $HOST"
    mysql Syslog -e "DELETE FROM SystemEvents where FromHost='$HOST' AND DeviceReportedTime < DATE_ADD(NOW(),INTERVAL -60 DAY)"
done