Несмотря на то, что этот вопрос довольно старый, я надеюсь, что он будет полезен для тех, кто искал запросы об ошибках в журнале mysql или похожие термины.
Не так давно я также требовал, чтобы mysqld регистрировал только ошибочные запросы.Я обнаружил, что mysql-proxy позволяет вам это сделать, и написал небольшой скрипт LUA:
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, необходимый для таблицы журналирования, настройте somedb
. mysql_error
по своему вкусу, но не забудьте:сделайте это также в приведенном выше сценарии LUA.
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
Чтобы использовать сценарий, запустите
/path/to/mysql-proxy --proxy-lua-script=/path/to/mysql-proxy-log-error-queries.lua
или, если это не удастся (> = v0.9)
/path/to/mysql-proxy --proxy-lua-script=/path/to/mysql-proxy-log-error-queries.lua --plugins=proxy
Прокси-сервер по умолчанию работает на порту 4040
, чтобы проверить:
mysql -u username -p --host=127.0.0.1 --port=4040
и запустить какой-то неисправный sql.
Когда все кажется в порядке, установите порт в вашем приложении на 4040 вместо действительного порта mysqld, и у вас будет журнал ошибок mysql на уровне базы данных.
Заключительное примечание: MySQL-прокси является бета-версией. Используйте с осторожностью, я думаю.Работаю здесь уже почти полгода без проблем, однако YMMV.