Подтвердить что ты не робот

Получить полную строку запроса MySQL вставить или обновить

Нужна помощь с MySQL, поскольку это не моя сильная сторона. Поэтому любая помощь приветствуется.

У меня есть проблемы на моем сайте, где UPDATE или INSERT были выполнены с отсутствующими значениями. Это вызвало некоторые проблемы с другими функциями на сайте, но я не смог найти, где были UPDATE или INSERT в любом из классов.

Есть ли какой-либо способ, возможно, триггер MySQL, который я мог бы добавить к этим таблицам, что позволило бы мне сохранить исходный или полный запрос UPDATE или INSERT. Я попытался войти в систему, но это относится ко всей базе данных, и она занимает слишком много дискового пространства.

Заранее благодарим за любые ответы.

PS: На данный момент классы PHP немного беспорядочны, поскольку мы все еще находимся на стадии разработки, поэтому добавление исключений из функций обновлений или вставок займет слишком много времени. Поэтому, пожалуйста, сосредоточьте свой ответ на вопросе. Еще раз спасибо.

4b9b3361

Ответ 1

Вы можете получить текущий SQL-запрос в виде строки со следующим выражением:

SELECT info FROM INFORMATION_SCHEMA.PROCESSLIST WHERE id = CONNECTION_ID()

Итак, вам нужно создать TRIGGER, который запускается в операциях insert и/или update в вашей таблице, который должен (i) получить текущую инструкцию sql и (ii) вставить ее в другую таблицу, например

DELIMITER |

CREATE TRIGGER log_queries_insert BEFORE INSERT ON `your_table`
FOR EACH ROW
BEGIN
    DECLARE original_query VARCHAR(1024);
    SET original_query = (SELECT info FROM INFORMATION_SCHEMA.PROCESSLIST WHERE id = CONNECTION_ID());
    INSERT INTO `app_sql_debug_log`(`query`) VALUES (original_query);
END;
|
DELIMITER ;

Вам нужно будет создать два триггера: один для обновлений и один для вставок. Триггер вставляет новый запрос в виде строки в таблице app_sql_debug_log в столбце query.

Ответ 2

Я думаю, вам нужно проверить Общий журнал запросов вашего сервера db.

The server ... ... logs each SQL statement received from clients. ... ... Since MySQL 5.1.6 log can be a file or a table.

Ответ 3

Вам не нужно регистрировать его в базе данных.

Используйте file_put_contents с файлом FILE_APPEND и сохраните его в текстовом файле, используя разделители табуляции или как csv. Таким образом, вы можете легко импортировать в базу данных, когда вам нужно или просмотреть файл в Excel или Numbers (на Mac), когда вам это нужно.

Вы можете зарегистрировать текстовый файл по датам, то есть sql_queries_2012-05-24, и просто сохранить его в папке. Текстовые файлы не должны занимать больше места, чем хранить его в базе данных. Простой оператор if if с функциями php date должен получить регистрацию, отсортированную по датам.

Использование текстовых файлов, безусловно, более экономично в ресурсах, чем хранение их в базе данных. Более того, использование php fgetcsv для индексации и INSERT из текстовых файлов намного быстрее, чем использование mysql UPDATE.

Ответ 4

Если вы не можете изменить приложение для регистрации того, что вы отправляете в MySQL (обычно, решение № 1), и вы не можете включить общий журнал запросов (решение № 2, но да, а не для производства) - вы можете использовать MySQL Proxy. Смотрите это: https://github.com/mysql/mysql-proxy

MySQL Proxy - это легкая программа, которую вы можете установить между вашим клиентом (скрипты PHP) и сервером MySQL. Вы можете запустить MySQL Proxy на том же сервере, на котором вы запускаете сам сервер MySQL, и заставлять своих клиентов напрямую подключаться к прокси-порту вместо сервера MySQL (если вы не можете изменить клиент, вы можете переместить сервер MySQL на другой порт и настроить MySQL Proxy к порту, ранее используемому MySQL Server).

Затем прокси MySQL может быть расширен с помощью специальных скриптов, где ваш пользовательский script может захватывать различные типы событий: новые подключения, запросы, отправленные на сервер, и т.д. Для запросов вы имеете возможность регистрировать их или блокировать их, или изменить запрос, или добавить новые запросы в дополнение к тем, которые действительно отправлены, что угодно.

Плохая новость - пользовательские скрипты реализованы в Lua (http://dev.mysql.com/doc/refman/5.5/en/mysql-proxy-scripting.html). Хорошие новости - вы можете найти множество образцов сценариев Lua для прокси-сервера MySQL. Например здесь: http://forge.mysql.com/wiki/Lua_Scripts_For_MySQL_Proxy_Examples. В частности, вы можете проверить пример "Блокировать нежелательные запросы" и изменить его на свои нужды (вы фактически ничего не блокируете, но будете печатать определенные запросы в журнале).

MySQL Proxy добавляет некоторые накладные расходы, но в целом он довольно легкий. Если вы также сохраните свои сценарии Lua, все должно быть в порядке.

EDIT:

Репозиторий был обновлен в 2014 году, и в настоящее время архивы версий говорят следующее:

MySQL Proxy не является GA и не рекомендуется для использования в целях производства.

Мы рекомендуем MySQL Router для использования в производстве. Загрузить MySQL Router"

MySQL-маршрутизатор не похож на то, что он с одинаковой функциональностью, как MySQL Proxy, печально.

Ответ 5

Простое решение на основе PHP

Используйте override_function в PHP, чтобы переопределить mysql_query своей собственной функцией, которую вы можете использовать для профилирования и/или регистрации любого из запросов.

rename_function('mysql_query', 'mysql_query_orig');
override_function('mysql_query', '$query', 'return override_mysql_query($query);');

function override_mysql_query($query)
{
    $result = mysql_query_orig($query);

    if (stripos($query, "mytablename") !== FALSE) {
        // log, echo, etc.
    }

    return $result;
}

Ответ 6

Если вы не хотите, чтобы какое-то значение отсутствовало в базе данных, можете ли вы использовать ограничение для принудительного выполнения этого?

Ответ 8

Вероятно, вы захотите включить двоичный журнал, чтобы вы могли посмотреть каждое обновление (обратите внимание: не каждый запрос). Вам просто нужно добавить параметр --log-bin, а затем просмотреть полученный журнал, используя mysqlbinlog. Если необходимо, вы можете запустить копию своей базы данных из резервной копии, начать в журнале в позиции резервной копии (сохранить в резервной копии с помощью чего-то вроде параметра --master-data до mysqldump) и запустить обновления в время, пока вы не получите плохой ряд. Затем вы знаете, какое обновление является виновником. Вы можете script использовать эту последнюю часть и/или использовать двоичный поиск по длине журнала, чтобы ускорить его работу.