Вопрос по mysql – Получить полную строку MySQL Query при вставке или обновлении

18

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

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

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

Заранее спасибо за любые ответы.

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

Tiberiu-Ionut Stan @ Да, используя PHP с CodeIgniter. asyadiqin
Что ты используешь в коде? PHP? Если да, я предоставлю вам быстрое, грязное и полностью рабочее решение. Tiberiu-Ionuț Stan
если мы не увидим код и ошибку, я уверен, что мы не сможем оказать большую помощь. Поэтому, пожалуйста, оставьте свой код / ошибка Satya
Я опубликовал здесь одно хорошее решение: Stackoverflow.com / а / 26604340/1328818 John F
Satya @ Ошибка связана не с MySQL, а с нашими основными PHP-классами. Так что это не актуально. Я просто ищу способы входа оператора SQL UPDATE или INSERT на 2 таблицы в базе данных. Благодарность asyadiqin

Ваш Ответ

8   ответов
31

го оператора:

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

То, что вам нужно сделать, это создатьTRIGGER который выполняется на операциях вставки и / или обновления в вашей таблице, которые должны(я получить текущий 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 колонка.

Спасибо за это. Будучи начинающим пользователем MySQL, два написанных вами триггера предназначены для двух таблиц, например. Таблица A и Таблица B. Итак, я должен добавить триггеры для каждой таблицы? Извините, если этот вопрос звучит глупо, но на самом деле я никогда не делаю много работы над MySQL, и триггеры для меня совершенно новые. Надеюсь услышать вас снова asyadiqin
Я очень стараюсь понять таблицу PROCESSLIST. На данный момент я ничего не сделал на столах. Я просто вставил новую запись, а также UPDATE в две таблицы, но когда я запрашиваю таблицу PROCESSLIST, в этой таблице нет ничего, чтобы показать запрос, который я только что сделал. Я что-то здесь упускаю? Еще раз спасибо asyadiqin
Triggers запускаются только одним событием - например, SELECT OR DELETE. В вашем случае вам нужны триггеры для операций INSERT и UPDATE, поэтому у вас должно быть два триггера для каждой таблицы: один запускается в INSERT, а другой - в операторах UPDATE. УВЕДОМЛЕНИЕ: «ДО ВСТАВКИ НАyour_table "Измените ключевое слово INSERT на UPDATE для второго триггера. Удачи! Itay Grudev
В таблицах PROCESSLIST отображаются текущие рабочие запросы. Пока триггер работает, ваш запрос все еще там, и к нему можно получить доступ. Itay Grudev
Я всегда получаю информацию SELECT FROM ... как последний запрос ... есть идеи почему? Cristian Rusu
4

Общий журнал запросов вашего сервера БД.

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

Это прекрасно работает, если нет хранимых процедур. Мы ищем способ получить логи даже внутри SP, чтобы увидеть, какие именно запросы вызвали изменение данных. psuhas
Ravinder @ Я думаю, что он регистрирует ВСЕ операторы SQL в базе данных, и у вас есть возможность либо записать его в файл, либо в таблицу. Как я уже упоминал, я пробовал это, но это занимает много места на диске, так как он регистрирует все. Я смотрю только на получение операторов SQL, если INSERT или UPDATE выполняется для 2 таблиц, а не для всей базы данных. Если я не прав, не могли бы вы дать мне пример того, как получить общий журнал запросов для записи операторов SQL, когда вносятся изменения в 2 конкретные таблицы, например. Таблица A и Таблица B asyadiqin
Это может сработать. Установите общий журнал запросов для сохранения в log_table и добавьтеINSERT триггер, который разрешает только запросы, которыеLIKE '%INSERT %' а такжеLIKE '%tableA%' для фактической вставки в log_table (чтобы сэкономить место) ypercubeᵀᴹ
@ ypercube - Хорошая идея! Но не уверен, каковы накладные расходы. Ravinder Reddy
1

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

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

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

0

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

0

Простое решение на основе 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;
}
0

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

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

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

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

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

РЕДАКТИРОВАТЬ

Последнее обновление хранилища произошло в 2014 году, и в настоящее время версии архивов скажи это

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

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

MySQL Router не выглядит так, как он, к сожалению, обеспечивает такую же функциональность, как MySQL Proxy.

-1

это может быть полезноhttp: //www.php.net/manual/en/mysqlnd.plugin.ph

-1

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

Похожие вопросы