Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to log error queries in mysql?

I know that there is general_log that logs all queries, but I want to find out which query has an error, and get the error message. I have tried running an error query on purpose, but it logs as a normal query and doesn't report it with error. Any ideas?

like image 685
Van Nguyen Avatar asked Apr 17 '10 13:04

Van Nguyen


People also ask

How do I enable MySQL query logging?

To disable or enable the general query log or change the log file name at runtime, use the global general_log and general_log_file system variables. Set general_log to 0 (or OFF ) to disable the log or to 1 (or ON ) to enable it.

Where is error log MySQL windows?

The error log is located in the data directory specified in your my. ini file. The default data directory location is C:\Program Files\MySQL\MySQL Server 8.0\data , or C:\ProgramData\Mysql on Windows 7 and Windows Server 2008.

Is there a MySQL log?

MySQL Server has several logs that can help you find out what activity is taking place. By default, no logs are enabled, except the error log on Windows. (The DDL log is always created when required, and has no user-configurable options; see Section 5.4.


5 Answers

I know this is ancient now, but for anyone having the same issue that lands here from Google, here's my two cents.

If you're using the cli client, you can simply redirect your sterr to a file, and then parse through that.

mysql -u user -p 2> errors.log
like image 140
Bryan Agee Avatar answered Oct 04 '22 01:10

Bryan Agee


There is no functionality in MySQL to do this.

You will have to stick with application-layer logging.

like image 32
Lightness Races in Orbit Avatar answered Oct 04 '22 01:10

Lightness Races in Orbit


It is possible to log error queries with the MariaDB Audit Plugin.

The MariaDB Audit Plugin works for MariaDB, MySQL and Percona Server.

For example, for these queries

select now();
select now()+();
select 9+();
select 'hello';

log seems like this:

20150807 23:00:36,mnv-Satellite-L300D,root,localhost,82,377,QUERY,`test`,'select now()
LIMIT 0, 1000',0
20150807 23:00:37,mnv-Satellite-L300D,root,localhost,82,379,QUERY,`test`,'select now()+()',1064
20150807 23:00:37,mnv-Satellite-L300D,root,localhost,82,382,QUERY,`test`,'select 9+()',1064
20150807 23:00:38,mnv-Satellite-L300D,root,localhost,82,383,QUERY,`test`,'select \'hello\'
LIMIT 0, 1000',0

Last column is return code. 0 is Ok. Else - error.

like image 27
Nick Avatar answered Oct 04 '22 02:10

Nick


Even though this question is quite old I hope it will be useful to someone who searched for mysql log error queries or similar terms.

Not too long ago I also required mysqld to log only erroneous queries. I found that mysql-proxy enables you to do that and wrote a small LUA script:

local err_flag = false
function read_query( packet )
    if packet:byte() == proxy.COM_QUERY then
        local user = proxy.connection.client.username
        local host = proxy.connection.client.src.name
        if user:lower() == 'someuser' then -- change this to any condition where errors should be logged
            proxy.queries:append(1, packet, {resultset_is_needed = true})
            proxy.queries:append(2, string.char(proxy.COM_QUERY) .. "SET @last_query = '" .. string.sub(packet, 2) .. "'", {resultset_is_needed = true} )
            proxy.queries:append(3, string.char(proxy.COM_QUERY) .. "SHOW WARNINGS", {resultset_is_needed = true} )
        end
        return proxy.PROXY_SEND_QUERY
    end
end


function insert_query(err_t, err_n, err_m)
  local query = "INSERT INTO `somedb`.`mysql_error` " .. -- change log destination 
    "(`date`, `err_num`,`err_type`, `err_message`, `problem_query`, `conn_id`)" ..
    " VALUES ( NOW(), " ..
    err_n  ..  "," .. "\"" ..
    err_t .."\"" .. "," .. "\"" ..
    err_m .. "\"" .. "," ..
    "@last_query" .. "," ..
    proxy.connection.server.thread_id .. ")"
    proxy.queries:append(4, string.char(proxy.COM_QUERY) .. query, {resultset_is_needed = true})
    return proxy.PROXY_SEND_QUERY
end


function read_query_result(inj)
    local res = assert(inj.resultset)
    if inj.id == 1 then
        err_flag = false
        if res.query_status == proxy.MYSQLD_PACKET_ERR then
            err_flag = true
            return proxy.PROXY_IGNORE_RESULT
        end
    elseif inj.id == 2 then
        return proxy.PROXY_IGNORE_RESULT
    elseif inj.id == 3 then
        if err_flag == true then
            for row in res.rows do
                proxy.response.type = proxy.MYSQLD_PACKET_ERR
                proxy.response.errmsg = row[3]
                insert_query(row[1], row[2], row[3])
            end
            return proxy.PROXY_SEND_RESULT
        end
        return proxy.PROXY_IGNORE_RESULT
    elseif inj.id == 4 then
        return proxy.PROXY_IGNORE_RESULT
    end
end

DDL needed for logging table, adjust somedb.mysql_error to liking, but don't forget to do so in the above LUA script also.

CREATE TABLE `somedb`.`mysql_error` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `date` datetime NOT NULL,
    `err_num` smallint(6) NOT NULL,
    `err_type` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
    `err_message` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
    `problem_query` varchar(8000) COLLATE utf8_unicode_ci NOT NULL,
    `conn_id` int(11) NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

To use the script, run

/path/to/mysql-proxy --proxy-lua-script=/path/to/mysql-proxy-log-error-queries.lua

or if that fails (>=v0.9)

/path/to/mysql-proxy --proxy-lua-script=/path/to/mysql-proxy-log-error-queries.lua --plugins=proxy

The proxy runs on port 4040 by default, to test:

mysql -u username -p --host=127.0.0.1 --port=4040

and run some faulty sql.

When everything seems to be in order set the port in your application to 4040 instead of the actual mysqld port and you have mysql error logging on the database level.

Final note: mysql-proxy is beta. Use with caution I guess. Been running here for almost half a year now without problems, however YMMV.

like image 25
kon Avatar answered Oct 04 '22 02:10

kon


I have tried running an error query on purpose, but it logs as a normal query and doesn't report it with error. Any ideas?

so, you did it wrong. No other idea without the code.

in PHP I'm doing it this way (assume you're using mysql driver):

$res=mysql_query($sql) or trigger_error(mysql_error().$sql);

it will log all erroneous queries if you have log_errors setting on (and you have to)

EDIT: I see now, you want global level logging,m not application level. But may be application level will suit you as well?

like image 36
Your Common Sense Avatar answered Oct 04 '22 01:10

Your Common Sense