How can I log MySQL queries? - mysql

Is it possible to log all queries that are executed? I am looking at a database that is accessed by many different apps. One of them is modifying a table's value in a way it should not. I am trying figure out which app is the culprit. It would help me out a lot if I can capture all the queries that are executed on that table and at what time.
Many thanks in advance for your help.

Either use the --log[=file_name] command line switch on mysqld or edit/create a my.cnf containing:
[mysqld]
log=/tmp/mysql.log
Explained fully in this article.

As far as I am aware, there are currently no auditing capabilities built in to MySQL. Log queries from within the applications that generate them, or sniff connections to the server.

in your .ini configuration add this line
log=allqueries.log
you will need to restart mysql

A possible solution to your problem is to utilize an update trigger on the table in question. The trigger will be fired on any update to the table, and it possible to write the trigger such that when it meets certain criteria (the value in question is changed), an action is performed (perhaps writing to a temporary table, the SQL statement that makes the change). For more information, I suggest looking at Trigger Syntax.

Take a look here: http://dev.mysql.com/doc/refman/5.1/en/server-logs.html
You're looking for general query log: http://dev.mysql.com/doc/refman/5.1/en/query-log.html

You can use the general log in MySQL to achieve this. I only recommend you do that on a test/development database without many concurrent users, because the amount of output generated is huge. I'm not sure if it logs the timestamp, though.
If it doesn't, on a unix/linux setup, I'd say write a simple script that read lines from the stdin and print the lines with the current timestamp when they were read, and pipe tail -f on the log file to it, so you can add your own timestamps.

Related

MySQL/MariaDB Trigger for Taking Ran Query and Pasting into a Row

So one of the projects I'm working on requires us to take every query that is ran on the server and automatically paste that query into a table inside of the database. The reason for this is so that the DBA is able to view all prior SQL Queries that have been ran on the box. Unfortunately I don't have any leeway to do this differently as the client is requiring this implementation.
Has anybody done this before or has any code that I could use that will automatically do this? Thanks.
Be careful! If you do an INSERT for every action taken, you will need to do an INSERT for that INSERT, at which point, you will ...
That is, the first logged query will hang the server and fill up the disk!
Instead of doing the task the way it is asked, turn on the "general log" and periodically scrape what it in it into another machine, which does not have this logging turned on.
Other arguments against the task as stated...
If a table has TRIGGERs, you will not be able to add another TRIGGER.
If "every query" really means "every", it is impossible (with a TRIGGER) since you can't write a SELECT or SHOW trigger.
"as the client is requiring this implementation". I would approach this unreasonable constraint by politely finding out what the real goal is. He has only described is an implementation.
If his goal is some kind of audit log, then my suggestion about the general log should suffice.

How to subscribe to update,delete and inserts on a mysql table?

I would like to get a notification when in certain mysql (or mariadb) tables (innodb) updates,inserts or deletes happen.
I need to track these changes from another process as soon as possible,
I was thinking maybe I could subscribe to the mysql binary log?
Can somebody explain how this can be done?
Is there for example a log read API that mysql offers?
Does the game change when I use a Galera cluster?
You may use mysqlbinlog with --stop-never option to get all insert, update, and delete statements (mysqlbinlog documentation).
You may use the C++ library MySQL Replication Listener that is based on the binlog api.
I don't know if this will help you, but I like to use a separate table to track the changes. If I have a table called "site_visitors", I'll create another table called "site_visitors_log" that is immediately written to with the information I need (IP addresses, timestamp, etc.) right after data is inserted into "site_visitors". Very convenient.
TRIGGER is your friend here. From MySQL-Doc:
A trigger is defined to activate when a statement inserts,
updates, or deletes rows in the associated table
See MySQL-Doc here, there are some examples, too.

MySQL Database Hacked, how can I tell which rows were affected?

I have a database that was compromised. It's a very big content table and I don't know if any of the rows were altered. Is there a way in MySQL to see which rows were edited and when?
If it was compromised by injection you have to crawl through HTTP server's access log. MySQL has a query logging ability but it's "always" disabled since it seriously slows down the server. Otherwise: No.
You can use The General Query Log to track down the queries if its not turned off. For future you can use this steps mentioned in answer to set the query log How to show the last queries executed on MySQL?.

Automatic MySQL backup on sharedhost

As I am not a coder so I should stop here but I am interested how far I could go to build an automatic SQL script.
Case:
A website is hosted on a shared host server which uses CPanel. The website use only one DB and one of the table is the log. Now the log table has reached 300k rows... (I might do something wrong here... it is a popular website?:))
So I need to reduce the log table but I would like to do a backup rather. So here is my idea:
Setup a backup DB and copy the old entries meanwhile use tables for only quarter years so the log from Jan-April would be stored in table_2012-q1 etc.
Method:
I would like to use cron and email alert.
Questions:
is there any better and easier solution to do the back up with this row num.
if I do a "move rows" by INSERT/DELETE rows how can I check which one is ready on time?
do I need to focus on the performance of this process as it should work in the background? In other words is it a select or a dump?
Sorry if it is too Dummy but I would like to learn! I also don't want to use too much processor for this.
Thanks Andras
Since you are using shared hosting, I'm pretty sure you will not be able to access cron, so here is an alternative:
Since the database is filled with log data :
1. Create a new table, regardless of the name or time period
2. Move the files (from a certain id) from one table to the next
This link will explain better : mysqldump partial database
If this is active DB, I would clone it and then play around with the ways the data will be moved since you do not consider youreself a coder.
Hope this helps.

MySQL - How to automatically log selects from table

currently I can log user insertions and updates on my tables to a table called Log. But I can't find how to enable triggers or something to also do it with selects.
Maybe look into mysql proxy - you can log everything that passes into mysql, modify it, etc.
http://dev.mysql.com/doc/refman/5.1/en/mysql-proxy.html
use a tool to read the mysql log. is the simpliest and elegant way to track mysql log.