<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body bgcolor="#ffffff" text="#000000">
<tt>Hi there,<br>
<br>
we had an issue with servicechecks where duplicate rows where inserted
instead of updating one single row. During my analysis there was more
of that "feature"...<br>
<br>
Looking at timedevents table ... there also is no unique constraint
since unique key != key<br>
<br>
now it looks like this:</tt>
<pre><tt>+---------------+-------------+------------+---------------------+------------------+---------------------+-----------------+---------------------+-----------------+-----------+---------------------+--------------------+
| timedevent_id | instance_id | event_type | queued_time | queued_time_usec | event_time | event_time_usec | scheduled_time | recurring_event | object_id | deletion_time | deletion_time_usec |
+---------------+-------------+------------+---------------------+------------------+---------------------+-----------------+---------------------+-----------------+-----------+---------------------+--------------------+
| 346416 | 1 | 0 | 2009-11-11 16:16:06 | 448613 | 0000-00-00 00:00:00 | 0 | 2009-11-11 16:20:58 | 0 | 19918 | 0000-00-00 00:00:00 | 0 |
| 346941 | 1 | 0 | 0000-00-00 00:00:00 | 0 | 2009-11-11 16:20:58 | 49905 | 2009-11-11 16:20:58 | 0 | 19918 | 0000-00-00 00:00:00 | 0 |
</tt></pre>
<p><tt>as you can see</tt></p>
<p><tt>instance_id=1 - both<br>
event_type=0 - both<br>
scheduled_time='2009-11-11 16:20:58' - both<br>
object_id=19918 - both</tt></p>
<p><tt>So the second query should generate an update not an insert!</tt></p>
<p><tt>This fail concerns the following tables:</tt></p>
<p><tt>systemcommands<br>
timedeventqueue<br>
timedevents</tt></p>
<p><tt>Difference between mysql and postgres/oracle:</tt></p>
<p><tt>MySQL:<br>
INSERT INTO table () VALUES () ON DUPLICATE KEY UPDATE SET foo=bar;</tt></p>
<p><tt>depends on the defined unique constraint within the table
creation.</tt></p>
<p><tt>Oracle:<br>
MERGE INTO table USING DUAL ON (unique constraint) WHEN MATCHED THEN
UPDATE SET foo=bar WHEN NOT MATCHED INSERT () VALUES ();</tt></p>
<p><tt>Postgres:<br>
UPDATE table SET foo=bar WHERE (unique constraint);<br>
if nothing affected <br>
INSERT INTO table () VALUES ();</tt></p>
<p><tt>Both Oracle and Postgres have defined unique constraints within
the queries already. The table created unique constraints are just a
doubled check.</tt></p>
<p><tt>They have been deeply debugged by myself, since I have
implemented their support (currently only within Icinga IDOUtils).<br>
</tt></p>
<p><tt>But MySQL is missing some constraints and cannot recheck that
within the query.</tt></p>
<hr>
<p><tt>So my fix attempted to recreate those unique keys within the
table creation.</tt></p>
<p><tt>Looks nice indeed, no more duplicates (tested on Icinga IDOUtils
where the exact same DB Scheme is applied and MySQL does the same on
duplicate key)<br>
</tt></p>
<pre><tt>mysql> select * from icinga_timedevents where object_id=20260;
</tt>
</pre>
<pre><tt>+---------------+-------------+------------+---------------------+------------------+---------------------+-----------------+---------------------+-----------------+-----------+---------------------+--------------------+
| timedevent_id | instance_id | event_type | queued_time | queued_time_usec | event_time | event_time_usec | scheduled_time | recurring_event | object_id | deletion_time | deletion_time_usec |
+---------------+-------------+------------+---------------------+------------------+---------------------+-----------------+---------------------+-----------------+-----------+---------------------+--------------------+
| 362362 | 1 | 0 | 2009-11-11 18:25:56 | 255593 | 2009-11-11 18:30:44 | 240715 | 2009-11-11 18:30:44 | 0 | 20260 | 0000-00-00 00:00:00 | 0 |
</tt></pre>
<pre><tt>mysql> select * from icinga_systemcommands where start_time='2009-11-11 18:25:46' and start_time_usec=178164;</tt></pre>
<pre><tt>+------------------+-------------+---------------------+-----------------+---------------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------+---------+---------------+----------------+-------------+--------+-------------+
| systemcommand_id | instance_id | start_time | start_time_usec | end_time | end_time_usec | command_line | timeout | early_timeout | execution_time | return_code | output | long_output |
+------------------+-------------+---------------------+-----------------+---------------------+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------+---------+---------------+----------------+-------------+--------+-------------+
| 126918 | 1 | 2009-11-11 18:25:46 | 178164 | 2009-11-11 18:25:46 | 207814 | /usr/bin/printf "%b" "1257960336\thostname\tUP\t1\tHARD\t0.030\tPING OK - Packet loss = 0%, RTA = 0.69 ms\t\n" >> /opt/icinga/var/host-perfdata.out | 5 | 0 | 0.029 | 0 | | |
</tt></pre>
<p><tt><br>
People are wondering why timedevents are that many rows and
exploding the db... well fixing that you'll get probably the half
of them!<br>
</tt></p>
<p><tt><br>
Before sending a patch feedback on the servicechecks patch would be
much appreciated - useful or duplicate rows are intended?<br>
</tt></p>
<p><tt>This was btw introduced within the commit "Long time catchup on
some minor patches" in January 2009 - for whatever reason.<br>
</tt></p>
<p><tt>Kind regards,<br>
Michael</tt></p>
<p><tt><br>
PS: When will Nagios/NDOUtils move to GIT? Would be much easier to send
those patches.</tt></p>
</body>
</html>