借助zabbix和mysql performance monitor模板实现mysql数据库的监控

1.安装mpm需要的相关依赖包:[保险起见,agent端也安装下面的依赖包]

  1. [root@client141 ~]# yum -y install perl-File-Which perl-libwww-perl perl-Digest-SHA1 perl-DBD-MySQL perl-Time-HiRes perl-Crypt-SSLeay  
  2. # 上面perl-File-Which没有自带,需要自行下载安装(如果还提示perl包,根据需要安装相应perl版本)  
  3. [root@client141 ~]#  rpm -ivh perl-File-Which-1.09-5.1.noarch.rpm   

2.下载mpm并解压:[解压后会产生两个压缩包]

  1. [root@client141 ~]# tar -zxvf mysql_performance_monitor-latest.tar.gz  
  2. mysql_performance_monitor_agent-0.9.1.tar.gz  
  3. mysql_performance_monitor_templates-0.9.1.tar.gz  

3.在zabbixe服务端或者是web端解压模板文件:

  1. [root@client141 ~]# tar -zxvf mysql_performance_monitor_templates-0.9.1.tar.gz  
  2. mysql_performance_monitor_templates-0.9.1/  
  3. mysql_performance_monitor_templates-0.9.1/CHANGELOG  
  4. mysql_performance_monitor_templates-0.9.1/xml/  
  5. mysql_performance_monitor_templates-0.9.1/xml/Template_FromDual.MySQL.ndb.xml  
  6. mysql_performance_monitor_templates-0.9.1/xml/Template_FromDual.MySQL.security.xml  
  7. mysql_performance_monitor_templates-0.9.1/xml/Template_FromDual.MySQL.innodb.xml  
  8. mysql_performance_monitor_templates-0.9.1/xml/Template_FromDual.MySQL.mpm.xml  
  9. mysql_performance_monitor_templates-0.9.1/xml/Template_FromDual.MySQL.myisam.xml  
  10. mysql_performance_monitor_templates-0.9.1/xml/Template_FromDual.MySQL.mysql.xml  
  11. mysql_performance_monitor_templates-0.9.1/xml/Template_FromDual.MySQL.aria.xml  
  12. mysql_performance_monitor_templates-0.9.1/xml/Template_FromDual.MySQL.galera.xml  
  13. mysql_performance_monitor_templates-0.9.1/xml/Template_FromDual.MySQL.slave.xml  
  14. mysql_performance_monitor_templates-0.9.1/xml/Template_FromDual.MySQL.server.xml  
  15. mysql_performance_monitor_templates-0.9.1/xml/clone_screen.txt  
  16. mysql_performance_monitor_templates-0.9.1/xml/Template_FromDual.MySQL.master.xml  
  17. mysql_performance_monitor_templates-0.9.1/xml/Template_FromDual.MySQL.drbd.xml  
  18. mysql_performance_monitor_templates-0.9.1/xml/Template_FromDual.MySQL.pbxt.xml  
  19. mysql_performance_monitor_templates-0.9.1/xml/Template_FromDual.MySQL.process.xml  

4.在zabbix server端或web导入相应模板文件:[加粗部分为需要导入的模板]

  1. [root@client141 ~]# cd mysql_performance_monitor_templates-0.9.1/xml/  
  2. 在Zabbix Web UI导入监控所需的模板(“Configuration”->”Templates”->”Import”):  
  3. 具体模板文件用途如下:  
  4. Template_FromDual.MySQL.ndb.xml              # 监控mysql cluster  
  5. Template_FromDual.MySQL.security.xml  
  6. Template_FromDual.MySQL.innodb.xml      # 监控innodb存储引擎状态变量  
  7. Template_FromDual.MySQL.mpm.xml         # 监控mpm agent本身,这个必须导入  
  8. Template_FromDual.MySQL.myisam.xml    # 监控myisam存储引擎状态变量  
  9. Template_FromDual.MySQL.mysql.xml       # 监控mysql 常用状态变量  
  10. Template_FromDual.MySQL.aria.xml             # 监控aria存储引擎的状态变量  
  11. Template_FromDual.MySQL.galera.xml          # 监控 mysql galera cluster  
  12. Template_FromDual.MySQL.slave.xml        # 监控mysql主从复制中的slave的状态  
  13. Template_FromDual.MySQL.server.xml      # 监控linux系统跟数据库使用相关的附加项  
  14. Template_FromDual.MySQL.master.xml     # 监控mysql主从复制的master的状态  
  15. Template_FromDual.MySQL.drbd.xml            # 监控drbd 设备的状态信息  
  16. Template_FromDual.MySQL.pbxt.xml             # 监控pbxt存储引擎状态变量  
  17. Template_FromDual.MySQL.process.xml        # 监控各种linux进程(比如:mysqld,ndbd)  

5.在客户端[mysql 数据库服务器端] 安装mysql_performance_monitor_agent

  1. [root@client100 ~]# tar -zxvf mysql_performance_monitor_agent-0.9.1.tar.gz  
  2. [root@client100 ~]# mv mysql_performance_monitor_agent-0.9.1 /usr/local/mysql_performance_monitor_agent  
  3. [root@client100 ~]# cd /usr/local/mysql_performance_monitor_agent/  
  4. # 修改 FromDualMySQLagent.pl 文件,指定zabbix_sender的位置  
  5. [root@client100 mysql_performance_monitor_agent]# sed -i ‘s|/usr/local/bin|/usr/bin|g’ FromDualMySQLagent.pl  
  6. # 编辑配置文件  
  7. [root@client100 mysql_performance_monitor_agent]# cd etc/  
  8. [root@client100 etc]# cp FromDualMySQLagent.conf.template /etc/FromDualMySQLagent.conf  
  9. [root@client100 etc]# vim /etc/FromDualMySQLagent.conf  
  10. [default]  
  11. Type = mysqld  
  12. Debug = 2  
  13.   
  14. #执行日志文件路径,需要zabbix用户可写权限  
  15. LogFile       = /var/log/zabbix/FromDualMySQLagent.log  
  16. CacheFileBase = /var/log/zabbix/cache/FromDualAgentCache  
  17.   
  18. #需要在Mysql中进行授权  
  19. Username = mpm  
  20. Password = kongzhong  
  21. MysqlHost = 127.0.0.1  
  22. MysqlPort = 3306  
  23. ZabbixServer = 192.168.1.141  
  24. Disabled = false  
  25. Modules = process mysql myisam innodb  
  26. #ClusterLog   = /var/lib/mysql-cluster/ndb_1_cluster.log  
  27.   
  28. # Mysql的PID文件,需要zabbix用户可读权限  
  29. PidFile      = /var/run/mysqld/mysqld.pid  
  30. #[db_server]  
  31. #Type         = mysqld  
  32. #Modules      = mpm server  
  33. #下面的主机名需要跟Zabbix Server里面定义的主机名一致  
  34. [client100]  
  35. Type = mysqld  
  36. #这些模块必须在mysql数据库上已经实现了功能,如主从,如果没有配置主从,而添加了master模板,在执行过程中就会报错  
  37. Modules = mpm server process mysql myisam innodb master   
  38. PidFile      = /var/run/mysqld/mysqld.pid  

6.修改zabbix agent 配置文件:

  1. # 这个参数配置文件,是自己新建的  
  2. [root@client100 ~]# vim /etc/zabbix/zabbix_agentd.d/FromDual_MySQL_monitoring.conf   
  3. # 添加如下参数:  
  4. UserParameter=FromDual.MySQL.check,/usr/local/mysql_performance_monitor_agent/FromDualMySQLagent.pl /etc/FromDualMySQLagent.conf  

7.登陆数据库,授权相应的mpm用户,权限

  1. mysql> grant process,replication client on *.* to ‘mpm’@’127.0.0.1’ identified by ‘kongzhong’;  
  2. mysql> flush privileges;  

8.修改 FromDualMySQLagent.conf 配置文件相关目录的权限:

  1. # 创建相关日志存放目录:  
  2. [root@client100 ~]# mkdir -p /var/log/zabbix/cache  
  3. # 手动创建日志文件:  
  4. [root@client100 ~]#touch /var/log/zabbix/FromDualMySQLagent.log  
  5. # 修改目录权限:  
  6. [root@client100 ~]#chown zabbix:zabbix /var/log/zabbix/ -R  
  7. # 修改权限  
  8. [root@client100 log]# chmod o+r /var/run/mysqld/mysqld.pid   
  9. # zabbix-agent 重启  
  10. [root@client100 etc]# /etc/init.d/zabbix-agent restart  

9.上面配置完成后,就需要在zabbix web创建组和主机,关联相关模板,这里不演示了

10.简单测试:

(1).检查MPM插件的工作情况:

  1. [root@client100 ~]# /usr/local/mysql_performance_monitor_agent/FromDualMySQLagent.pl  /etc/FromDualMySQLagent.conf  
  2. 1  
  3. # 返回值为1:表示MPM插件正常,重启zabbix_agent,加载mpm插件  

(2).在实际中,如果怀疑是zabbix_agentd问题,使用如下测试方式:

  1. [root@client100 ~]#  zabbix_agentd -c /etc/zabbix/zabbix_agentd.conf -t FromDual.MySQL.check  
  2. FromDual.MySQL.check                          [t|1]  
  3. [root@client100 ~]# zabbix_agentd  -c /etc/zabbix/zabbix_agentd.conf -t system.uptime  
  4. system.uptime                                 [u|6518]  
  5. # 以上能正常返回值,说明zabbix_agent是正常的  

(3). 如果有错误的话,请查看/var/log/zabbix下的相关日志,很多是权限问题,注意查看修改

# 提示pid文件不可读:采用:usermod -G mysql zabbix

(4). 报如下故障时:

  1. ([root@client100 ~]# tail -f /var/log/zabbix/FromDualMySQLagent.log ),其他zabbix服务端、客户端日志都正常,无报错  
  2. 5279:2014-03-17 15:26:39.853 – INFO: FromDual Performance Monitor for MySQL (0.9.1) run started.  
  3. 5279:2014-03-17 15:26:39.867 – WARN:       192.168.1.141, 10051, db_server  
  4. 5279:2014-03-17 15:26:39.867 – WARN:       Connection to zabbix server failed (rc=1305)!  
  5. 5279:2014-03-17 15:26:40.878 – WARN:       192.168.1.141, 10051, db_server  
  6. 5279:2014-03-17 15:26:40.878 – WARN:       Connection to zabbix server failed (rc=1305)!  
  7. 5279:2014-03-17 15:26:40.882 – WARN:       192.168.1.141, 10051, 192.168.1.100  
  8. 5279:2014-03-17 15:26:40.882 – WARN:       Connection to zabbix server failed (rc=1305)!  
  9. 5279:2014-03-17 15:26:41.890 – WARN:       192.168.1.141, 10051, 192.168.1.100  
  10.   
  11. 可采取措施如下步骤:  
  12.    第一步:修改 FromDualMySQLagent.conf 配置文件,注释掉如下部分:[这些注释的部分,因为在zabbix web没有配置此主机]  
  13. # [db_server]  
  14. # Type         = mysqld  
  15. # Modules      = mpm server  
  16.    [client100]  
  17.    Type = mysqld  
  18.    Mysqlport=3306  
  19.    Modules = mpm server process mysql myisam innodb master  
  20.    PidFile      = /var/run/mysqld/mysqld.pid  
  21.   
  22.    第二步: 注释掉模块里检查zabbix server 的语句:  
  23.    [root@client100 ~]# vim /usr/local/mysql_performance_monitor_agent/lib/sendData.pm  
  24. # 注释掉的语句如下:   
  25.   #   $rc = &FromDualMySQLagent::checkConnectionToZabbixServer($main::gParameter{‘ZabbixServer’}, $main::gParameter{‘ZabbixServerPort’}, $main::gParameter{‘Hostname’});  

(5). 要注意 /var/log/zabbix/cache/ 目录下相关文件的权限,保证zabbix用户下

  1. [root@client100 ~]# cd /var/log/zabbix/cache/  
  2. [root@client100 cache]# ll  
  3. -rw-rw-r– 1 zabbix zabbix 0 Mar 22 07:25 FromDualAgentCache.192.168.1.100.cache  
  4. # 特别需要注意的是:此文件没有写入是正常的,因为程序自动清空了此文件,但如果说文件不停的变大,那就说明配置有问题,数据没有发出去  

(6). 报如下错误,处理方式为:

  1. 12933:2014-03-22 06:52:06.005 – INFO: FromDual Performance Monitor for MySQL (0.9.1) run started.  
  2. 12933:2014-03-22 06:52:06.019 – ERR :       Load of cache file failed. rc=1301  
  3. 12933:2014-03-22 06:52:07.029 – ERR :       Load of cache file failed. rc=1301  
  4.   
  5. # 报此错了,上面的文件,也在不断变大,一般是上面文件有错,建议删掉文件,重新启动程序,让程序自己再重新创建个新文件(而不是清空文件)  

(7).在zabbix web 端配置主机组时,主机组为 mysql database (可以设置为其他组,已经测试成功)

 

主从数据一致检查及修复工具:pt-table-checksum和pt-table-sync

首先,这两个命令都是由percona-toolkit提供,可以安装此软件包:

1.percona-toolkit的安装:

(1).安装相关依赖包:

主要有perl,per-DBD-MySQL

(2).安装percona-toolkit

  1. [root@client102 ~]# rpm -ivh percona-toolkit-2.2.6-1.noarch.rpm   
  2. 注:此时安装完成后,上面两个命令就已经有了  

2.在master上做授权操作:(IP为主库IP地址)

  1. mysql> grant select ,process,super,replication slave on *.* to ‘checksums’@’192.168.1.102’ identified by ‘checksums’;  
  2. mysql> flush privileges;  
  3.   注:select:查看所有库的表;process:执行show processlist ;super:设置binlog_format=‘statement’  
  4.          replication slave:show slavehosts  

3.数据库主从结构:

主:192.168.1.102(binlog_format=row)

从:192.168.1.103(binlog_format=row)

(1).主从执行数据一致检查:

  1. [root@client102 ~]# pt-table-checksum h=’192.168.1.102′,u=’checksums’,p=’checksums’,P=3306 -d kz –nocheck-replication-filters –no-check-binlog-format –replicate=kz.checksums  
  2.             TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME TABLE  
  3. 03-09T02:34:46      0      0        2       1       0   0.270 kz.b  
  4.   
  5. 注: –nocheck-replication-filters:不检查复制过滤器(即参数文件里设置的repliacte-do-waild-table等规则)  
  6.        —no-check-binlog-format :不检查复制的binlog格式(这个参数在,binlog_format=row时,一定要加,不然报错)  
  7.        –replicate=kz.checksums:把checksum的信息写入指定库,指定表,建议直接写到被检查的库里  
  8.        –create-replicate-table:这个参数在第一次运行时添加,用于建立checksums表(但是我测试没加,表能正常建立)  
  9.        –ignore-tables=mysql.user:对某个表忽略检查  
  10.   
  11. 执行结果显示参数意义:  
  12.  TS            :完成检查的时间。  
  13. ERRORS     :检查时候发生错误和警告的数量。  
  14. DIFFS        :0表示一致,1表示不一致。当指定–no-replicate-check时,会一直为0,当指定–replicate-check-only会显示不同的信息。  
  15. ROWS       :表的行数。  
  16. CHUNKS    :被划分到表中的块的数目。  
  17. SKIPPED    :由于错误或警告或过大,则跳过块的数目。  
  18. TIME         :执行的时间。  
  19. TABLE       :被检查的表名。  

(2).下面我们制造数据不一致的情况:
我们这里直接复制出查询结果:(我发现,当你数据不一致的情况,复制还是正常的)

  1. 主库数据结果:  
  2. mysql> select * from b;  
  3. +—+——+  
  4. | a | b    |  
  5. +—+——+  
  6. | 1 |    1 |  
  7. | 3 |    3 |  
  8. | 5 |    5 |  
  9. | 6 |    6 |  
  10. | 7 |    7 |  
  11. +—+——+  
  12. 从库数据结果:  
  13. mysql> select * from b;  
  14. +—+——+  
  15. | a | b    |  
  16. +—+——+  
  17. | 1 |    1 |  
  18. | 2 |    2 |  
  19. | 3 |    3 |  
  20. | 4 |    4 |  
  21. | 5 |    5 |  
  22. | 6 |    6 |  
  23. | 7 |    7 |  
  24. +—+——+  
  25. 注:此时数据不一致了吧,但你发现其复制还是正常的  

(3)再次检查数据不一致的情况:

  1. [root@client102 ~]# pt-table-checksum h=’192.168.1.102′,u=’checksums’,p=’checksums’,P=3306 -d kz –nocheck-replication-filters –no-check-binlog-format –replicate=kz.checksums  
  2.             TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME TABLE  
  3. 03-09T02:51:05      0      1        5       1       0   0.041 kz.b  
  4. 注:此时 diffs 显示为1:表示主从数据不一致了  

(4).这是我们需要知道哪些数据不一致了,可以使用如下命令实现(不一致数据太多建议输入到一个文件里)

  1. [root@client102 ~]# pt-table-sync –replicate=kz.checksums h=’192.168.1.102′,u=’checksums’,p=’checksums’ h=’192.168.1.103′,u=’checksums’,p=’checksums’  –print  

(5).我们知道数据不一致,那么就要执行修复操作,如下:

  1. [root@client102 ~]# pt-table-sync –replicate=kz.checksums h=’192.168.1.102′,u=’checksums’,p=’checksums’ h=’192.168.1.103′,u=’checksums’,p=’checksums’  –execute  
  2. 注:此时我们再来看看主从的数据情况(可以使用pt-table-checksum检查,这里为了直观,直接查看数据)  
  3.        以上命令检查有个重要事项:就是这张表上必须有主键或唯一索引  
  4.        监听端口不一致时,说检查比较麻烦,没有测试,等以后用到了再测试  
  5.        我们经常设置从机具有只读属性(read-only=1),但是这个属性对具有super权限的用户是无效的,其可正常写入  
  6. 从数据:[这里我们直接看从上的数据,是不是和主上数据一致就行,发现一致了吧,神奇的东西]  
  7. mysql> select * from b;  
  8. +—+——+  
  9. | a | b    |  
  10. +—+——+  
  11. | 1 |    1 |  
  12. | 3 |    3 |  
  13. | 5 |    5 |  
  14. | 6 |    6 |  
  15. | 7 |    7 |  
  16. +—+——+  

mysql误删除ibdata1之后的恢复方法

环境模拟:
1.删除掉数据目录下,ib*文件:
   [root@jj-svn160_231 data]# rm -rf ib*
2.登录数据库插入数据:[发现数据可以正常插入]
   mysql> use test
   mysql> insert into a select * from a;
解决方法如下:
1.数据库不能停机
2.查看当前数据库进程号:从下面可以看出mysql的进程号为:20301
   [root@jj-svn160_231 test]# ps -ef |grep mysql
root     14473  4261  0 19:27 tty1     00:00:00 ./mysql -uroot -px xxxxxxx
root     19918     1  0 20:14 pts/0    00:00:00 /bin/sh /opt/mysql/bin/mysqld_safe –datadir=/home/mysql/data –pid-file=/home/mysql/data/jj-   svn160_231.dacn.org.pid
mysql    20301 19918  0 20:14 pts/0    00:00:00 /opt/mysql/bin/mysqld –basedir=/opt/mysql –datadir=/home/mysql/data –plugin-dir=/opt/mysql/lib/plugin –user=mysql –log-error=/var/log/mysqld.log –pid-file=/home/mysql/data/jj-svn160_231.dacn.org.pid –socket=/tmp/mysql.sock –port=3306
root     25443 14404  0 21:27 pts/0    00:00:00 ./mysql -uroot -px xxxxxxx
root     25624 14450  0 21:29 pts/1    00:00:00 grep mysql
3.从内存中查看当前ibdatta和ib_logfile文件信息(看到这里我们放心多了,文件还在,只是被标记为删除状态)
  [root@jj-svn160_231 test]# ls -la /proc/20301/fd/ |grep -e ibdata -e ib_
lrwx—— 1 root  root  64 Mar  6 21:30 10 -> /home/mysql/data/ib_logfile0 (deleted)
lrwx—— 1 root  root  64 Mar  6 21:30 11 -> /home/mysql/data/ib_logfile1 (deleted)
lrwx—— 1 root  root  64 Mar  6 21:30 4 -> /home/mysql/data/ibdata1 (deleted)
lrwx—— 1 root  root  64 Mar  6 21:30 9 -> /home/mysql/data/ibdata2 (deleted)
4.此时,直接将内存信息复制到数据目录是不行的,会造成空间损坏,因此我们应该采取加全局读锁操作,讲脏页全部刷入磁盘
   mysql> flush tables with read lock;
5.查看当前innodb引擎的状态:[保证log sequence number的值和last checkpoint 值相等]
   mysql> show  engine innodb  status\G;

LOG

Log sequence number 1838299
Log flushed up to   1838299
Last checkpoint at  1838299
  注:有时脏页比较多,可以设置全局参数,加快速度:mysql> set global innodb_max_dirty_pages_pct=0;
         保证一些后台线程完成它们的工作,如.ibuf=1
————————————-
INSERT BUFFER AND ADAPTIVE HASH INDEX
————————————-
Ibuf: size 1, free list len 0, seg size 2, 0 merges
         purge thread 应该purge了全部的transcations
————
TRANSACTIONS
————
Trx id counter 2B02
Purge done for trx’s n:o < 2503 undo n:o < 0
History list length 39
         确保innodb不再进行写操作:
——–
FILE I/O
——–
I/O thread 0 state: waiting for completed aio requests (insert buffer thread)
I/O thread 1 state: waiting for completed aio requests (log thread)
I/O thread 2 state: waiting for completed aio requests (read thread)
I/O thread 3 state: waiting for completed aio requests (read thread)
I/O thread 4 state: waiting for completed aio requests (read thread)
I/O thread 5 state: waiting for completed aio requests (read thread)
I/O thread 6 state: waiting for completed aio requests (write thread)
I/O thread 7 state: waiting for completed aio requests (write thread)
I/O thread 8 state: waiting for completed aio requests (write thread)
I/O thread 9 state: waiting for completed aio requests (write thread)
Pending normal aio reads: 0 [0, 0, 0, 0] , aio writes: 0 [0, 0, 0, 0] ,
ibuf aio reads: 0, log i/o’s: 0, sync i/o’s: 0
Pending flushes (fsync) log: 0; buffer pool: 0
239 OS file reads, 15 OS file writes, 13 OS fsyncs
0.00 reads/s, 0 avg bytes/read, 0.00 writes/s, 0.00 fsyncs/s
6.以上数值如果都正常的话,则可以把内存的数据复制到数据目录,并修改数据的权限
    [root@jj-svn160_231 test]# cp /proc/20301/fd/10 /home/mysql/data/ib_logfile0
    [root@jj-svn160_231 test]# cp /proc/20301/fd/11 /home/mysql/data/ib_logfile1
    [root@jj-svn160_231 test]# cp /proc/20301/fd/4 /home/mysql/data/ibdata1
    [root@jj-svn160_231 test]# cp /proc/20301/fd/9 /home/mysql/data/ibdata2
    [root@jj-svn160_231 data]# chown mysql. ib*
7.释放全局读锁,并重启数据库,验证数据:
     mysql> unlock tables;
     [root@jj-svn160_231 bin]# /etc/init.d/mysqld restart
     至此,ib* 相关文件就已经全部恢复完成

innodb表,如何利用存在的*.FRM恢复表结构(不讨论数据)

问题描述:innodb表,如何利用存在的*.FRM恢复表结构(不讨论数据)

模拟环境如下:[以下环境与真实环境还是有差距的]
[root@jj-svn160_231 bin]# ./mysql -uroot -pkongzhong
mysql> use test;
Database changed
mysql> create table a(a int) engine=innnodb;
Query OK, 0 rows affected, 2 warnings (0.05 sec)
下面进入数据存放目录,讲原文件重命名
[root@jj-svn160_231 test]# ls
a.frm  a.ibd
[root@jj-svn160_231 test]# mv a.frm a.frm.bak
[root@jj-svn160_231 test]# mv a.ibd a.ibd.bak
重启数据库[真实情况,此处是无法启动的]
[root@jj-svn160_231 bin]# /etc/init.d/mysqld restart
解决方案:
1.创建一个新数据库,库下无表:
   mysql> create database kz;
2.创建一张同名,同引擎的表,字段可以不限,如下:
   mysql> use kz;
   mysql> create table a(a int,b int,c int,d int) engine=innnodb;
3.将原a.frm文件复制到刚才新建的数据库目录下,并覆盖原表结构
  [root@jj-svn160_231 test]# cp a.frm.bak  ../kz/a.frm
4.在参数文件,添加一个参数:

    innodb_force_recovery=1
5.重启数据库:
    [root@jj-svn160_231 bin]# /etc/init.d/mysqld restart
6.登录数据库,查看表结构信息
    [root@jj-svn160_231 bin]# ./mysql -uroot -pkongzhong
    mysql> use kz;
mysql> show tables;
+————–+
| Tables_in_kz |
+————–+
| a            |
+————–+
mysql> show create table a;
+——-+————————————————————————————–+
| Table | Create Table                                                                         |
+——-+————————————————————————————–+
| a     | CREATE TABLE `a` (
`a` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+——-+————————————————————————————–+
         至此,表结构就已经恢复好了。其实后面还需要与原表空间关联,比较复杂,暂不讨论

分布式文档存储数据库:MongoDB

MongoDB官网:http://www.mongodb.org/

       MongoDB:简称分布式文档存储数据库
 
1.概述:
     MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型。
     Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引
     它的特点是高性能、易部署、易使用,存储数据非常方便。
2.主要功能特性有:
     (1).面向集合存储,易存储对象类型的数据。
     (2).模式自由。
     (3).支持动态查询。
     (4).支持完全索引,包含内部对象。
     (5).支持查询。
     (6).支持复制和故障恢复
     (7).使用高效的二进制数据存储,包括大型对象(如视频等)。
     (8).自动处理碎片,以支持云计算层次的扩展性
     (9).支持RUBY,PYTHON,JAVA,C++,PHP等多种语言。
     (10).文件存储格式为BSON(一种JSON的扩展)
     (11).可通过网络访问
3.相关名词解释:
      面向集合(Collenction-Orented):
             意思是数据被分组存储在数据集中,被称为一个集合(Collenction)。
             每个 集合在数据库中都有一个唯一的标识名,并且可以包含无限数目的文档
             集合的概念类似关系型数据库(RDBMS)里的表(table),不同的是它不需要定 义任何模式(schema)。
      模式自由(schema-free):
             意味着对于存储在mongodb数据库中的文件,我们不需要知道它的任何结构定义。
             如果需要的话,你完全可以把不同结构的文件存储在同一个数据库里。
             存储在集合中的文档,被存储为键-值对的形式。
             用于唯一标识一个文档,为字符串类型,而则可以是各中复杂的文件类型
             我们称这种存储形式为BSON(Binary Serialized dOcument Format)。
         注:MongoDB服务端可运行在Linux、Windows或OS X平台,支持32位和64位应用,默认端口为27017。
                推荐运行在64位平台,因为MongoDB在32位模式运行时支持的最大文件尺寸为2GB。
                MongoDB把数据存储在文件中(默认路径为:/data/db),为提高效率使用内存映射文件进行管理。

基于mysql 5.5+mysql-master-ha实现mysql ha架构

    听说很多大公司都在使用mysql ha(mysql-master-ha)的环境,下面,我也试着搭建测试一下。
一.MHA原理及其特点:
1.原理:
       MHA在主服务器发生故障时,自动实现故障转移,快速将从服务器晋级为主服务器(通常在10-30s),而不影响复制的一致性,适用于任何存储引擎
       MHA 提供在线服务器切换,将从服务器器提升为主服务器,时间在0.5-2s,这段时间,数据是无法写入的。
       MHA manager 是通过ssh 连接到 mysql slave服务器上
       MHA 每次从宕掉的主服务器上保存二进制日志,但不是每次都成功(主服务器硬件故障或无法通过ssh访问)
       mysql 5.5支持半同步复制,MHA与半同步复制结合,可以大大降低数据丢失的风险,
2.特性:
   (1).主服务器的自动监控和故障转移
   (2).交互式主服务器故障迁移(使用MHA实现故障迁移,不监控主服务器,出现故障,手工调用MHA切换)
   (3).非交互式的主故障迁移(不监控主服务器,但自动实现故障转移)
   (4).在线切换主服务器
      注: MHA 可以应用于任何复制结构(此点待定)
二.MHA的前提条件:
1.搭建的前提条件:
   (1).mysql 主从复制已配置好(master-slave)
   (2).4台server 设置SSH公钥免密码登录
   (3).操作系统为linux系统(MHA 只支持linux系统)
   (4).单台可写主服务器和多台从服务器或只读服务器
   (5).mysql 版本为5.0或以上版本
   (6).候选主服务器的log-bin必须开启
   (7).所有服务器上的二进制日志和中级日志过滤规则必须相同
   (8).候选服务器上的复制用户必须存在
   (9).保留中继日志和定期清理
        参考文章:http://www.vmcd.org/2012/04/mysql-high-availability-mha/
2.MHA的基本说明:
     MHA由node 和 manage 组成,
     node 安装在每一台mysql服务器上(主从上都要装),
     manage端运行在独立服务器上,也需要安装node节点
3.MHA 切换过程:
   (1).监控和故障转移过程
        检测复制设置和确定当前主服务器
        监控主服务器
        检测主服务器当掉
        再次检测从服务器配置
        关闭当掉的主服务器(可选)
        恢复一个新的主服务器
        激活新的主服务器
        恢复其余的从服务器
        告警(可选)
   (2).在线切换过程
        检测复制设置和确定当前主服务器
        确定新的主服务器
        阻塞写入到当前主服务器
        等待所有从服务器赶上复制
        授予写入到新的主服务器
        重新设置从服务器
三.MHA 部署实例:
    主DB:192.168.1.101
    从DB1:192.168.1.102
    从DB2:192.168.1.103
    MHA管理端:192.168.1.100
    系统版本:red hat linux 6
    数据库版本:mysql 5.5
    注:默认mysql主从配置已经配置完毕

1.对mysql的主从进行半同步配置、从上建立复制的用户和授予相应的权限、日志清除设置

  1. # 所有mysql数据库服务器,安装半同步插件(semisync_master.so,semisync_slave.so)  
  2. mysql> install plugin rpl_semi_sync_master soname ‘semisync_master.so’;      
  3. mysql> install plugin rpl_semi_sync_slave soname ‘semisync_slave.so’;  
  4. # 注:其实master是安装在主,slave是安装在从上,但是我们是涉及从升级为主,所以主从都装  
  5. # 卸载插件使用命令:   
  6. # mysql> uninstall plugin rpl_semi_sync_slave;  
  7. # mysql> uninstall plugin rpl_semi_sync_master;  
  8. # 修改所有数据库服务器的参数文件(/etc/my.cnf),添加内容如下:  
  9. [root@client101-103  ~]# vim /etc/my.cnf  
  10. rpl_semi_sync_master_enabled=1  
  11. rpl_semi_sync_master_timeout=1000  
  12. rpl_semi_sync_slave_enabled=1  
  13. relay_log_purge=0     # 此参数将定期清除中继日志功能关闭  
  14. # 重启数据库,查看同步状态和半同步参数、状态  
  15. [root@client101-103  ~]# /etc/init.d/mysql restart  
  16. # 查看半同步参数:  
  17. mysql> show variables like ‘%sync%’;  
  18. # 查看半同步状态:  
  19. mysql> show status like ‘%sync%’;  
  20. # 有几个状态参数值得关注的:  
  21. rpl_semi_sync_master_status:显示主服务是异步复制模式还是半同步复制模式  
  22. rpl_semi_sync_master_clients:显示有多少个从服务器配置为半同步复制模式  
  23. rpl_semi_sync_master_yes_tx:显示从服务器确认成功提交的数量  
  24. rpl_semi_sync_master_no_tx:显示从服务器确认不成功提交的数量  
  25. rpl_semi_sync_master_tx_avg_wait_time:事务因开启semi_sync,平均需要额外等待的时间  
  26. rpl_semi_sync_master_net_avg_wait_time:事务进入等待队列后,到网络平均等待时间  
  27. # 两台从数据库建立用于复制的用户和密码  
  28. mysql> GRANT REPLICATION SLAVE ON *.* TO ‘slave’@’192.168.1.%’ IDENTIFIED BY ‘slave’;  
  29. mysql> flush privileges;  

2.4台server建立ssh无密码验证登陆

  1. 注:ssh-keygen  -t   rsa:  
  2. # manage 端  
  3. [root@client100 ~]# ssh-keygen  -t rsa  
  4. [root@client100 ~]# ssh-copy-id root@192.168.1.101  
  5. [root@client100 ~]# ssh-copy-id root@192.168.1.102  
  6. [root@client100 ~]# ssh-copy-id root@192.168.1.103  
  7. # 主DB   
  8. [root@client101 ~]# ssh-keygen  -t rsa  
  9. [root@client101 ~]# ssh-copy-id root@192.168.1.100  
  10. [root@client101 ~]# ssh-copy-id root@192.168.1.102  
  11. [root@client101 ~]# ssh-copy-id root@192.168.1.103  
  12. # 从DB1   
  13. [root@client102 ~]# ssh-keygen  -t rsa  
  14. [root@client102 ~]# ssh-copy-id root@192.168.1.100  
  15. [root@client102 ~]# ssh-copy-id root@192.168.1.102  
  16. [root@client102 ~]# ssh-copy-id root@192.168.1.103  
  17. # 从DB2   
  18. [root@client103 ~]# ssh-keygen  -t rsa  
  19. [root@client103 ~]# ssh-copy-id root@192.168.1.100  
  20. [root@client103 ~]# ssh-copy-id root@192.168.1.101  
  21. [root@client103 ~]# ssh-copy-id root@192.168.1.102  

3.在3台数据库节点安装MHA的node节点:

  1. # 如果安装下面包,报依赖关系错,请先安装mysql-share-compat包  
  2. # 先安装下面的 perl-dbd-mysql包  
  3. # 在下面执行perl时,如果出现报错,需要安装如下这几个perl包: perl-devel perl-CPAN  
  4. ## 在192.168.1.101上执行如下操作  
  5. [root@client101 ~]# yum -y install perl-DBD-MySQL  
  6. [root@client101 ~]# tar -xf mha4mysql-node-0.54.tar.gz  
  7. [root@client101 ~]# cd mha4mysql-node-0.54  
  8. [root@client101 mha4mysql-node-0.54]# perl Makefile.PL  
  9. [root@client101 mha4mysql-node-0.54]# make && make install  
  10. # 在192.168.1.102上执行如下操作  
  11. [root@client102 ~]# yum -y install perl-DBD-MySQL  
  12. [root@client102 ~]# tar -xf mha4mysql-node-0.54.tar.gz  
  13. [root@client102 ~]# cd mha4mysql-node-0.54  
  14. [root@client102 mha4mysql-node-0.54]# perl Makefile.PL  
  15. [root@client102 mha4mysql-node-0.54]# make && make install  
  16. # 在192.168.1.103上执行如下操作  
  17. [root@client103 ~]# yum -y install perl-DBD-MySQL  
  18. [root@client103 ~]# tar -xf mha4mysql-node-0.54.tar.gz  
  19. [root@client103 ~]# cd mha4mysql-node-0.54  
  20. [root@client103 mha4mysql-node-0.54]# perl Makefile.PL  
  21. [root@client103 mha4mysql-node-0.54]# make && make install  

4.管理节点安装MHA的manager和node(192.168.1.100):

  1. # 管理节点一定记得装mha4mysql-node-0.54.tar.gz  和  mha4mysql-manager-0.55.tar.gz   
  2. # 管理节点,不装node 会报错的  
  3. # 安装相关perl包(有些包,系统没有自带,需要自行下载安装)  
  4. [root@client100 ~]# yum install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-Config-IniFiles  
  5. [root@client100 ~]# tar -xf mha4mysql-node-0.54.tar.gz  
  6. [root@client100 ~]# cd mha4mysql-node-0.54  
  7. [root@client100 mha4mysql-node-0.54]# perl Makefile.PL  
  8. [root@client100 mha4mysql-node-0.54]# make && make install  
  9.   
  10. [root@client100 ~]# tar -xf mha4mysql-manager-0.55.tar.gz  
  11. [root@client100 ~]# cd mha4mysql-manager-0.55  
  12. [root@client100 mha4mysql-manager-0.55]# perl Makefile.PL  
  13. [root@client100 mha4mysql-manager-0.55]# make && make install  

5.编辑管理节点的配置文件

  1. # 建立配置文件存放目录,并将模板配置文件复制到新建目录  
  2. [root@client100 ~]# mkdir /etc/mastermha  
  3. [root@client100 ~]# mkdir -p /mastermha/app1  
  4. [root@client100 ~]# cd /tmp/mha4mysql-manager-0.55  
  5. [root@client100 mha4mysql-manager-0.55]# cp samples/conf/* /etc/mastermha/  
  6. [root@client100 ~]# vim /etc/mastermha/app1.cnf  
  7. [server default]  
  8. manager_workdir=/masterha/app1  
  9. manager_log=/masterha/app1/manager.log  
  10. user=mha_mon  
  11. password=123456  
  12. ssh_user=root  
  13. repl_user=slave  
  14. repl_password=slave  
  15. ping_interval=1  
  16. shutdown_script=“”  
  17. master_ip_online_change_script=“”  
  18. report_script=“”  
  19.   
  20. [server1]  
  21. hostname=192.168.1.101  
  22. master_binlog_dir=/var/lib/mysql/  
  23. candidate_master=1  
  24.   
  25. [server2]  
  26. hostname=192.168.1.102  
  27. master_binlog_dir=/var/lib/mysql  
  28. candidate_master=1  
  29.   
  30. [server3]  
  31. hostname=192.168.1.103  
  32. #master_binlog_dir=/var/lib/mysql  
  33. no_master=1   

6.在所有数据库节点的机器上进行授权操作(192.168.1.101/192.168.1.102/192.168.1.103)

  1. mysql> grant all privileges on *.* to ‘mha_mon’@’192.168.1.%’ identified by ‘123456’;  
  2. Query OK, 0 rows affected (1.00 sec)  
  3. mysql> flush privileges;  

7.测试ssh连接是否正常

  1. # 所有都为ok 即为正常  
  2. [root@client100 mastermha]# masterha_check_ssh  –global_conf=/etc/mastermha/masterha_default.cnf  –conf=/etc/mastermha/app1.cnf  
  3. Sun Mar  2 14:52:53 2014 – [info] Reading default configuratoins from /etc/mastermha/masterha_default.cnf..  
  4. Sun Mar  2 14:52:53 2014 – [info] Reading application default configurations from /etc/mastermha/app1.cnf..  
  5. Sun Mar  2 14:52:53 2014 – [info] Reading server configurations from /etc/mastermha/app1.cnf..  
  6. Sun Mar  2 14:52:53 2014 – [info] Starting SSH connection tests..  
  7. Sun Mar  2 14:53:04 2014 – [debug]  
  8. Sun Mar  2 14:52:53 2014 – [debug]  Connecting via SSH from root@192.168.1.102(192.168.1.102:22) to root@192.168.1.101(192.168.1.101:22)..  
  9. Sun Mar  2 14:53:03 2014 – [debug]   ok.  
  10. Sun Mar  2 14:53:03 2014 – [debug]  Connecting via SSH from root@192.168.1.102(192.168.1.102:22) to root@192.168.1.103(192.168.1.103:22)..  
  11. Sun Mar  2 14:53:04 2014 – [debug]   ok.  
  12. Sun Mar  2 14:53:04 2014 – [debug]  
  13. Sun Mar  2 14:52:54 2014 – [debug]  Connecting via SSH from root@192.168.1.103(192.168.1.103:22) to root@192.168.1.101(192.168.1.101:22)..  
  14. Sun Mar  2 14:53:04 2014 – [debug]   ok.  
  15. Sun Mar  2 14:53:04 2014 – [debug]  Connecting via SSH from root@192.168.1.103(192.168.1.103:22) to root@192.168.1.102(192.168.1.102:22)..  
  16. Sun Mar  2 14:53:04 2014 – [debug]   ok.  
  17. Sun Mar  2 14:54:53 2014 – [debug]  
  18. Sun Mar  2 14:52:53 2014 – [debug]  Connecting via SSH from root@192.168.1.101(192.168.1.101:22) to root@192.168.1.102(192.168.1.102:22)..  
  19. Sun Mar  2 14:53:53 2014 – [debug]   ok.  
  20. Sun Mar  2 14:53:53 2014 – [debug]  Connecting via SSH from root@192.168.1.101(192.168.1.101:22) to root@192.168.1.103(192.168.1.103:22)..  
  21. Sun Mar  2 14:54:53 2014 – [debug]   ok.  
  22. Sun Mar  2 14:54:53 2014 – [info] All SSH connection tests passed successfully.  

8.测试数据库之间的复制情况:

  1. # 如果正常点额话,下面会有ok显示  
  2. [root@client100 mastermha]# masterha_check_repl –global_conf=/etc/mastermha/masterha_default.cnf  –conf=/etc/mastermha/app1.cnf  
  3. Sun Mar  2 15:10:16 2014 – [info] Reading default configuratoins from /etc/mastermha/masterha_default.cnf..  
  4. Sun Mar  2 15:10:16 2014 – [info] Reading application default configurations from /etc/mastermha/app1.cnf..  
  5. Sun Mar  2 15:10:16 2014 – [info] Reading server configurations from /etc/mastermha/app1.cnf..  
  6. Sun Mar  2 15:10:16 2014 – [info] MHA::MasterMonitor version 0.55.  
  7. Sun Mar  2 15:10:25 2014 – [info] Dead Servers:  
  8. Sun Mar  2 15:10:25 2014 – [info]   192.168.1.101(192.168.1.101:3306)  
  9. Sun Mar  2 15:10:25 2014 – [info] Alive Servers:  
  10. Sun Mar  2 15:10:25 2014 – [info]   192.168.1.102(192.168.1.102:3306)  
  11. Sun Mar  2 15:10:25 2014 – [info]   192.168.1.103(192.168.1.103:3306)  
  12. Sun Mar  2 15:10:25 2014 – [info] Alive Slaves:  
  13. Sun Mar  2 15:10:25 2014 – [info]   192.168.1.102(192.168.1.102:3306)  Version=5.5.36-log (oldest major version between slaves) log-bin:enabled  
  14. Sun Mar  2 15:10:25 2014 – [info]     Replicating from 192.168.1.101(192.168.1.101:3306)  
  15. Sun Mar  2 15:10:25 2014 – [info]     Primary candidate for the new Master (candidate_master is set)  
  16. Sun Mar  2 15:10:25 2014 – [info]   192.168.1.103(192.168.1.103:3306)  Version=5.5.36-log (oldest major version between slaves) log-bin:enabled  
  17. Sun Mar  2 15:10:25 2014 – [info]     Replicating from 192.168.1.101(192.168.1.101:3306)  
  18. Sun Mar  2 15:10:25 2014 – [warning] MySQL master is not currently alive!  
  19. Sun Mar  2 15:10:25 2014 – [info] Checking slave configurations..  
  20. Sun Mar  2 15:10:25 2014 – [info]  read_only=1 is not set on slave 192.168.1.102(192.168.1.102:3306).  
  21. Sun Mar  2 15:10:25 2014 – [warning]  relay_log_purge=0 is not set on slave 192.168.1.102(192.168.1.102:3306).  
  22. Sun Mar  2 15:10:25 2014 – [info] Checking replication filtering settings..  
  23. Sun Mar  2 15:10:25 2014 – [info]  Replication filtering check ok.  
  24. Sun Mar  2 15:10:25 2014 – [info] Starting SSH connection tests..  
  25. Sun Mar  2 15:10:26 2014 – [info] All SSH connection tests passed successfully.  
  26. Sun Mar  2 15:10:26 2014 – [info] Checking MHA Node version..  
  27. Sun Mar  2 15:10:26 2014 – [info]  Version check ok.  
  28. Sun Mar  2 15:10:26 2014 – [info] Getting current master (maybe dead) info ..  
  29. Sun Mar  2 15:10:26 2014 – [info] Identified master is 192.168.1.101(192.168.1.101:3306).  
  30. Sun Mar  2 15:10:26 2014 – [info] Checking SSH publickey authentication settings on the current master..  
  31. Sun Mar  2 15:10:31 2014 – [warning] HealthCheck: Got timeout on checking SSH connection to 192.168.1.101! at /usr/local/share/perl5/MHA/HealthCheck.pm line 298.  
  32. Sun Mar  2 15:10:31 2014 – [info] Checking SSH publickey authentication and checking recovery script configurations on all alive slave servers..  
  33. Sun Mar  2 15:10:31 2014 – [info]   Executing command : apply_diff_relay_logs –command=test –slave_user=’mha_mon’ –slave_host=192.168.1.102 –slave_ip=192.168.1.102 –slave_port=3306 –workdir=/data/log/masterha –target_version=5.5.36-log –manager_version=0.55 –relay_log_info=/var/lib/mysql/relay-log.info  –relay_dir=/var/lib/mysql/  –slave_pass=xxx  
  34. Sun Mar  2 15:10:31 2014 – [info]   Connecting to root@192.168.1.102(192.168.1.102:22)..  
  35. Creating directory /data/log/masterha.. done.  
  36.   Checking slave recovery environment settings..  
  37.     Opening /var/lib/mysql/relay-log.info … ok.  
  38.     Relay log found at /var/lib/mysql, up to mysql-relay-bin.000007  
  39.     Temporary relay log file is /var/lib/mysql/mysql-relay-bin.000007  
  40.     Testing mysql connection and privileges.. done.  
  41.     Testing mysqlbinlog output.. done.  
  42.     Cleaning up test file(s).. done.  
  43. Sun Mar  2 15:10:31 2014 – [info]   Executing command : apply_diff_relay_logs –command=test –slave_user=’mha_mon’ –slave_host=192.168.1.103 –slave_ip=192.168.1.103 –slave_port=3306 –workdir=/data/log/masterha –target_version=5.5.36-log –manager_version=0.55 –relay_log_info=/var/lib/mysql/relay-log.info  –relay_dir=/var/lib/mysql/  –slave_pass=xxx  
  44. Sun Mar  2 15:10:31 2014 – [info]   Connecting to root@192.168.1.103(192.168.1.103:22)..  
  45. Creating directory /data/log/masterha.. done.  
  46.   Checking slave recovery environment settings..  
  47.     Opening /var/lib/mysql/relay-log.info … ok.  
  48.     Relay log found at /var/lib/mysql, up to mysql-relay-bin.000009  
  49.     Temporary relay log file is /var/lib/mysql/mysql-relay-bin.000009  
  50.     Testing mysql connection and privileges.. done.  
  51.     Testing mysqlbinlog output.. done.  
  52.     Cleaning up test file(s).. done.  
  53. Sun Mar  2 15:10:32 2014 – [info] Slaves settings check done.  
  54. Sun Mar  2 15:10:32 2014 – [info]  
  55. 192.168.1.101 (current master)  
  56. +–192.168.1.102  
  57. +–192.168.1.103  
  58.   
  59. Sun Mar  2 15:10:32 2014 – [info] Checking replication health on 192.168.1.102..  
  60. Sun Mar  2 15:10:32 2014 – [info]  ok.  
  61. Sun Mar  2 15:10:32 2014 – [info] Checking replication health on 192.168.1.103..  
  62. Sun Mar  2 15:10:32 2014 – [info]  ok.  
  63. Sun Mar  2 15:10:32 2014 – [warning] master_ip_failover_script is not defined.  
  64. Sun Mar  2 15:10:32 2014 – [warning] shutdown_script is not defined.  
  65. Sun Mar  2 15:10:32 2014 – [info] Got exit code 0 (Not master dead).  
  66.   
  67. MySQL Replication Health is OK.  

9.启动管理节点进程:

  1. [root@client100 mastermha]#nohup masterha_manager –conf=/etc/mastermha/app1.cnf > /tmp/mha_manager.log  </dev/null 2>&1 &  
  2. # 可以用以下命令,查看mha 进程是否启动  
  3. [root@client100 mastermha]# ps -ef |grep mha   
  4. # 检查MHA状态:  
  5. [root@client100 ~]# masterha_check_status  –global_conf=/etc/mastermha/masterha_default.cnf  –conf=/etc/mastermha/app1.cnf  
  6.  app1 (pid:2835) is running(0:PING_OK), master:192.168.1.101  
  7. #  正常情况下,如果为ok,则mha已经配置成功  
  8. # 也可以查看相关日志,/masterha/app1/manager.log 此日记记录详细切换过程  

10.测试:

     关闭目前为主的mysql,仔细查看日志,系统会自动进行切换
注:切换失败后,再次启动管理端,是启不来的,需要删除目录下相关app1.failover.complete,才可正常开启
     各位自行测试,有问题,可以互相探讨。