[horde] IMP IMAP DB Cache backend lifetime
Joao S Veiga
jsveiga at rf.com.br
Thu Aug 31 11:13:47 UTC 2017
----- Message from Federico Giannici <giannici at neomedia.it> ---------
>
> I think that a possible simple solution could be to add a "created"
> field the horde_imap_client_message table automatically set to the
> current timestamp at the INSERT. Then we could use this field to
> purge the messages that were cached since a lot (maybe a month?). In
> this way no messages would remain in cache forever, but eventually
> the reload of the message would happen only after a lot of time (and
> in a "time distributed" way).
>
> What do you think?
>
Hi Federico,
(Did you fix the Db.php script first (the missing ")")? That would
prevent the lifetime limit to work.)
The horde_imap_client_message (and the horde_imap_client_metadata) are
related to the horde_imap_client_data by the messageid field, and
horde_imap_client_data already (should) have timestamps, so when
clearing the tables by timestamp, the old _message/_metadata entries
should go away too. The script uses the horde_imap_client_data
'modified' timestamp to do that, but...
If you look at the horde_imap_client_data, you probably have a lot of
data with NULL in the 'modified' field because of what I mentioned
before (the _createUid() does not set the 'modified', then the script
does not clear these rows).
I have changed my
Imap_Client/lib/Horde/Imap/Client/Cache/Backend/Db.php to insert the
'modified' when creating the entries (it's under the "protected
function _createUid($mailbox)"):
--- Db.php.orig 2017-08-30 07:57:02.299562533 -0300
+++ Db.php 2017-08-30 07:58:37.094862818 -0300
@@ -389,15 +389,16 @@
{
return $this->_db->insert(
sprintf(
- 'INSERT INTO %s (hostspec, mailbox, port, username) ' .
- 'VALUES (?, ?, ?, ?)',
+ 'INSERT INTO %s (hostspec, mailbox, port, username,
modified) ' .
+ 'VALUES (?, ?, ?, ?, ?)',
self::BASE_TABLE
),
array(
$this->_params['hostspec'],
$mailbox,
$this->_params['port'],
- $this->_params['username']
+ $this->_params['username'],
+ $time()
)
);
}
After this you'll want to clear the entries that are already with
'modified' = NULL:
delete from horde_imap_client_metadata where messageid in (select
messageid from horde_imap_client_data where modified is NULL);
delete from horde_imap_client_message where messageid in (select
messageid from horde_imap_client_data where modified is NULL);
delete from horde_imap_client_data where modified is NULL;
and also messages/metadata that have no corresponding entries in
horde_imap_client_data (should not exist, but at least in my server
they do):
delete FROM horde.horde_imap_client_message where messageid not in
(select messageid from horde_imap_client_data);
delete FROM horde.horde_imap_client_metadata where messageid not in
(select messageid from horde_imap_client_data);
Then what I did was to create a script to clean unmatched and old
entries (older than 120 days) every day, from crontab. (I'm not a php
guy, so I did it on perl, which is my native tongue):
(yes, running imp-query-imap-cache periodically could do it, but that
script does not clear the unmatched messages/metadata too, only the
old ones)
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
my $db = DBI->connect("DBI:mysql:horde:localhost", "horde",
"XXXXXXXX", {mysql_enable_utf8=>1});
my $old = time() - 120 * 24 * 3600;
my $q = $db->prepare("delete from horde_imap_client_metadata where
messageid in (select messageid from horde_imap_client_data where
modified < ?);");
$q->execute($old);
$q = $db->prepare("delete from horde_imap_client_message where
messageid in (select messageid from horde_imap_client_data where
modified < ?);");
$q->execute($old);
$q = $db->prepare("delete from horde_imap_client_data where modified < ?;");
$q->execute($old);
$db->do("delete FROM horde.horde_imap_client_message where messageid
not in (select messageid from horde_imap_client_data);");
$db->do("delete FROM horde.horde_imap_client_metadata where messageid
not in (select messageid from horde_imap_client_data);");
$db->disconnect();
Note that this will only work after you have cleared the NULL entries
and changed Db.php so that doesn't happen again.
Best regards,
Joao S Veiga
More information about the horde
mailing list