我有一個PHP應用程序,它爲多個用戶使用單個數據庫。用戶登錄,他們的ID存儲在一個會話中,他們使用應用程序來檢索或更新數據庫中的數據。以每個用戶爲基礎記錄所有MySQL事務
爲了安全/存檔的目的,我想每個用戶都記錄每個SQL事務。請注意,「用戶」不是MySQL用戶,因爲他們只使用一個用戶。我該怎麼做呢?
我目前正在運行Centos 5.8,PHP 5.3.18和MySQL 5.5。
感謝
我有一個PHP應用程序,它爲多個用戶使用單個數據庫。用戶登錄,他們的ID存儲在一個會話中,他們使用應用程序來檢索或更新數據庫中的數據。以每個用戶爲基礎記錄所有MySQL事務
爲了安全/存檔的目的,我想每個用戶都記錄每個SQL事務。請注意,「用戶」不是MySQL用戶,因爲他們只使用一個用戶。我該怎麼做呢?
我目前正在運行Centos 5.8,PHP 5.3.18和MySQL 5.5。
感謝
$sql = "UPDATE table SET col = ?"
$db->prepare($sql);
//some params etc...
$filename = '/dir/logs/log-' . $_SESSION['username'] . '';
$handle = fopen($filename, "wr");
$db->execute();
fwrite($handle, $sql);
這是一個簡單的例子,你如何使用查詢無論是執行和在一個文件中,用戶命名的寫作。那麼,用這種方法,也許你會在執行前得到$ sql的內容,但我認爲你有這個想法。
P.S:THX爲編輯:)
您可以配置MySQL產生General query log(GQL)。此日誌記錄了從所有客戶端收到的已建立的客戶端連接和語句。它是一個常規的文本日誌文件,它按照它們接收的順序記錄每個針對您DBMS的命令。它包含時間戳,標識,命令和參數。
IP地址和會話不存在,因爲數據庫請求通過服務器在本地運行。時間戳允許從您的Web服務器與客戶端的IP條目進行非常精確的匹配,即Apache httpd或Tomcat Access log file(ALF)。
我們使用GQL來增強由GWT Web應用程序產生的稀疏ALF信息。
此示例一般查詢日誌應該給你的想法:
110602 12:55:20 3 Connect [email protected] on w2p
3 Query /* mysql-connector-java-5.1.15 (Revision: ${bzr.revision-id}) */SHOW VARIABLES WHERE Variable_name ='language' OR Variable_name = 'net_write_timeout' OR Variable_name = 'interactive_timeout' OR Variable_name = 'wait_timeout' OR Variable_name = 'character_set_client' OR Variable_name = 'character_set_connection' OR Variable_name = 'character_set' OR Variable_name = 'character_set_server' OR Variable_name = 'tx_isolation' OR Variable_name = 'transaction_isolation' OR Variable_name = 'character_set_results' OR Variable_name = 'timezone' OR Variable_name = 'time_zone' OR Variable_name = 'system_time_zone' OR Variable_name = 'lower_case_table_names' OR Variable_name = 'max_allowed_packet' OR Variable_name = 'net_buffer_length' OR Variable_name = 'sql_mode' OR Variable_name = 'query_cache_type' OR Variable_name = 'query_cache_size' OR Variable_name = 'init_connect'
110602 12:55:21 3 Query /* mysql-connector-java-5.1.15 (Revision: ${bzr.revision-id}) */SELECT @@session.auto_increment_increment
3 Query SHOW COLLATION
3 Query SET NAMES utf8mb4
3 Query SET character_set_results = NULL
3 Query SET autocommit=1
3 Query select * from user where username = 'asdasd' and password = 'aa'
1 Query show global status
110602 12:55:25 1 Query show global status
110602 12:55:30 3 Query select * from user where username = 'costis' and password = 'snafu'
您會如何建議鏈接GQL到實際用戶?這是通過與ALF比較來完成的嗎? – user1032531 2013-04-04 13:26:21
沒錯。您從ALF獲取IP地址,並從GQL獲取用戶名。 – 2013-04-04 13:28:53
我對Tomcat ALF一無所知。我需要學習嗎?我看過我的Apache/var/httpd/access_log文件,但沒有看到我如何將它與MYSQL日誌相關聯。 – user1032531 2013-04-04 13:38:49
您可以打開和閱讀MySQL general query log。它包含了所有類似的疑問:
...
130404 19:02:50 476 Connect [email protected] on test
476 Query SET NAMES utf8
476 Query SELECT * FROM `table1`
130404 19:02:52 476 Quit
130404 19:03:33 477 Connect [email protected] on test
477 Query SET NAMES utf8
...
476,477等都是MySQL的線程ID。每個新的連接都擁有它的ID。 所有你需要知道的你的用戶線程ID。對於PHP mysqli擴展,你可以使用mysqli_thread_id()
echo $_SESSION['username'].' '.
date('Y-m-d H:i:s').' '.
mysqli_thread_id($link);
商店此值介於日誌相匹配。
MySQL線程ID是一種很好的方法,但我對使用MySQL通用查詢日誌持懷疑態度。 – user1032531 2013-04-04 15:13:50
爲什麼要登錄到文件?由於您已經在使用數據庫,因此請記錄到包含timestamp,user-id和SQL語句(以及可能的其他字段)等額外字段的表中,並將SQL存儲在該表中。這樣,您可以使用SQL來過濾日誌,這比將日誌存儲在文件中肯定更加強大/靈活。 – user13955 2013-04-04 13:13:30
您可能是對的,但我認爲它應該在另一個數據庫上,因爲這個是由多個用戶使用的,這對於肯定有更新權限,並且可以很容易地操縱日誌 – 2013-04-04 13:16:22
他說PHP * application *,所以應該因爲大概數據庫只能被應用程序訪問,所以用戶不能直接寫入。 – user13955 2013-04-04 13:18:14