21

Need help with MySQL as it's not really my forte. So any help is appreciated.

I have issues on my site where UPDATE or INSERT were done with missing values. This caused some issues on other functions on the site, but I am not able to find where the UPDATE or INSERT were done in any of the classes.

Is there any way, maybe a MySQL trigger, that I could add to these tables that would allow me to store the original or full query of the UPDATE or INSERT. I have tried logging but that applies to the whole database and it takes up too much diskspace.

Thanks in advance for any replies.

PS: At the moment, the PHP classes are a bit messy as we're still in the development stage, so adding exceptions to the updates or inserts functions will take too much time. So please focus the answer to the question. Thanks again.

4

8 に答える 8

41

次のステートメントを使用して、現在の SQL クエリを文字列として取得できます。

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

したがって、次のように、(i)現在の SQL ステートメントを取得し、(ii)それを別のテーブルに挿入するTRIGGER必要がある、テーブルの挿入および/または更新操作で実行される を作成する必要があります。

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 ;

更新用と挿入用の 2 つのトリガーを作成する必要があります。app_sql_debug_logトリガーは、列のテーブルに新しいクエリを文字列として挿入しqueryます。

于 2012-05-20T06:54:14.363 に答える
4

データベースサーバーの 一般的なクエリログを確認する必要があると思います。

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

于 2012-05-17T01:20:08.713 に答える
1

データベースで値が欠落したくない場合は、制約を使用してそれを強制できますか?

于 2012-05-26T07:05:48.327 に答える
1

データベースに正確にログインする必要はありません。

file_put_contentsをFILE_APPENDとともに使用し、タブ区切り文字を使用して、またはcsvとしてテキストファイルに保存します。これにより、必要なときにデータベースに簡単にインポートしたり、必要なときにいつでもExcelまたはNumbers(Macの場合)でファイルを表示したりできます。

テキストファイルを日付別にログに記録することができます。つまり、sql_queries_2012-05-24で、フォルダーに保存するだけです。テキストファイルは、データベースに保存するよりも多くのスペースを必要としません。phpdate関数を使用した単純な'ifelse'ステートメントは、ログを日付でソートする必要があります。

テキストファイルを使用すると、データベースに保存するよりもリソースのコスト効率が高くなります。さらに、php fgetcsvを使用してインデックスを作成し、テキストファイルからINSERTを実行すると、mysqlUPDATEを使用するよりもはるかに高速になります。

于 2012-05-24T03:17:53.323 に答える
0

MySQLに送信するものをログに記録するようにアプリケーションを変更することも(通常はソリューション#1)、一般的なクエリログを有効にすることもできない場合(ソリューション#2ですが、本番環境ではありません)-MySQLプロキシを使用することをお勧めします。これを参照してください:https ://github.com/mysql/mysql-proxy

MySQLプロキシは、クライアント(PHPスクリプト)とMySQLサーバーの間に配置できる軽量のプログラムです。MySQLサーバー自体を実行しているのと同じサーバーでMySQLプロキシを実行し、クライアントをMySQLサーバーではなくプロキシポートに直接接続させることができます(クライアントを変更できない場合は、MySQLサーバーを別のポートに移動してMySQLプロキシを設定できます)以前にMySQLサーバーで使用されていたポートへ)。

次に、MySQLプロキシをカスタムスクリプトで拡張できます。カスタムスクリプトは、新しい接続、サーバーに送信されたクエリなど、さまざまなタイプのイベントをキャッチできます。クエリの場合、ログに記録したり、ブロックしたり、クエリを変更したりする柔軟性があります。 、または実際に送信されたクエリに加えて、新しいクエリを追加します。

悪いニュース-カスタムスクリプトはLua http://dev.mysql.com/doc/refman/5.5/en/mysql-proxy-scripting.htmlに実装されています。朗報-MySQLプロキシ用のサンプルLuaスクリプトがたくさんあります。たとえば、ここにあります:http: //forge.mysql.com/wiki/Lua_Scripts_For_MySQL_Proxy_Examples。特に、「不要なクエリのブロック」の例を確認して、必要に応じて変更することをお勧めします(実際には何もブロックしませんが、特定のクエリをログに出力します)。

MySQLプロキシはオーバーヘッドを追加しますが、一般的にはかなり軽量です。Luaスクリプトも軽量に保つと、問題なく動作するはずです。

編集:

リポジトリの最終更新日は2014年で、現在、バージョンアーカイブには次のように記載されています。

MySQLプロキシはGAではないため、本番環境での使用はお勧めしません。

本番環境での使用にはMySQLルーターをお勧めします。MySQLルーターをダウンロード»

悲しいことに、MySQLルーターはMySQLプロキシと同じ種類の機能を許可しているようには見えません。

于 2012-05-25T19:27:59.430 に答える
0

シンプルな PHP ベースのソリューション

override_functionPHP で使用し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;
}
于 2012-05-26T06:38:16.773 に答える
-1

サーバーに PHP 5.3.0 以降がインストールされている場合、これが役に立つかもしれません http://www.php.net/manual/en/mysqlnd.plugin.php

于 2012-05-19T08:23:51.157 に答える
-2

おそらく、すべての更新を確認できるように、バイナリ ログを有効にする必要があります (注: すべてのクエリではありません)。オプションを追加して--log-binから、 を使用して結果のログを調べるだけですmysqlbinlog。必要に応じて、バックアップからデータベースのコピーを開始し、バックアップの位置からログを開始し (--master-dataオプションのようなものを使用してバックアップに保存されますmysqldump)、更新を一度に 1 つずつ実行して、悪い列。その後、どのアップデートが原因であるかがわかります。最後の部分をスクリプト化するか、ログの長さに対してバイナリ検索を使用して、ログを高速化することができます。

于 2012-05-19T08:51:35.517 に答える