Fixing Kmail

For many years I used fetchmail and postfix with their default settings. fetchmail would put incoming mail into /var/spool/mail/karl. Kmail would load data from local mbox file ** /var/spool/mail/karl** and from a local Kmail mail folder at ~/.local/share/local-mail. That worked with Kmail being a standalone application. But Kmail switching to akonadi caused severe annoyances and I already l looked for a replacement of Kmail. Switching from mbox type /var/spool/mail/karl to mail-dir type /home/karl/.local/share/local-mail/ and deleting the mbox account solved the problem:

erlangen:~ # postconf home_mailbox=.local/share/local-mail/inbox/
erlangen:~ # systemctl restart postfix                                                                                                                                                                                                                                         
erlangen:~ #       

On some occasions akonadi starts heavy writing to disk and contributing a significant fraction to cpu load of a i7 6700K. Even deleting akonadi storage .local/share/akonadi won’t fix this. Deletion of the following configuration data fixed the problem:

karl@erlangen:~> ll .config/akonadi/agent_config_akonadi*changes.dat
-rw-r--r-- 1 karl users 16 27. Feb 21:56 .config/akonadi/agent_config_akonadi_akonotes_resource_0_changes.dat
-rw-r--r-- 1 karl users 16 27. Feb 21:56 .config/akonadi/agent_config_akonadi_archivemail_agent_changes.dat
-rw-r--r-- 1 karl users 16 27. Feb 21:56 .config/akonadi/agent_config_akonadi_birthdays_resource_changes.dat
-rw-r--r-- 1 karl users 16 27. Feb 21:56 .config/akonadi/agent_config_akonadi_contacts_resource_0_changes.dat
-rw-r--r-- 1 karl users 16 27. Feb 16:22 .config/akonadi/agent_config_akonadi_followupreminder_agent_changes.dat
-rw-r--r-- 1 karl users 16 27. Feb 21:56 .config/akonadi/agent_config_akonadi_ical_resource_0_changes.dat
-rw-r--r-- 1 karl users 16 27. Feb 16:22 .config/akonadi/agent_config_akonadi_indexing_agent_changes.dat
-rw-r--r-- 1 karl users 16 28. Feb 06:43 .config/akonadi/agent_config_akonadi_maildir_resource_0_changes.dat
-rw-r--r-- 1 karl users 16 27. Feb 21:56 .config/akonadi/agent_config_akonadi_maildispatcher_agent_changes.dat
-rw-r--r-- 1 karl users 16 27. Feb 16:22 .config/akonadi/agent_config_akonadi_mailfilter_agent_changes.dat
-rw-r--r-- 1 karl users 16 27. Feb 21:56 .config/akonadi/agent_config_akonadi_migration_agent_changes.dat
-rw-r--r-- 1 karl users 16 27. Feb 16:22 .config/akonadi/agent_config_akonadi_newmailnotifier_agent_changes.dat
-rw-r--r-- 1 karl users 16 27. Feb 21:56 .config/akonadi/agent_config_akonadi_notes_agent_changes.dat
-rw-r--r-- 1 karl users 16 27. Feb 16:22 .config/akonadi/agent_config_akonadi_sendlater_agent_changes.dat
karl@erlangen:~> 

Adding an existing directory as a KMail local folder account can be a frustrating experience. For achieving reproducible results the following procedure was found to work reliably:

  • rename the folder to be added: mv Mail Mail.renamed
  • create a new local folder account in Kmail with new folder Mail
  • quit Kmail and stop akonadi; verify all processes are terminated using ps ux|grep kmail
    and ps ux|grep akonadi - copy from renamed folder: * rsync -a Mail.renamed/ Mail/*

While adding folder Mail directly using KMail failed on many occasions the above procedure worked reliably.

On some occasions the indexer starts to fail on some folder and tries again after 5 seconds flooding the journal with the folliwing messages:

.....
Feb 15 09:19:47 erlangen akonadiserver[2472]: org.kde.pim.akonadiserver: ItemRetrievalJob for request 0x7f3a04043c30 finished
Feb 15 09:19:52 erlangen akonadiserver[2472]: org.kde.pim.akonadiserver: ItemRetrievalJob for request 0x7f3a04020df0 finished
Feb 15 09:19:57 erlangen akonadiserver[2472]: org.kde.pim.akonadiserver: ItemRetrievalJob for request 0x7f3a04024990 finished
Feb 15 09:20:02 erlangen akonadiserver[2472]: org.kde.pim.akonadiserver: ItemRetrievalJob for request 0x7f3a04024990 finished
Feb 15 09:20:07 erlangen akonadiserver[2472]: org.kde.pim.akonadiserver: ItemRetrievalJob for request 0x7f3a04024990 finished
....

.

To stop the above behavior create a temporary folder and move the messages of the offending folder identified by akonadiconsole to the new folder and back to the original one.

Assuming the current default Akonadi database, run this script at login:


#!/bin/bash
#
# Akonadi fsck - check that Akonadi is running.
#
# Wait until Akonadi Control is running.
until  $( /bin/pidof /usr/bin/akonadi_control ) ]]
do
  echo "$(printf '%(%Y-%m-%d %H:%M:%S)T' -1) Waiting for Akonadi Control"
  sleep 10s
done
echo "$(printf '%(%Y-%m-%d %H:%M:%S)T' -1) Akonadi Control is running"
#
# Wait unti the Akonadi Server is running.
until  $( /bin/pidof /usr/bin/akonadiserver ) ]]
do
  echo "$(printf '%(%Y-%m-%d %H:%M:%S)T' -1) Waiting for Akonadi Server"
  sleep 10s
done
echo "$(printf '%(%Y-%m-%d %H:%M:%S)T' -1) Akonadi Server is running"
#
# Wait until the Akonadi Server has finished starting.
sleep 20s
echo "$(printf '%(%Y-%m-%d %H:%M:%S)T' -1) Waited for the Akonadi Server to finish starting"
#
# On login, execute the Akonadi internal storage consistency check once per day.
#
if  -f ~/.local/share/akonadi/dateLastChecked ]]
then
  declare -i AkonadiFsckLastDate
  AkonadiFsckLastDate="$(/usr/bin/cat ~/.local/share/akonadi/dateLastChecked)"
  declare -i OneDayAgo
  OneDayAgo="$(/usr/bin/date --date='1 days ago' +%Y%m%d)"
  if (( $AkonadiFsckLastDate <= $OneDayAgo ))
  then
    echo "$(printf '%(%Y-%m-%d %H:%M:%S)T' -1) Akonadi fsck start"
    /usr/bin/logger "Akonadi fsck start"
    # Akonadi internal storage consistency check
    /usr/bin/akonadictl fsck
    /usr/bin/date +%Y%m%d > ~/.local/share/akonadi/dateLastChecked
    echo "$(printf '%(%Y-%m-%d %H:%M:%S)T' -1) Akonadi fsck completed"
    /usr/bin/logger "Akonadi fsck completed"
  else
    echo "$(printf '%(%Y-%m-%d %H:%M:%S)T' -1) Last Akonadi fsck was less than 1 day ago"
  fi
else
  /usr/bin/date +%Y%m%d > ~/.local/share/akonadi/dateLastChecked
fi
#
# Akonadi internal storage vacuum once every three days
if  -f ~/.local/share/akonadi/dateLastVacuumed ]]
then
  declare -i AkonadiVacuumLastDate
  AkonadiVacuumLastDate="$(/usr/bin/cat ~/.local/share/akonadi/dateLastVacuumed)"
  declare -i ThreeDaysAgo
  ThreeDaysAgo="$(/usr/bin/date --date='3 days ago' +%Y%m%d)"
  if (( $AkonadiVacuumLastDate <= $ThreeDaysAgo ))
  then
    echo "$(printf '%(%Y-%m-%d %H:%M:%S)T' -1) Akonadi vacuum start"
    /usr/bin/logger "Akonadi vacuum start"
    /usr/bin/akonadictl vacuum
    /usr/bin/date +%Y%m%d > ~/.local/share/akonadi/dateLastVacuumed
    echo "$(printf '%(%Y-%m-%d %H:%M:%S)T' -1) Akonadi vacuum completed"
    /usr/bin/logger "Akonadi vacuum completed"
    echo "$(printf '%(%Y-%m-%d %H:%M:%S)T' -1) Akonadi fsck start"
    /usr/bin/logger "Akonadi fsck start"
    /usr/bin/akonadictl fsck
    echo "$(printf '%(%Y-%m-%d %H:%M:%S)T' -1) Akonadi fsck completed"
    /usr/bin/logger "Akonadi fsck completed"
  fi
else
  /usr/bin/date +%Y%m%d > ~/.local/share/akonadi/dateLastVacuumed
fi
#
echo "$(printf '%(%Y-%m-%d %H:%M:%S)T' -1) Akonadi internal storage consistency check completed."
kdialog --title "Akonadi internal storage consistency" --passivepopup "Check completed."
## notify-send --icon=dialog-information "Akonadi internal storage consistency" "Check completed."
#
# ** History . . . **
#

My solution was to remove and lock kmail so it is never again installed. Then add the KDE3 repository and install the KDE3 version of kmail.

Works like a charm for 5GB of mail folders, as does the Trinity version. Of course it’s search is a bit slower, but I’m OK with that.

Actually most of the annoying malfunctions of kmail have been fixed. The remaining one I encountered is with the indexer choking on 8-bit characters. The pertaining message fragments are easily identified in the message list as ‘unknown subject’, ‘unknown sender’ … and can safely be deleted. So for most accounts kmail works as advertised. Search of kmail2 5.13.2 (19.12.2) is really fast. :wink: