This is a follow-up question of

Why are some file changes not shown in tail -f?

With the use of capital F: tail -F I can monitor the output of

tail -F ~/.mysql_history

from the manual:

      keep trying to open a file even if it is inaccessible when  tail
      starts  or if it becomes inaccessible later; useful when follow-
      ing by name, i.e., with --follow=name

-f, --follow[={name|descriptor}]
      output appended data as the file grows; -f, --follow, and --fol-
      low=descriptor are equivalent

-F     same as --follow=name --retry

but then the whole file is added to the output each time it changes.

Is there a way to tail the .mysql_history file correctly?

I also tried

tail --follow=name ~/.mysql_history 

but then I get the same behaviour and additionally this each time the history file changes:

tail: '.mysql_history' has been replaced; following end of new file

(using LC_ALL=C tail --follow=name ~/.mysql_history to get the english errormessage)

My end goal is to redirect the complete output of all changes in the mysql history into another file, but this is not satisfying:

tail -F ~/.mysql_history >> ~/.mysql_complete_history
  • Please put here english version of the error message. It can be printed out by prepending the command with LC_ALL=C . – user37607 Nov 30 '13 at 6:58
  • Try also putting a -n 10 option on the command line. – Keith Nov 30 '13 at 7:42
  • @Keith that's an idea, but it doesen't seem to work - no change in the behaviour – rubo77 Nov 30 '13 at 7:59
  • the .mysql_history is not a log file which gets appended to, but a history file, much like .bash_history. It gets overwritten, hence the warning. If no early history is dropped, you can still follow the tail, but you need to store how big the file is and print out the extra bytes when the file grows. That is what Stephane's script seems to be doing. For .bash_history, such tricks do not work, because of the , by default, dropped older lines. – Anthon Nov 30 '13 at 8:18
  • In which way isn't ~/.mysql_history complete already? – Stéphane Chazelas Nov 30 '13 at 14:43

You could try something like:

perl -e '
  $f = shift;
  while (open F, "<", $f) {
    seek F, $n, 0;
    while (<F>) {print};
    $n = tell F;
    sleep 1;
  }' ~/.mysql_history

tail -f reads the tail of the file and then sits there trying to read any new stuff every second. So does tail -F, but it also checks if the current file descriptor is still pointing to the same directory entry and starts with the new file if need be.

Here, we get it further. The idea being to reopen the file every second and seek in back to where we left it last time.

  • What about Anthon's comment about .bash_history? – rubo77 Nov 30 '13 at 9:18
  • If bash rewrites a different file, there's not much you can do. mysql may do that as well (if history-size is set in ~/.inputrc for instance). It sounds like a XY problem. What's your end goal? – Stéphane Chazelas Nov 30 '13 at 10:18
  • Your script works on ~/.mysql_history. I added my end goal to my question. I tried perl -e ' $f = shift; while (open F, "<", $f) { seek F, $n, 0; while (<F>) {print}; $n = tell F; sleep 1; }' ~/.mysql_history >> ~/.mysql_complete_history but that doesen't work. – rubo77 Nov 30 '13 at 10:38
  • How can I redirect the output of your perl lines to another file? – rubo77 Dec 6 '13 at 18:49

If I understand correctly, you need an audit plugin. There are various free implementations, search for McAfee MySQL Audit Plugin, MariaDB Audit Plugin for MySQL. Oracle also offers a commercial implementation for their Enterprise MySQL Server.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.