mysql觸發器(trigger)操作memcache

安裝遇到的問題:

對memcache的操作一般都是放程序裏面去操作的,新增,更新,刪除什麼的。如果能利用mysql來對memcache進行操作,那就更好,代碼端就會簡單一點。但是利用mysql來操作memcache,比較適合實現簡單的方式。下面說一下安裝的過程和遇到的問題,在看安裝過程的之前,我覺得應當先看一下,我安裝時候所遇到的問題,這樣你可以避免掉,少走一點彎路。

一,安裝所要的軟件

mysql5.1以上版本:http://downloads.mysql.com/archives/

libevent下載:wget  http://www.monkey.org/~provos/libevent-1.2.tar.gz

libmemcached下載:http://download.tangent.org/

memcached下載:http://www.danga.com/memcached/

memcached_functions_mysql下載:http://download.tangent.org/

 

二,mysql的安裝

mysql的安裝方式有很多,你可以用系統的軟件管理包來安裝,不同的linux版本,軟件管理工具是不一樣的。

redhat,centos 有yum,ubuntu 有apt-get ,arch有pacman等。用系統自帶的管理工具安裝比較簡單。如果是自己下載怎麼安裝的呢,mysql的官方網站提供了三種mysql的安裝源碼,一種是.rpm的,一種是二進制的,一種是要自己編譯的。

1,用rpm來按裝

  1. rpm -i MySQL-server-VERSION.i386.rpm  
  2. rpm -i MySQL-client-VERSION.i386.rpm  

2,二進制包進行安裝

二進制包安裝有一個缺點,就是要安裝到什麼地方,都是死的。安裝過程中有問題的,查看一下是不是裝了glibc,以及版本是不是太低了。

  1. groupadd mysql  
  2. useradd -g mysql mysql  
  3. tar zxvf /path/to/mysql-VERSION-OS.tar.gz -C /usr/local  
  4. cd /usr/local  
  5. mv mysql-VERSION-OS ./mysql  
  6. cd /usr/local/mysql  
  7. scripts/mysql_install_db        --user=mysql  
  8. chown  -R mysql:mysql /usr/local/mysql  
  9. bin/mysqld_safe --user=mysql        &  

3,源碼自己編譯

  1. groupadd mysql  
  2. useradd -g mysql mysql  
  3. tar zxvf /path/to/mysql-VERSION-OS.tar.gz  
  4. cd /mysql-VERSION-OS  
  5. ./configure --prefix=/usr/local/mysql  //路徑可自定義   
  6. make && make install  
  7. cp support-files/my-medium.cnf /etc/my.cnf  
  8. cd /usr/local/mysql  
  9. bin/mysql_install_db --user=mysql  
  10. chown  -R mysql:mysql /usr/local/mysql  
  11. bin/mysqld_safe --user=mysql &  

安裝遇難問題:安裝mysql至少要5.1版本以上的,服務器端,還是客戶端都要,裝完memcached_functions_mysql後,調用libmemcached模塊時會報錯的。

[root@BlackGhost sql]#  /usr/local/mysql/bin/mysql <install_functions.sql
ERROR 1126 (HY000) at line 1: Can't open shared library 'libmemcached_functions_mysql.so' (errno: 22 /usr/local/mysql/lib/mysql/plugin/libmemcached_functions_mysql.so: undefined symbol: memcached_string_append)

上面是用mysqld_safe來啓動mysql的,也可以用mysql.server來啓動,它在/usr/local/mysql/share/mysql 下面,你也可以把mysql.server考到開機啓動的目錄下面,並且重命名爲mysqld

[root@BlackGhost mysql]# ./mysql.server stop
Shutting down MySQL.. SUCCESS!
[root@BlackGhost mysql]# ./mysql.server start
Starting MySQL. SUCCESS!

二,關於libevent和memcached的安裝

1.deb

Debian 系直接 $  sudo apt-get install memcached   都搞定,不然還需要分別安裝libevent與memcached

2.源碼安裝

wget  http://www.monkey.org/~provos/libevent-1.2.tar.gz   #下載libevent

1 .查看是否已經安裝了libevent,一般情況下,裝系統的時候libevent就會裝進去的。
ls -al /usr/lib | grep libevent

 

[root@BlackGhost etc]# ls -al /usr/lib | grep libevent
lrwxrwxrwx  1 mysql mysql       21 Mar 25  2009 libevent-1.2.so.1 -> libevent-1.2.so.1.0.3
-rwxr-xr-x  1 mysql mysql   208300 Mar 25  2009 libevent-1.2.so.1.0.3
-rw-r--r--  1 mysql mysql   268992 Mar 25  2009 libevent.a
-rwxr-xr-x  1 mysql mysql      820 Mar 25  2009 libevent.la
lrwxrwxrwx  1 mysql mysql       21 Mar 25  2009 libevent.so -> libevent-1.2.so.1.0.3
如果顯示上面內容說明你已安裝了,就可以跳過第二步。

2 . 先安裝libevent:

第一種方法
tar zxvf libevent-1.2.tar.gz
cd libevent-1.2
./configure --prefix=/usr
make
make install

第二種方法

用系統自命的軟件管理工具,archlinux用pacman,centos用yum ,大便用apt-get等

[root@BlackGhost etc]# pacman -Ss libevent
core/libevent 1.4.11-1
An event notification library

安裝完後在進行第一步,進行測試

3 . 安裝memcached服務器端:
tar zxvf memcached-1.2.0.tar.gz
cd memcached-1.2.0
./configure  --with-libevent=/usr    --prefix=/usr/local/memcahced
make
make install
如果有錯,請確認一下,local下面有memcahced這個文件夾,以及libevent的安裝路徑是否正確

4 .啓動memcached服務

/usr/local/bin/memcached -d -m 20 -u zhangy -p 11211 -P ./memcached.pid

-d #作爲守護進程運行

-m#分配20M的內存

-u #用戶是zhangy

-p #監聽端口是12000

-P#進程PID存放的位置

[zhangy@BlackGhost ~]$ ps -e|grep memcache
17904 ?        00:00:00 memcached

到此memcached的服務器端已經安裝。

三,libmemcached的安裝


$ tar xvzf  libmemcached-0.34.tar.gz 
cd libmemcached-0.34
$  ./configure --prefix=/usr/local/libmemcached34 --with-memcached=/usr/bin/memcached
sudo make
sudo make install
$ sudo chmod 777 /etc/ld.so.conf
$ echo "/usr/local/libmemcached34" >> /etc/ld.so.conf
$ ldconfig

注意路徑不要錯了。install_functions.sql定義了一些memcache的操作函數:如下到這兒安裝基本上結束,下面我們來測試一下

1.當時我下載的是libmemcached-0.42.tar.gz,安裝memcached_functions_mysql過程中遇到這樣一個問題

servers.c:263:28: error: 'memcached_st' has no member named 'hosts'
servers.c:264:28: error: 'memcached_st' has no member named 'hosts'

後來我在網上查一下,libmemcached-0.34沒有這個問題

2. libmemcached-0.37會 遇到  ERROR 1126 (HY000) at line 38: Can't open shared library 'libmemcached_functions_mysql.so' (errno: 0 /usr/local/mysql/lib/plugin/libmemcached_functions_mysql.so: undefined symbol: memcached_string_append)

所以推薦安裝 ibmemcached-0.34。

3.在安裝libmemcached的時候,如果不是默認安裝,需要指定memcached安裝路徑。

 

四,安裝memcached_functions_mysql

  1. tar xzf memcached_functions_mysql-0.9.tar.gz  
  2. cd memcached_functions_mysql-0.9  
  3. ./configure --prefix=/usr/local/memcache_mysql --with-mysql=/usr/local/mysql/bin/mysql_config --with-libmemcached=/usr/local/libmemcached37  
  4. make && make install  
  5. cp /usr/local/memcache_mysql/lib/libmemcached_functions*   /usr/local/mysql/lib/mysql/plugin

別忘了加上--with-libmemcached=/usr/local/libmemcached34 不然會報以下錯誤

checking for mysql_config... /usr/bin/mysql_config
checking for libmemcached >= 0.17... configure: error: libmemcached not found

如果是mysql 5.5 mysql插件的目錄是/usr/local/mysql/lib/plugin

 

創建mysql的memcache操作函數

$ mysql < sql/install_functions.sql

mysql如果不是默認安裝,需要指定路徑。

也可以在mysql管理裏面運行install_functions.sql的sql腳本。

mysql>  source sql/install_functions.sql

 

這樣我們就可以使用mysql memcached UDF 了,我們可以通過下面語句查看是否已經正常安裝
mysql>  select * from mysql.func;
+------------------------------+-----+---------------------------------+----------+
| name | ret | dl | type |
+------------------------------+-----+---------------------------------+----------+
| memc_add | 2 | libmemcached_functions_mysql.so | function |
| memc_add_by_key | 2 | libmemcached_functions_mysql.so | function |
| memc_servers_set | 2 | libmemcached_functions_mysql.so | function |
32 rows in set (0.00 sec)

添加trigger ,就是向memcache內insert,update,deletel等,參照:
1)memcached_functions_mysql-0.9/sql 目錄下的trigger_fun.sql
2)或者文檔:http://dev.mysql.com/doc/refman/5.1/en/ha-memcached-interfaces-mysqludf.html
如果懶得看就看我後邊的例子

五,測試

例子1:

mysql> select memc_servers_set('127.0.0.1:11211')
注意:如果mysql restart,需要重新運行這句以建立與memcached之間的關係
mysql>  select memc_servers_behavior_set('MEMCACHED_BEHAVIOR_NO_BLOCK','1');
+--------------------------------------------------------------+
| memc_servers_behavior_set('MEMCACHED_BEHAVIOR_NO_BLOCK','1') |
+--------------------------------------------------------------+
| 0 |
+--------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>  select memc_servers_behavior_set('MEMCACHED_BEHAVIOR_TCP_NODELAY','1');
+-----------------------------------------------------------------+
| memc_servers_behavior_set('MEMCACHED_BEHAVIOR_TCP_NODELAY','1') |
+-----------------------------------------------------------------+
| 0 |
+-----------------------------------------------------------------+
1 row in set (0.00 sec)
注意:設置MEMCACHED_BEHAVIOR_NO_BLOCK爲打開狀態,這樣在memcached出現問題時(不能連接時)
數據繼續插入到mysql中,報錯提示,如果不設置此值,如果memcached失敗,mysql需要等到timeout
纔可以插入到表中。
mysql> use test;
Database changed
 
mysql> create table xxd (id int, value varchar(100));    
mysql> create trigger xxdmmci after insert on xxd for each row set @tmp = memc_set(NEW.id, NEW.value);
mysql> create trigger xxdmmcu after update on xxd for each row set @tmp = memc_set(NEW.id, NEW.value);
mysql> create trigger xxdmmcd before delete on xxd for each row set @tmp = memc_delete(OLD.id);
mysql> insert into xxd values(1, 'xxd'),(2,'xxd79'),(3, 'buro79xxd');         
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0
 
mysql> select memc_get('2');
+----------------------------+
| memc_get('2')              |
+----------------------------+
| xxd79 |
+----------------------------+
1 row in set (0.00 sec)
mysql> update xxd set value='xxd_new' where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0
mysql> select memc_get('1');
+----------------------------+
| memc_get('1')              |
+----------------------------+
| xxd_new |
+----------------------------+
1 row in set (0.00 sec)
mysql> delete from xxd where id=1;
Query OK, 1 row affected (0.00 sec)
 
mysql> select memc_get('1');
+----------------------------+
| memc_get('1')              |
+----------------------------+
| NULL |
+----------------------------+
1 row in set (0.00 sec)
mysql> exit
$  telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
get 1
END
get 2
VALUE 2 0 5
xxd79
END
get 3
VALUE 3 0 9
buro79xxd
END
quit
Connection closed by foreign host.

例子2:
  1. //創建一個測試有   
  2. drop table if  exists urls;  
  3. create table urls (  
  4.  id int(3) not null,  
  5.  url varchar(64) not null default   '' ,  
  6.  primary key (id)  
  7.  );  
  8.   
  9. //連接memcched,根啓動memcahed的端口要一樣   
  10. select memc_servers_set('127.0.0.1:12000,127.0.0.1:13000' );  
  11. //設置一個開始序列   
  12. select memc_set('urls:sequence' , 0);  
  13.   
  14. //創建插入memcached觸發器   
  15. DELIMITER |  
  16.   
  17. DROP TRIGGER IF EXISTS url_mem_insert |  
  18. CREATE TRIGGER url_mem_insert  
  19. BEFORE INSERT ON urls  
  20. FOR EACH ROW BEGIN  
  21.  SET NEW.id= memc_increment('urls:sequence' );  
  22.  SET @mm= memc_set(concat('urls:' ,NEW.id), NEW.url);  
  23. END  |  
  24.   
  25. //創建更新memcached觸發器   
  26. DROP TRIGGER IF EXISTS url_mem_update |  
  27. CREATE TRIGGER url_mem_update  
  28. BEFORE UPDATE ON urls  
  29. FOR EACH ROW BEGIN  
  30.  SET @mm= memc_replace(concat('urls:' ,OLD.id), NEW.url);  
  31. END  |  
  32.   
  33. //創建刪除memcached觸發器   
  34. DROP TRIGGER IF EXISTS url_mem_delete |  
  35. CREATE TRIGGER url_mem_delete  
  36. BEFORE DELETE  ON urls  
  37. FOR EACH ROW BEGIN  
  38.  SET @mm= memc_delete(concat('urls:' ,OLD.id));  
  39. END  |  
  40.   
  41. DELIMITER ;  //寫觸發器的時候,我們會用;mysql執行分割符也是;所以我們在寫觸發器或者是存儲過程的時候都會改變一下,例如:DELIMITER |   
  42.   
  43. //插入一些測試數據   
  44. insert into urls (url) values ('http://google.com' );  
  45. insert into urls (url) values ('http://baidu.com/' );  
  46. insert into urls (url) values ('http://www.51yip.com/' );  
  47. insert into urls (url) values ('http://blog.51yip.com/' );  
  48. insert into urls (url) values ('http://51yip.com' );  
  49. insert into urls (url) values ('http://mysql.com' );  
  50. select * from urls;  
  51.   
  52. //將插入的6條數據顯示出來,下面的顯示和刪除也是一樣的不多說了。   
  53. select memc_get('urls:1' );  
  54. select memc_get('urls:2' );  
  55. select memc_get('urls:3' );  
  56. select memc_get('urls:4' );  
  57. select memc_get('urls:5' );  
  58. select memc_get('urls:6' );  
  59.   
  60. update urls set url= 'http://mysql.com/sun'  where url =  'http://51yip.com' ;  
  61. select url from urls where url = 'http://51yip.com/manual' ;  
  62. select memc_get('urls:6' );  
  63.   
  64. delete  from urls where url =  'http://blog.51yip.com/' ;  
  65. select * from urls where url='http://blog.51yip.com/' ;  
  66. select memc_get('urls:4' );  

我以前寫過一篇:關於memcache的key的管理,徘徊中 (http://blog.51yip.com/php/729.html)裏面提到對單表進行緩存 ,可以完全配合這篇文章所說的東西。如果有多表聯合查詢的話,在用觸器就比較麻煩了,還不如放到程序裏去執行

 

引用原文地址:

1.http://blog.51yip.com/cache/76.html

2.http://archive.cnblogs.com/a/2022594/

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章