当 root 或其他人编辑或更新特定数据库时,如何从 MySQL 获取邮件?它应该触发发送邮件并记录编辑。
我试过触发器,但它不起作用。
服务器规格:
我试过的脚本
#!/bin/sh
tail -f /var/log/mysql/mysql.log | egrep 'INSERT|UPDATE|DELETE|root'
| mail -s 'backend update' sushanth@example.com
Run Code Online (Sandbox Code Playgroud)
但它不工作
MySQL 没有任何内置的特定 SMTP 设置、机制或驱动程序。
但是,您可以通过两项基本操作来进行所需的监控。
选项 1:您可以监控二进制日志
如果启用了二进制日志,您可以编写一个shell脚本来调用mysql并执行SHOW MASTER STATUS;如果文件名或文件大小发生变化,则某些内容发生变化。一旦检测到,您可以发送一封电子邮件表示发生了变化!
尝试这样的事情:
FIRST_READ=1
while [ 1 -eq 1 ]
do
mysql -h... -u... -p... --skip-column-names -A -e"SHOW MASTER STATUS" > /tmp/ms.txt
currfile=`cat /tmp/ms.txt | awk '{print $1}'`
currsize=`cat /tmp/ms.txt | awk '{print $2}'`
if [ ${FIRST_READ} -eq 0 ]
then
SOMETHING_CHANGED=2
if [ "${prevfile}" == "${currfile}" ] ; then (( SOMETHING_CHANGED-- )) ; fi
if [ "${prevsize}" == "${currsize}" ] ; then (( SOMETHING_CHANGED-- )) ; fi
if [ ${SOMETHING_CHANGED} -gt 0 ]
then
echo "Something Changed" | mail -s "Something Changed Subject" abc@xyz.com
fi
fi
FIRST_READ=0
prevfile=${currfile}
prevsize=${currsize}
sleep 10
done
Run Code Online (Sandbox Code Playgroud)
选项 2:您可以监控 information_schema.tables
您可以循环遍历每个表并检查 information_schema.tables 中的 UPDATE_TIME 列
首先收集所有以数据库开头的表名。然后,循环遍历所有表名并检查 information_schema.tables 中的该条目。
尝试以下操作(过去 10 分钟内发生更改的任何表):
mysql -h... -u... -p... --skip-column-names -A -e"SELECT CONCAT(table_schema,'.',table_name) FROM information_schema.tables WHERE table_schema NOT IN ('information_schema','mysql') AND engine IS NOT NULL" > /tmp/TableNamesToPoll.txt
while [ 1 -eq 1 ]
do
for DBTB in `cat /tmp/TableNamesToPoll.txt`
do
DB=`echo ${DBTB} | sed 's/\./ /g' | awk '{print $1}'`
TB=`echo ${DBTB} | sed 's/\./ /g' | awk '{print $2}'`
NEWUPDATE=`mysql -h... -u... -p... --skip-column-names -A -e"SELECT IFNULL(update_time,NOW() - INTERVAL 100 YEAR) > (NOW() - INTERVAL 10 MINUTE) UpdatedRecently FROM information_schema.tables WHERE table_schema='${DB}' AND table_name='${TB}'"`
if [ ${NEWUPDATE} -eq 1 ]
then
echo "Something Changed in ${DBTB}" | mail -s "Something Changed Subject" abc@xyz.com
fi
done
sleep 5
done
Run Code Online (Sandbox Code Playgroud)
这些只是检测变化的框架脚本。对于选项 1,您可以针对当前二进制日志执行 mysqlbinlog,并查看在您需要的任何时间范围内执行的 SQL。对于选项 2,您可以更改 SQL 以检索给定表的上次更新的日期时间戳。
更新 2011-06-29 06:30 美国东部时间
选项 3:您可以监控一般日志
有趣的是,您可以激活通用日志。更有趣的是,您可以将其激活为 MySQL 表。通用日志作为表的模板已作为general_log.CSV 存在于/var/lib/mysql/mysql 中。步骤如下:
步骤01)将这些添加到/etc/my.cnf
[mysqld]
log-output=TABLE
log
Run Code Online (Sandbox Code Playgroud)
步骤02)service mysql restart(general_log是重启后的CSV表)
步骤03)运行这些命令将general_Log从CSV转换为MyISAM
SET GLOBAL general_log = 'OFF';
ALTER TABLE mysql.general_log ENGINE = MyISAM;
ALTER TABLE mysql.general_log ADD INDEX (event_time);
Run Code Online (Sandbox Code Playgroud)
步骤04)将general_log文件移动到一个可以容纳快速增长的日志表的巨大磁盘卷
示例:如果您有以下磁盘布局
[root@iml-db10 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vg1-root 117G 3.2G 108G 3% /
/dev/mapper/vg2-data01
1.7T 688G 877G 44% /data
/dev/sdc1 3.6T 36G 3.4T 2% /backup
/dev/sda1 99M 18M 77M 19% /boot
tmpfs 95G 0 95G 0% /dev/shm
none 16G 51M 16G 1% /var/tmpfs
Run Code Online (Sandbox Code Playgroud)
执行以下步骤移动通用日志表:
mkdir /backup/general_log
mv /var/lib/mysql/mysql/general_log.MY* /backup/general_log/.
chown -R mysql:mysql /backup/general_log
ln -s /backup/general_log/general_log.MYD /var/lib/mysql/mysql/general_log.MYD
ln -s /backup/general_log/general_log.MYI /var/lib/mysql/mysql/general_log.MYI
Run Code Online (Sandbox Code Playgroud)
何时确保符号链接存在
[root@db1]# ls -l /var/lib/mysql/mysql/general*
-rw-rw---- 1 mysql mysql 8776 Jun 25 15:53 /var/lib/mysql/mysql/general_log.frm
lrwxrwxrwx 1 root root 35 Jun 25 18:33 /var/lib/mysql/mysql/general_log.MYD -> /backup/general_log/general_log.MYD
lrwxrwxrwx 1 root root 35 Jun 25 18:32 /var/lib/mysql/mysql/general_log.MYI -> /backup/general_log/general_log.MYI
Run Code Online (Sandbox Code Playgroud)
步骤 05) 运行此 SQL 命令
SET GLOBAL general_log = 'ON';
Run Code Online (Sandbox Code Playgroud)
就是这样。您应该将 General_log 作为 MyISAM 表
mysql> show create table mysql.general_log\G
*************************** 1. row ***************************
Table: general_log
Create Table: CREATE TABLE `general_log` (
`event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`user_host` mediumtext NOT NULL,
`thread_id` int(11) NOT NULL,
`server_id` int(10) unsigned NOT NULL,
`command_type` varchar(64) NOT NULL,
`argument` mediumtext NOT NULL,
KEY `event_time` (`event_time`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='General log' DATA DIRECTORY='/backup/general_log/' INDEX DIRECTORY='/backup/general_log/'
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
您需要做的就是通过运行此查询的 crontab 每 15 分钟轮询一次 General_log 表
SELECT COUNT(1) UpdateCount FROM mysql.general_log
WHERE LOCATE('UPDATE',argument) > 0
AND event_time >= (NOW() - INTERVAL 15 MINUTE);
SELECT COUNT(1) DeleteCount FROM mysql.general_log
WHERE LOCATE('DELETE',argument) > 0
AND event_time >= (NOW() - INTERVAL 15 MINUTE);
Run Code Online (Sandbox Code Playgroud)
警告:条目会很快堆积起来。删除保留最近 3 天的所有事件。每晚午夜在 crontab 中运行此命令
SET @old_log_state = @@global.general_log;
SET GLOBAL general_log = 'OFF';
DELETE FROM mysql.general_log WHERE event_time < NOW() - INTERVAL 3 DAY;
SET GLOBAL slow_query_log = @old_log_state;
Run Code Online (Sandbox Code Playgroud)
尝试一下!
归档时间: |
|
查看次数: |
14419 次 |
最近记录: |