数据库进程间通信解决方案
$Id: MySQL-plugin.xml 587 2013-12-16 14:00:00Z netkiller $
摘要
你是否想过当数据库中的数据发生变化的时候出发某种操作?但因数据无法与其他进程通信(传递信号)让你放弃,而改用每隔一段时间查询一次数据变化的方法?下面的插件可以解决你的问题。
原文出处:http://netkiller.github.io/journal/mysql.plugin.fifo.html
你是否有这样的需求:
你需要监控访问网站的IP,当同一个IP地址访问次数过多需要做出处理,例如拉黑,直接丢进iptables 防火墙规则连中。你的做法只能每个一段时间查询一次数据库,并且判断是否满足拉黑需求?
你是否需要监控某些数据发生变化,并通知其他程序作出处理。例如新闻内容修改后,需要立即做新页面静态化处理,生成新的静态页面
你使用数据库做队列,例如发送邮件,短信等等。你要通知发送程序对那些手机或者短线发送数据
需要让数据库与其他进程通信,传递信号
例如,发送短信这个需求,你只要告诉发短信的机器人发送的手机号码即可,机器人永远守候那哪里,只要命令一下立即工作。
监控数据库变化的需求原理类似,我们需要有一个守护进程等待命令,一旦接到下达命令便立即生成需要的静态页面
这里所提的方案是采用fifo(First In First Out)方案,通过管道相互传递信号,使两个进程协同工作,这样的效率远比定时任务高许多。fifo是用于操作系统内部进程间通信,如果跨越操作系统需要使用Socket,还有一个新名词MQ(Message queue).
这里只做fifo演示, 将本程序改为Socket方案,或者直接集成成熟的MQ也是分分钟可以实现。
有了上面的function后你就可以在begin,commit,rollback 直接穿插使用,实现在事物处理期间做你爱做的事。也可以用在触发器与EVENT定时任务中。
https://github.com/netkiller/mysql-fifo-plugin
编译udf,最后将so文件复制到 /usr/lib/mysql/plugin/
git clone https://github.com/netkiller/mysql-image-plugin.git cd mysql-image-plugin gcc -O3 -g -I/usr/include/mysql -I/usr/include -fPIC -lm -lz -shared -o fifo.so fifo.c sudo mv fifo.so /usr/lib/mysql/plugin/
装载
create function fifo_create returns string soname fifo.so; create function fifo_remove returns string soname fifo.so; create function fifo_read returns string soname fifo.so; create function fifo_write returns string soname fifo.so;
卸载
drop function fifo_create; drop function fifo_remove; drop function fifo_read; drop function fifo_write;
我们假设有一个demo这样的表,我使用shell写了一个守护进程用于处理数据库送过来的数据
#!/bin/bash ######################################## # Homepage: http://netkiller.github.io # Author: neo netkiller@msn.com ######################################## NAME=demo PIPE=/tmp/myfifo ######################################## LOGFILE=/tmp/$NAME.log PIDFILE=/tmp/${NAME}.pid ######################################## function start(){ if [ -f "$PIDFILE" ]; then exit 2 if [ ! -f "$LOGFILE" ]; then ${LOGFILE} for (( ; ; )) while read line NOW=$(date +%Y-%m-%d %H:%M:%S) echo "[${NOW}] [OK] ${line}" ${LOGFILE} done $PIPE done echo $! $PIDFILE function stop(){ [ -f $PIDFILE ] kill `cat $PIDFILE` rm -rf $PIDFILE case "$1" in start) start stop) stop status) ps ax | grep ${0} | grep -v grep | grep -v status restart) stop start echo $"Usage: $0 {start|stop|status|restart}" exit 2 exit $?
启动守护进程
$ ./sms.sh start $ ./sms.sh status 596 pts/5 S 0:00 /bin/bash ./sms.sh start
监控日志,因为守护进程没有输出,完成人户后写入日志。
$ tail -f /tmp/demo.log
开始推送任务
mysql select fifo_write(/tmp/myfifo,concat(mobile,\r\n)) from demo; +-------------------------------------------------+ | fifo_write(/tmp/myfifo,concat(mobile,\r\n)) | +-------------------------------------------------+ | true | | true | | true | +-------------------------------------------------+ 3 rows in set (0.00 sec)
现在看看日志的变化
$ tail -f /tmp/demo.log [2013-12-16 14:55:48] [OK] 13113668891 [2013-12-16 14:55:48] [OK] 13113668892 [2013-12-16 14:55:48] [OK] 13113668893
我们再将上面的例子使用触发器进一步优化
CREATE TABLE `demo_sent` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `mobile` VARCHAR(50) NOT NULL, `status` ENUM(true,false) NOT NULL DEFAULT false, `ctime` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) COLLATE=utf8_general_ci ENGINE=InnoDB CREATE DEFINER=`dba`@`%` TRIGGER `demo_after_insert` AFTER INSERT ON `demo` FOR EACH ROW BEGIN insert into demo_sent(mobile,status) select new.mobile,fifo_write(/tmp/myfifo,concat(new.mobile,)) as status;
测试
mysql insert into demo(name,mobile) values(jerry,13322993040); Query OK, 1 row affected (0.05 sec)
日志变化
$ tail -f /tmp/demo.log [2013-12-16 14:55:48] [OK] 13113668891 [2013-12-16 14:55:48] [OK] 13113668892 [2013-12-16 14:55:48] [OK] 13113668893 [2013-12-16 14:55:48] [OK] 13322993040
我们可以采用主从数据库,将任务放在专用的从库上执行
我们可以创建很多个管道,用于做不同的工作,例如插入一个任务,更新一个任务,发短信一个任务,处理模板与静态化一个任务等等。
netkiller Nickname:netkiller | English name: Neo chen | QQ: 291379 | 订阅号:netkiller-ebook | 网站:http://www.netkiller.cn
相关文章
- 时序数据库influxdb体验
- 在postgresql数据库中创建只读用户的操作
- 讲解Oracle数据库中结束死锁进程的一般方法
- 删除EM,强制结束EM进程后,启动数据库ORA-00119,ORA-00132报错的解决方法
- mysql遇见contains nonaggregated column ‘information_schema.PROFILING.SEQ’异常详解数据库
- MySQL进程监控:深入了解数据库性能(mysql进程监控)
- MySQL数据库中的增删改查操作代码(mysql增删改查代码)
- MySQL数据库中的进程ID解析(mysql进程id)
- Oracle数据库是否需要JDK?(oracle需要jdk吗)
- 企业信息化Oracle数据库驱动企业全面信息化进程(oracle数据库实现)
- Linux下搭建完善的数据库连接池(linux数据库连接池)
- 优化极致优化:Oracle 数据库进程(oracle数据库进程)
- 查看Oracle数据库进程的简单方法(查询oracle进程数)
- Oracle数据库如何处理死锁进程?(oracle死锁进程)
- Oracle RAC进程:实现高可用数据库的关键技术(oraclerac进程)
- 优化MySQL进程内存优化:提升数据库性能(mysql进程内存)
- 解决MySQL数据库乱码问题(mysql乱码问题)
- 高可用性!MySQL双机热备方案让你的数据库永不停机(mysql双机热备方案)
- 「杀」手手法 | 如何「杀死」Oracle进程,解决数据库卡顿问题(杀死oracle进程)
- 利用电脑远程连接MSSQL数据库(电脑远程连接mssql)
- 数据库在本地计算机上搭建MSSQL数据库(在本地计算机上mssql)
- 写分离SQL Server读写分离:提高数据库性能的利器(sqlserver读)
- 如何获得Oracle数据库中表格的返回时间?(oracle返回时间)
- SQL Server数据库中的与或非运算(sqlserver与或非)
- ODBC库链接MSSQL:构建高效的数据库结构(odbc库 mssql)
- 重塑数据库:完善Oracle记录(更新oracle记录)
- 如何使用Redis将数据存储到数据库(往redis存数据库)
- Oracle数据库全量增量更新的解决方案(oracle全量增量更新)
- Oracle写入进程提高数据库性能及加快写入速度(oracle写入进程)
- Oracle 1435推动企业数据库进程变革(oracle-1435)
- 检查电脑是否安装了Redis数据库(查看是否有安装redis)
- AIX系统下优雅关闭Oracle数据库进程(Aix停oracle进程)
- Oracle数据库主进程安全运行的关键(oracle 主进程)
- Oracle数据库管理之五大进程(oracle五大进程)
- MySQL 数据库不能提交问题解决办法(mysql不能提交数据库)
- Oracle数据库优化之三板斧法(oracle优化 三板斧)
- Oracle数据库实用手册(oracle中手册)
- 解除Oracle数据库中的LCK进程(oracle中lck进程)
- 深入理解Oracle数据库管理之DBA进程(oracle中dba进程)
- PHPXML备份Mysql数据库
- SQLServer数据库实用SQL语句
- 如何区分SQL数据库中的主键与外键