传统复制迁移到GTID复制上?

MySQLA390_Fander 回复了问题 • 2 人关注 • 1 个回复 • 679 次浏览 • 2016-11-15 02:04 • 来自相关话题

shell小招 自动 切换当前会话目录

LinuxA390_Fander 回复了问题 • 4 人关注 • 2 个回复 • 829 次浏览 • 2016-11-15 01:37 • 来自相关话题

记录一次诡异的慢查询问题

MySQLyaowenlong 发表了文章 • 2 个评论 • 594 次浏览 • 2016-11-09 16:11 • 来自相关话题

第一次写事故记录,思路有些混乱,大家将就看一下哈   
   昨天公司促销,今天,研发过来找到我们说他们有个sql跑不出来结果(PS:大促降级我们设置有pt-kill,5秒不出结果的查询会被kill)
我们首先想到的是看监控,从监控数据上看:
系统现象1:cpuload很高,直接打到了10;
     2:网络连接状态正常;
     3:内存使用正常还有30G物理内存:
     4:磁盘io正常,util不到1.
发现只有cpuload很高,并且是user时间占用高,不是sys占用时间。
继续查看mysql的监控数据:连接数正常,300左右,
                活跃连接数正常,10以内。
                qps,2k左右,也不高
               没有超长的锁等待时间,说明不是锁引起,确实是查询很慢。
               还没找到问题所在,继续排查,慢日志,





只有两条,
查看第一条的执行计划:





 
执行计划有 Using filesort ,但是两个查询rows 为1; select 结果基本只有1条少量可能有几条(在研发出了解到);从sql和执行计划来看没发现什么问题,是很简单的查询。
于是想到是否是配置参数的问题,比如innodb_buffer_pool_size配置小了,
发现是80G,并不小;顺便查看了一下状态:

mysql> show status like '%buffer_pool%';
+---------------------------------------+--------------+
| Variable_name                         | Value        |
+---------------------------------------+--------------+
| Innodb_buffer_pool_pages_data         | 5242872      |
| Innodb_buffer_pool_pages_dirty        | 26725        |
| Innodb_buffer_pool_pages_flushed      | 928942474    |
| Innodb_buffer_pool_pages_free         | 3            |
| Innodb_buffer_pool_pages_misc         | 1            |
| Innodb_buffer_pool_pages_total        | 5242876      |
| Innodb_buffer_pool_read_ahead_rnd     | 0            |
| Innodb_buffer_pool_read_ahead         | 12430752     |
| Innodb_buffer_pool_read_ahead_evicted | 53538        |
| Innodb_buffer_pool_read_requests      | 371347304415 |
| Innodb_buffer_pool_reads              | 34573956     |
| Innodb_buffer_pool_wait_free          | 0            |
| Innodb_buffer_pool_write_requests     | 12426911055  |
看起来没有异常;
至此感觉进入了迷茫期了,只是发现了莫名其妙的cpuload高,其它没发现任何异常,诡异啊!
然后继续理清思路,该实例只是一个sharing的一个从库,为啥就这台有问题,其他3台都没有问题。于是开始对比该机器和其他从的机器参数。
发现,numa都是关闭了,磁盘一样,内存一样,等等,cpu貌似不对,有问题的这台机器的cpu核心只有24个,主频只有1.8GHZ,其它是机器是32核心,主频是2.3GHZ;难道问题就这个?cpu太烂?
感觉发现了新大陆一样,等等 不对呀,cpu至少还是24核1.8GHZ,pci-e卡,128G内存的服务器的mysql跑这么简单的sql,QPS只能跑到2k,而且5s都不能出数据,想想都不合理啊。但是到目前都还没发现其它有力证据说明是其他问题,难道需要换服务器,没资源啊。于是就开始浮想翩翩了。不了了之,问题也不能富县,姑且就当是一个灵异事件吧;
然后想着在看看这个sql吧。
mysql> SELECT  so.shipping_no,se.total_deal_price,se.after_discount_price, so.shipping_no  FROM `shipping_order_110` AS `so`  LEFT JOIN `shipping_ext_110` AS `se`  USING (`shipping_no`)  WHERE  (`so`.`order_id` = '810103370')  AND ( `so`.`uid` = '69208878' )     ORDER BY shipping_no;
+-------------+------------------+----------------------+-------------+
| shipping_no | total_deal_price | after_discount_price | shipping_no |
+-------------+------------------+----------------------+-------------+
|  1018668733 |           188.00 |               188.00 |  1018668733 |
+-------------+------------------+----------------------+-------------+
1 row in set (0.01 sec)

mysql> SELECT  so.shipping_no,se.total_deal_price,se.after_discount_price, so.shipping_no  FROM `shipping_order_110` AS `so`  LEFT JOIN `shipping_ext_110` AS `se`  USING (`shipping_no`)  WHERE  (`so`.`order_id` = '810103370')  AND ( `so`.`uid` = '69208878' )     ORDER BY shipping_no;
+-------------+------------------+----------------------+-------------+
| shipping_no | total_deal_price | after_discount_price | shipping_no |
+-------------+------------------+----------------------+-------------+
|  1018668733 |           188.00 |               188.00 |  1018668733 |
+-------------+------------------+----------------------+-------------+
1 row in set (0.01 sec)
连续执行2次,都是0.01秒
去掉order by 子句

mysql> SELECT  so.shipping_no,se.total_deal_price,se.after_discount_price, so.shipping_no  FROM `shipping_order_110` AS `so`  LEFT JOIN `shipping_ext_110` AS `se`  USING (`shipping_no`)  WHERE  (`so`.`order_id` = '810103370')  AND ( `so`.`uid` = '69208878' )   ;
+-------------+------------------+----------------------+-------------+
| shipping_no | total_deal_price | after_discount_price | shipping_no |
+-------------+------------------+----------------------+-------------+
|  1018668733 |           188.00 |               188.00 |  1018668733 |
+-------------+------------------+----------------------+-------------+
1 row in set (0.00 sec)

mysql> SELECT  so.shipping_no,se.total_deal_price,se.after_discount_price, so.shipping_no  FROM `shipping_order_110` AS `so`  LEFT JOIN `shipping_ext_110` AS `se`  USING (`shipping_no`)  WHERE  (`so`.`order_id` = '810103370')  AND ( `so`.`uid` = '69208878' )   ;
+-------------+------------------+----------------------+-------------+
| shipping_no | total_deal_price | after_discount_price | shipping_no |
+-------------+------------------+----------------------+-------------+
|  1018668733 |           188.00 |               188.00 |  1018668733 |
+-------------+------------------+----------------------+-------------+
1 row in set (0.00 sec)
连续执行两次都是0.00秒,sql问题? 虽然不确定是这个问题但是修改后效果确实是有的,于是准备找研发沟通一下是否可以修改一下sql;………………饭点到了,先吃了饭在说吧 这个反正不急(准时吃饭还是有好处呀,不然可能就找不到真实原因了!!)
 
在休的时候,研发有来找我们,说问题有出现了,查不出结果了。
登陆服务器继续排查问题,这次虽然抓住了现场,但是除了之前监控发现的问题,没有任何新的进展!总觉得这个机器不会骗人,哪里来的那么多诡异事件呢,于是继续排查问题,对比一下参数:
问题机器:
mysql>  show variables like '%buff%';
+------------------------------+-------------+
| Variable_name                | Value       |
+------------------------------+-------------+
| bulk_insert_buffer_size      | 8388608     |
| innodb_buffer_pool_instances | 4           |
| innodb_buffer_pool_size      | 85899345920 |
| innodb_change_buffering      | inserts     |
| innodb_log_buffer_size       | 16777216    |
| join_buffer_size             | 67108864    |
| key_buffer_size              | 536870912   |
| myisam_sort_buffer_size      | 8388608     |
| net_buffer_length            | 16384       |
| preload_buffer_size          | 32768       |
| read_buffer_size             | 67108864    |
| read_rnd_buffer_size         | 67108864    |
| sort_buffer_size             | 536870912   |
| sql_buffer_result            | OFF         |
+------------------------------+-------------+
14 rows in set (0.00 sec)
正常机器:
mysql> show variables like '%buff%';
+------------------------------+-------------+
| Variable_name                | Value       |
+------------------------------+-------------+
| bulk_insert_buffer_size      | 8388608     |
| innodb_buffer_pool_instances | 4           |
| innodb_buffer_pool_size      | 85899345920 |
| innodb_change_buffering      | inserts     |
| innodb_log_buffer_size       | 16777216    |
| join_buffer_size             | 2097152     |
| key_buffer_size              | 536870912   |
| myisam_sort_buffer_size      | 8388608     |
| net_buffer_length            | 16384       |
| preload_buffer_size          | 32768       |
| read_buffer_size             | 2097152     |
| read_rnd_buffer_size         | 2097152     |
| sort_buffer_size             | 2097152     |
| sql_buffer_result            | OFF         |
 
read_buffer_size,join_buffer_size,sort_buffer_size,read_rnd_buffer_size
这几个参数的值区别有点大呢,是不是这个问题?老师说这些参数最好不要改大了,不然容易oom,但是没说会影响性能啊,管他呢,先改一波,改小应该没有风险,直接都改小。
重启连接池。问题貌似解决了,至今没有发现问题
然后去官网查了这个几个参数的解释:
 
join_buffer_size:
说了一段这个:Memory allocation time can cause substantial performance drops if the global size is larger than needed by most queries that use it.
sort_buffer_size:
, there are thresholds of 256KB and 2MB where larger values may significantly slow down memory allocation, so you should consider staying below one of those values. Experiment to find the best value for your workload
两个的大意都是说分配内容需要花费很多时间,如果分配或多会严重影响查询效率;
 
经过这次问题:得到两点心得:
       1、找问题一定要有耐性,需要思路清晰,不要轻易相信有灵异事件发生。
       2、遇到所谓的灵异事件,坚持的越久,越可能找到问题所在。
       3、多看官方文档,这个很重要!! 查看全部
第一次写事故记录,思路有些混乱,大家将就看一下哈   
   昨天公司促销,今天,研发过来找到我们说他们有个sql跑不出来结果(PS:大促降级我们设置有pt-kill,5秒不出结果的查询会被kill)
我们首先想到的是看监控,从监控数据上看:
系统现象1:cpuload很高,直接打到了10;
     2:网络连接状态正常;
     3:内存使用正常还有30G物理内存:
     4:磁盘io正常,util不到1.
发现只有cpuload很高,并且是user时间占用高,不是sys占用时间。
继续查看mysql的监控数据:连接数正常,300左右,
                活跃连接数正常,10以内。
                qps,2k左右,也不高
               没有超长的锁等待时间,说明不是锁引起,确实是查询很慢。
               还没找到问题所在,继续排查,慢日志,

慢查询.png

只有两条,
查看第一条的执行计划:

执行计划.png

 
执行计划有 Using filesort ,但是两个查询rows 为1; select 结果基本只有1条少量可能有几条(在研发出了解到);从sql和执行计划来看没发现什么问题,是很简单的查询。
于是想到是否是配置参数的问题,比如innodb_buffer_pool_size配置小了,
发现是80G,并不小;顺便查看了一下状态:

mysql> show status like '%buffer_pool%';
+---------------------------------------+--------------+
| Variable_name                         | Value        |
+---------------------------------------+--------------+
| Innodb_buffer_pool_pages_data         | 5242872      |
| Innodb_buffer_pool_pages_dirty        | 26725        |
| Innodb_buffer_pool_pages_flushed      | 928942474    |
| Innodb_buffer_pool_pages_free         | 3            |
| Innodb_buffer_pool_pages_misc         | 1            |
| Innodb_buffer_pool_pages_total        | 5242876      |
| Innodb_buffer_pool_read_ahead_rnd     | 0            |
| Innodb_buffer_pool_read_ahead         | 12430752     |
| Innodb_buffer_pool_read_ahead_evicted | 53538        |
| Innodb_buffer_pool_read_requests      | 371347304415 |
| Innodb_buffer_pool_reads              | 34573956     |
| Innodb_buffer_pool_wait_free          | 0            |
| Innodb_buffer_pool_write_requests     | 12426911055  |
看起来没有异常;
至此感觉进入了迷茫期了,只是发现了莫名其妙的cpuload高,其它没发现任何异常,诡异啊!
然后继续理清思路,该实例只是一个sharing的一个从库,为啥就这台有问题,其他3台都没有问题。于是开始对比该机器和其他从的机器参数。
发现,numa都是关闭了,磁盘一样,内存一样,等等,cpu貌似不对,有问题的这台机器的cpu核心只有24个,主频只有1.8GHZ,其它是机器是32核心,主频是2.3GHZ;难道问题就这个?cpu太烂?
感觉发现了新大陆一样,等等 不对呀,cpu至少还是24核1.8GHZ,pci-e卡,128G内存的服务器的mysql跑这么简单的sql,QPS只能跑到2k,而且5s都不能出数据,想想都不合理啊。但是到目前都还没发现其它有力证据说明是其他问题,难道需要换服务器,没资源啊。于是就开始浮想翩翩了。不了了之,问题也不能富县,姑且就当是一个灵异事件吧;
然后想着在看看这个sql吧。
mysql> SELECT  so.shipping_no,se.total_deal_price,se.after_discount_price, so.shipping_no  FROM `shipping_order_110` AS `so`  LEFT JOIN `shipping_ext_110` AS `se`  USING (`shipping_no`)  WHERE  (`so`.`order_id` = '810103370')  AND ( `so`.`uid` = '69208878' )     ORDER BY shipping_no;
+-------------+------------------+----------------------+-------------+
| shipping_no | total_deal_price | after_discount_price | shipping_no |
+-------------+------------------+----------------------+-------------+
|  1018668733 |           188.00 |               188.00 |  1018668733 |
+-------------+------------------+----------------------+-------------+
1 row in set (0.01 sec)

mysql> SELECT  so.shipping_no,se.total_deal_price,se.after_discount_price, so.shipping_no  FROM `shipping_order_110` AS `so`  LEFT JOIN `shipping_ext_110` AS `se`  USING (`shipping_no`)  WHERE  (`so`.`order_id` = '810103370')  AND ( `so`.`uid` = '69208878' )     ORDER BY shipping_no;
+-------------+------------------+----------------------+-------------+
| shipping_no | total_deal_price | after_discount_price | shipping_no |
+-------------+------------------+----------------------+-------------+
|  1018668733 |           188.00 |               188.00 |  1018668733 |
+-------------+------------------+----------------------+-------------+
1 row in set (0.01 sec)
连续执行2次,都是0.01秒
去掉order by 子句

mysql> SELECT  so.shipping_no,se.total_deal_price,se.after_discount_price, so.shipping_no  FROM `shipping_order_110` AS `so`  LEFT JOIN `shipping_ext_110` AS `se`  USING (`shipping_no`)  WHERE  (`so`.`order_id` = '810103370')  AND ( `so`.`uid` = '69208878' )   ;
+-------------+------------------+----------------------+-------------+
| shipping_no | total_deal_price | after_discount_price | shipping_no |
+-------------+------------------+----------------------+-------------+
|  1018668733 |           188.00 |               188.00 |  1018668733 |
+-------------+------------------+----------------------+-------------+
1 row in set (0.00 sec)

mysql> SELECT  so.shipping_no,se.total_deal_price,se.after_discount_price, so.shipping_no  FROM `shipping_order_110` AS `so`  LEFT JOIN `shipping_ext_110` AS `se`  USING (`shipping_no`)  WHERE  (`so`.`order_id` = '810103370')  AND ( `so`.`uid` = '69208878' )   ;
+-------------+------------------+----------------------+-------------+
| shipping_no | total_deal_price | after_discount_price | shipping_no |
+-------------+------------------+----------------------+-------------+
|  1018668733 |           188.00 |               188.00 |  1018668733 |
+-------------+------------------+----------------------+-------------+
1 row in set (0.00 sec)
连续执行两次都是0.00秒,sql问题? 虽然不确定是这个问题但是修改后效果确实是有的,于是准备找研发沟通一下是否可以修改一下sql;………………饭点到了,先吃了饭在说吧 这个反正不急(准时吃饭还是有好处呀,不然可能就找不到真实原因了!!)
 
在休的时候,研发有来找我们,说问题有出现了,查不出结果了。
登陆服务器继续排查问题,这次虽然抓住了现场,但是除了之前监控发现的问题,没有任何新的进展!总觉得这个机器不会骗人,哪里来的那么多诡异事件呢,于是继续排查问题,对比一下参数:
问题机器:
mysql>  show variables like '%buff%';
+------------------------------+-------------+
| Variable_name                | Value       |
+------------------------------+-------------+
| bulk_insert_buffer_size      | 8388608     |
| innodb_buffer_pool_instances | 4           |
| innodb_buffer_pool_size      | 85899345920 |
| innodb_change_buffering      | inserts     |
| innodb_log_buffer_size       | 16777216    |
| join_buffer_size             | 67108864    |
| key_buffer_size              | 536870912   |
| myisam_sort_buffer_size      | 8388608     |
| net_buffer_length            | 16384       |
| preload_buffer_size          | 32768       |
| read_buffer_size             | 67108864    |
| read_rnd_buffer_size         | 67108864    |
| sort_buffer_size             | 536870912   |
| sql_buffer_result            | OFF         |
+------------------------------+-------------+
14 rows in set (0.00 sec)
正常机器:
mysql> show variables like '%buff%';
+------------------------------+-------------+
| Variable_name                | Value       |
+------------------------------+-------------+
| bulk_insert_buffer_size      | 8388608     |
| innodb_buffer_pool_instances | 4           |
| innodb_buffer_pool_size      | 85899345920 |
| innodb_change_buffering      | inserts     |
| innodb_log_buffer_size       | 16777216    |
| join_buffer_size             | 2097152     |
| key_buffer_size              | 536870912   |
| myisam_sort_buffer_size      | 8388608     |
| net_buffer_length            | 16384       |
| preload_buffer_size          | 32768       |
| read_buffer_size             | 2097152     |
| read_rnd_buffer_size         | 2097152     |
| sort_buffer_size             | 2097152     |
| sql_buffer_result            | OFF         |
 
read_buffer_size,join_buffer_size,sort_buffer_size,read_rnd_buffer_size
这几个参数的值区别有点大呢,是不是这个问题?老师说这些参数最好不要改大了,不然容易oom,但是没说会影响性能啊,管他呢,先改一波,改小应该没有风险,直接都改小。
重启连接池。问题貌似解决了,至今没有发现问题
然后去官网查了这个几个参数的解释:
 
join_buffer_size:
说了一段这个:Memory allocation time can cause substantial performance drops if the global size is larger than needed by most queries that use it.
sort_buffer_size:
, there are thresholds of 256KB and 2MB where larger values may significantly slow down memory allocation, so you should consider staying below one of those values. Experiment to find the best value for your workload
两个的大意都是说分配内容需要花费很多时间,如果分配或多会严重影响查询效率;
 
经过这次问题:得到两点心得:
       1、找问题一定要有耐性,需要思路清晰,不要轻易相信有灵异事件发生。
       2、遇到所谓的灵异事件,坚持的越久,越可能找到问题所在。
       3、多看官方文档,这个很重要!!

docker 安装 及简单使用

DockerA128_huanggr 发表了文章 • 0 个评论 • 684 次浏览 • 2016-09-27 23:35 • 来自相关话题

安装docker推荐用安装 centos7系统
yum install libdevmapper* -y
yum install docker -y
centos7默认没有ifconfig命令 要用ifconfig : yum -y install net-tools
 
service docker start 启动docker

docker search centos6.8 搜索 官方镜像 
INDEX       NAME                                        DESCRIPTION                                    STARS     OFFICIAL   AUTOMATED
docker.io   docker.io/644597521/centos6.8               centos6.8 from official                        1                    
docker.io   docker.io/tian/centos6.8-lamp-base                                                         1                    
docker.io   docker.io/13652604711/centos6.8-ssh                                                        0                    
docker.io   docker.io/13652604711/centos6.8-ssh-squid                                                  0                    
docker.io   docker.io/13652604711/centos6.8-ssh-ssr                                                    0                    
docker.io   docker.io/13652604711/centos6.8-ssh-vpn                                                    0                    
docker.io   docker.io/algoblu/centos6.8                                                                0                    
docker.io   docker.io/andrewvergel/centos6.8            Develoment Image                               0                    
docker.io   docker.io/confused123/centos6.8-ssh                                                        0                    
docker.io   docker.io/djatlantic/centos6.8                                                             0                    
docker.io   docker.io/finance/centos6.8                                                                0                    
docker.io   docker.io/finance/centos6.8-base            基于centos6.8构建的基本镜像。基...                        0                    
docker.io   docker.io/kxdmmr/centos6.8                                                                 0                    
docker.io   docker.io/lanceyuan/centos6.8                                                              0                    
docker.io   docker.io/leonjones/centos6.8                                                              0                    
docker.io   docker.io/ryus1234/centos6.8                                                               0                    
docker.io   docker.io/scummos/centos6.8-qt5.7           CentOS 6.8 with Qt 5.7, Python 3.5, LLVM 3.8   0                    
docker.io   docker.io/sgclark/centos6.8-qt5.7                                                          0                    
docker.io   docker.io/tian/centos6.8-64bit-base                                                        0     
              
docker pull docker.io/644597521/centos6.8  下载基础镜像
 
查看镜像
docker images 
 
做服务镜像
在系统上建设一个目录,并在目录下建Dockerfile 文件
cat Dockerfile
 
FROM docker.io/644597521/centos6.8
MAINTAINER guirong huang "149951292@qq.com"
RUN yum install -y curl sysstat openssh-server openssh openssh-clients vim libaio iotop tar gcc
RUN mkdir -p /data/redis307/data && mkdir /data/redis307/logs && mkdir /data/redis307/conf
COPY redis-3.0.7.tar.gz /data/ #拷贝包装包到镜像/data目录中
Add redis.conf /data/redis307/conf/ #添加redis配置文件到镜像/data/redis307/conf/目录中
RUN cd /data && tar xvf redis-3.0.7.tar.gz
RUN cd /data/redis-3.0.7 && make MALLOC=libc && make  PREFIX=/usr/local/redis307/ install
RUN groupadd redis && useradd -g redis redis
RUN cd /usr/local/ && chown -R redis.redis redis307 && cd /data && chown -R redis.redis redis307
RUN rm -fr /data/redis-3.0.7.tar.gz
EXPOSE 6379
CMD ["-D"]
创建服务镜像命令
docker build -t="redis:3.0.7" .
创建redis容器
docker run --name redis3.0.7 restart=always -p 6379:6379 -v /data/redis:/data/redis -dit redis:3.0.7 bash  
注:--name指定容器名字,restart=always 让服务在docker重启时容器的服务也是随着重启,-p 容器端口6379映射到宿主机6379端口,-v 批挂载/data/redis目录到容器中/data/redis目录中,-dit指后台运行启动容器
docker ps 查看启动的容器
docker exec -it 容器id bash  进入容器
 
 
MySQL Dockerfile文件
FROM centos:6.7
  
MAINTAINER guirong huang "149951292@qq.com"  
  
RUN yum install -y curl openssh-server openssh openssh-clients vim libaio  tar wget perl-DBD* perl-Time* rsync
  
COPY mysql-5.6.29-linux-glibc2.5-x86_64.tar.gz /root/
#RUN cd /root && curl -s http://cdn.mysql.com/archives/ ... ar.gz -o mysql-5.6.29-linux-glibc2.5-x86_64.tar.gz
Add my.cnf /etc/
Add mysql.sh /root/
RUN /bin/bash /root/mysql.sh && \
rm -f /root/mysql-5.6.29-linux-glibc2.5-x86_64.tar.gz
EXPOSE 3306 
VOLUME  ["/data/mysql"] 
CMD ["-D"] 查看全部
安装docker推荐用安装 centos7系统
yum install libdevmapper* -y
yum install docker -y
centos7默认没有ifconfig命令 要用ifconfig : yum -y install net-tools
 
service docker start 启动docker

docker search centos6.8 搜索 官方镜像 
INDEX       NAME                                        DESCRIPTION                                    STARS     OFFICIAL   AUTOMATED
docker.io   docker.io/644597521/centos6.8               centos6.8 from official                        1                    
docker.io   docker.io/tian/centos6.8-lamp-base                                                         1                    
docker.io   docker.io/13652604711/centos6.8-ssh                                                        0                    
docker.io   docker.io/13652604711/centos6.8-ssh-squid                                                  0                    
docker.io   docker.io/13652604711/centos6.8-ssh-ssr                                                    0                    
docker.io   docker.io/13652604711/centos6.8-ssh-vpn                                                    0                    
docker.io   docker.io/algoblu/centos6.8                                                                0                    
docker.io   docker.io/andrewvergel/centos6.8            Develoment Image                               0                    
docker.io   docker.io/confused123/centos6.8-ssh                                                        0                    
docker.io   docker.io/djatlantic/centos6.8                                                             0                    
docker.io   docker.io/finance/centos6.8                                                                0                    
docker.io   docker.io/finance/centos6.8-base            基于centos6.8构建的基本镜像。基...                        0                    
docker.io   docker.io/kxdmmr/centos6.8                                                                 0                    
docker.io   docker.io/lanceyuan/centos6.8                                                              0                    
docker.io   docker.io/leonjones/centos6.8                                                              0                    
docker.io   docker.io/ryus1234/centos6.8                                                               0                    
docker.io   docker.io/scummos/centos6.8-qt5.7           CentOS 6.8 with Qt 5.7, Python 3.5, LLVM 3.8   0                    
docker.io   docker.io/sgclark/centos6.8-qt5.7                                                          0                    
docker.io   docker.io/tian/centos6.8-64bit-base                                                        0     
              
docker pull docker.io/644597521/centos6.8  下载基础镜像
 
查看镜像
docker images 
 
做服务镜像
在系统上建设一个目录,并在目录下建Dockerfile 文件
cat Dockerfile
 
FROM docker.io/644597521/centos6.8
MAINTAINER guirong huang "149951292@qq.com"
RUN yum install -y curl sysstat openssh-server openssh openssh-clients vim libaio iotop tar gcc
RUN mkdir -p /data/redis307/data && mkdir /data/redis307/logs && mkdir /data/redis307/conf
COPY redis-3.0.7.tar.gz /data/ #拷贝包装包到镜像/data目录中
Add redis.conf /data/redis307/conf/ #添加redis配置文件到镜像/data/redis307/conf/目录中
RUN cd /data && tar xvf redis-3.0.7.tar.gz
RUN cd /data/redis-3.0.7 && make MALLOC=libc && make  PREFIX=/usr/local/redis307/ install
RUN groupadd redis && useradd -g redis redis
RUN cd /usr/local/ && chown -R redis.redis redis307 && cd /data && chown -R redis.redis redis307
RUN rm -fr /data/redis-3.0.7.tar.gz
EXPOSE 6379
CMD ["-D"]
创建服务镜像命令
docker build -t="redis:3.0.7" .
创建redis容器
docker run --name redis3.0.7 restart=always -p 6379:6379 -v /data/redis:/data/redis -dit redis:3.0.7 bash  
注:--name指定容器名字,restart=always 让服务在docker重启时容器的服务也是随着重启,-p 容器端口6379映射到宿主机6379端口,-v 批挂载/data/redis目录到容器中/data/redis目录中,-dit指后台运行启动容器
docker ps 查看启动的容器
docker exec -it 容器id bash  进入容器
 
 
MySQL Dockerfile文件
FROM centos:6.7
  
MAINTAINER guirong huang "149951292@qq.com"  
  
RUN yum install -y curl openssh-server openssh openssh-clients vim libaio  tar wget perl-DBD* perl-Time* rsync
  
COPY mysql-5.6.29-linux-glibc2.5-x86_64.tar.gz /root/
#RUN cd /root && curl -s http://cdn.mysql.com/archives/ ... ar.gz -o mysql-5.6.29-linux-glibc2.5-x86_64.tar.gz
Add my.cnf /etc/
Add mysql.sh /root/
RUN /bin/bash /root/mysql.sh && \
rm -f /root/mysql-5.6.29-linux-glibc2.5-x86_64.tar.gz
EXPOSE 3306 
VOLUME  ["/data/mysql"] 
CMD ["-D"]

520 Redis中国用户组成立啦,约吗?

activityzhangdh 发表了文章 • 0 个评论 • 439 次浏览 • 2016-05-21 00:45 • 来自相关话题

 Hello 大家好,

    很高兴告诉大家,Redis中国用户组经过一个多月的紧张筹备,终于在今天这个美好的日子和大家见面了!希望有更多的Redis爱好者加入到我们当中,共同致力为Redis技术的推广和应用,贡献绵薄之力。

    首先,我们非常感谢Antirez等大神为我们开发出了这么好用的工具,也非常感谢Rediser们为Redis版本的持续更新、功能改善和性能提高付出的努力,以及为建立健全的文档而付出的辛勤努力。我们注意到随着互联网技术的日益普及,Redis在国内被普遍应用,越来越多的人开始了解Redis,越来越多的企业开始应用Redis。但是对于Redis Cluster这种比较新的技术,在生产环境中还是使用较少的;在Redis的代码贡献上,还是不容乐观的。所以我们任重道远…

    Redis中国用户组,是由国内互联网公司的Redis一线工程师联合发起的非营利性技术组织。Redis中国用户组的成立得到了核心发起人李强和许瑞的大力支持,无私地将他们从2011年运营至今的redis.cn贡献出来,作为Redis中国用户组官网。不仅如此,我们还组建了Redis中国用户组QQ群521503946和微信群,提供给大家技术交流。并且Redis中国用户组也有了自己的官方微博(蓝V哦~)@Redis2016。除此之外,我们还第一时间组织力量给Redis官方发出认证函,以期得到官方的认可和支持(已经收到官方认可和支持的答复)。
    
    Redis中国用户组,在国内,作为Redis的一个核心组织,在今后的岁月里主要会从以下几个方面为持续推广普及Redis做出努力:
       1.延续redis.cn的光荣传统和使命,坚持不懈的继续翻译Redis官网和相关技术文章,期刊,新闻等,相信很多初学者都是从这里成长起来的
       2.不定期组织线上分享
       3.不定期组织线下交流活动,技术沙龙或联合举办技术大会
       4.逐步开始运营Redis中国用户组官方微信订阅号,推送经典技术文章,博客等
       5.邀请Redis技术大牛,讨论交流,并在Redis的代码贡献上持续发力
       6.有余力了,会以Redis中国用户组的名义出系列书籍

   写在最后,我们真诚地希望更多的Redis用户或爱好者能加入到我们的行列中,一起努力,创造Redis美好的明天。

   最后特别感谢Redis中国用户组核心成员(发起人):李强(创业)、张冬洪(微博)、王义成(阿里云)、许瑞(唯品会)、强昌金(去哪儿)、曹增涛(微博)、刘东辉(微博)、卓汝林(小米)、孙赫(今日头条)。
 
                                                                                                                                           Redis中国用户组
                                                                                                                                               2016-05-20 查看全部
redis_520_1(0).jpg

 Hello 大家好,

    很高兴告诉大家,Redis中国用户组经过一个多月的紧张筹备,终于在今天这个美好的日子和大家见面了!希望有更多的Redis爱好者加入到我们当中,共同致力为Redis技术的推广和应用,贡献绵薄之力。

    首先,我们非常感谢Antirez等大神为我们开发出了这么好用的工具,也非常感谢Rediser们为Redis版本的持续更新、功能改善和性能提高付出的努力,以及为建立健全的文档而付出的辛勤努力。我们注意到随着互联网技术的日益普及,Redis在国内被普遍应用,越来越多的人开始了解Redis,越来越多的企业开始应用Redis。但是对于Redis Cluster这种比较新的技术,在生产环境中还是使用较少的;在Redis的代码贡献上,还是不容乐观的。所以我们任重道远…

    Redis中国用户组,是由国内互联网公司的Redis一线工程师联合发起的非营利性技术组织。Redis中国用户组的成立得到了核心发起人李强和许瑞的大力支持,无私地将他们从2011年运营至今的redis.cn贡献出来,作为Redis中国用户组官网。不仅如此,我们还组建了Redis中国用户组QQ群521503946和微信群,提供给大家技术交流。并且Redis中国用户组也有了自己的官方微博(蓝V哦~)@Redis2016。除此之外,我们还第一时间组织力量给Redis官方发出认证函,以期得到官方的认可和支持(已经收到官方认可和支持的答复)。
    
    Redis中国用户组,在国内,作为Redis的一个核心组织,在今后的岁月里主要会从以下几个方面为持续推广普及Redis做出努力:
       1.延续redis.cn的光荣传统和使命,坚持不懈的继续翻译Redis官网和相关技术文章,期刊,新闻等,相信很多初学者都是从这里成长起来的
       2.不定期组织线上分享
       3.不定期组织线下交流活动,技术沙龙或联合举办技术大会
       4.逐步开始运营Redis中国用户组官方微信订阅号,推送经典技术文章,博客等
       5.邀请Redis技术大牛,讨论交流,并在Redis的代码贡献上持续发力
       6.有余力了,会以Redis中国用户组的名义出系列书籍

   写在最后,我们真诚地希望更多的Redis用户或爱好者能加入到我们的行列中,一起努力,创造Redis美好的明天。

   最后特别感谢Redis中国用户组核心成员(发起人):李强(创业)、张冬洪(微博)、王义成(阿里云)、许瑞(唯品会)、强昌金(去哪儿)、曹增涛(微博)、刘东辉(微博)、卓汝林(小米)、孙赫(今日头条)。
 
                                                                                                                                           Redis中国用户组
                                                                                                                                               2016-05-20

python 实现 mysql start | stop | restar | status 便捷管理命令

MySQLglon 发表了文章 • 1 个评论 • 742 次浏览 • 2016-05-16 17:27 • 来自相关话题

脚本还比较傻瓜,要求 MySQL 规范化部署。
basedir = /usr/local/mysql
datadir = /data/mysql/appname/data
conf_path: /data/mysql/appname/my%port.cnf
socket:/tmp/mysql%port.cnf
 
使用:
./mysqlCtrl {start|stop|restart|enter}
./mysqlCtrl -i mysql3316 -h 192.168.1.1 -u glon -p xxx -P3306 -o {start|stop|restart|enter}
 
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# Author:glon
# date:2016-5-16 17:47:10

import sys
import os
import time
import getopt
import subprocess

app='mysql3316'
dbhost='localhost'
dbport=3316
dbuser='root'
dbpassword='123456'
operations = ['start','stop','restart','status','enter']

def usage():
print '''usage:
-i: app name.
-h: database host.
-P: databaee port
-u: database user
-p: database password
-o: database operation.{start|stop|restart|status|enter}

eg:
1) python mysqlCtrl.py -i mysql3316 -h 192.168.1.1 -u glon -p xxx -P3306 -o start
2) python mysqlCtrl.py start'''

def execCmd(cmd):
res = subprocess.Popen(cmd,stdout = subprocess.PIPE,shell = True)
return res.stdout.read()

def chkMySQL():
chk_mysql_process_cmd="ps aux | grep mysqld | grep %s | grep -v grep | wc -l" % dbport
chk_mysql_port_cmd ="netstat -tunlp | grep \":%s\" | wc -l" % dbport

mysql_process_num = execCmd(chk_mysql_process_cmd)
mysql_port_num = execCmd(chk_mysql_process_cmd)

return int(mysql_process_num and mysql_port_num)

def getOpts():
db_cfg = {}
opts, args = getopt.getopt(sys.argv[1:], 'i:h:P:u:p:o:', ['help'])
ops = dict(opts)
db_cfg['instance'] = ops['-i'] if ops.has_key('-i') else app
db_cfg['host'] = ops['-h'] if ops.has_key('-h') else dbhost
db_cfg['user'] = ops['-u'] if ops.has_key('-u') else dbuser
db_cfg['pwd'] = ops['-p'] if ops.has_key('-p') else dbpassword
db_cfg['port'] = ops['-P'] if ops.has_key('-P') else dbport

db_cfg['opt'] = None
if len(args) > 0:
for arg in args:
if operations.count(arg):
db_cfg['opt'] = arg
break

if ops.has_key('-o'):
db_cfg['opt'] = ops['-o']

return db_cfg

def startMySQL(dbconf):
if not chkMySQL():
cmd = "sudo /usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/%s/my%s.cnf &" % (dbconf['instance'],dbconf['port'])
subprocess.Popen(cmd,stderr = subprocess.PIPE,shell=True)
print ">>> Start MySQL \033[32m [ OK ] \033[0m" if chkMySQL() > 0 else '>>> Start MySQL \033[31m [ FAIL ] \033[0m'
else:
print ">>> MySQL is already \033[32m [ EXIST ] \033[0m"

def stopMySQL(dbconf):
if not chkMySQL():
print ">>> Stop MySQL \033[32m [ OK ] \033[0m"
else:
cmd = "sudo /usr/local/mysql/bin/mysqladmin -S /tmp/mysql%s.sock shutdown -u%s -p%s" % (dbconf['port'],dbconf['user'],dbconf['pwd'])
subprocess.Popen(cmd,stderr = subprocess.PIPE,shell=True)
time.sleep(5)
print ">>> Stop MySQL \033[32m [ OK ] \033[0m" if chkMySQL() == 0 else '>>> Stop MySQL \033[31m [ FAIL ] \033[0m'

def enterMySQL(dbconf):
if chkMySQL():
cmd = "/usr/local/mysql/bin/mysql -S /tmp/mysql%s.sock -u%s -p%s" % (dbconf['port'],dbconf['user'],dbconf['pwd'])
os.system(cmd)
else:
print ">>> MySQL is \033[31m [ NOT EXIST ] \033[0m"

if __name__== "__main__":
try:
db_conf = getOpts()
if db_conf['opt'] == 'start':
print '>>> starting MySQL on Port %s ...' % db_conf['port']
startMySQL(db_conf)
elif db_conf['opt'] == 'stop':
print '>>> stopping MySQL on Port %s ...' % db_conf['port']
stopMySQL(db_conf)
elif db_conf['opt'] == 'restart':
print '>>> restarting MySQL on Port %s...' % db_conf['port']
stopMySQL(db_conf)
startMySQL(db_conf)
elif db_conf['opt'] == 'status':
print '>>> MySQL is \033[32m [ RUNNING ] \033[0m on Port %s' % db_conf['port'] if chkMySQL() > 0 else '>>> MySQL is \033[31m [ NOT ON SERVICE ] \033[0m on Port %s' % db_conf['port']
elif db_conf['opt'] == 'enter':
enterMySQL(db_conf)
else:
print '>>> Nothing to do, plz input the right operation ...'
usage()


except getopt.GetoptError, err:
print str(err)
usage()
sys.exit(2) 查看全部
脚本还比较傻瓜,要求 MySQL 规范化部署。
basedir = /usr/local/mysql
datadir = /data/mysql/appname/data
conf_path: /data/mysql/appname/my%port.cnf
socket:/tmp/mysql%port.cnf
 
使用:
./mysqlCtrl {start|stop|restart|enter}
./mysqlCtrl -i mysql3316 -h 192.168.1.1 -u glon -p xxx -P3306 -o {start|stop|restart|enter}
 
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# Author:glon
# date:2016-5-16 17:47:10

import sys
import os
import time
import getopt
import subprocess

app='mysql3316'
dbhost='localhost'
dbport=3316
dbuser='root'
dbpassword='123456'
operations = ['start','stop','restart','status','enter']

def usage():
print '''usage:
-i: app name.
-h: database host.
-P: databaee port
-u: database user
-p: database password
-o: database operation.{start|stop|restart|status|enter}

eg:
1) python mysqlCtrl.py -i mysql3316 -h 192.168.1.1 -u glon -p xxx -P3306 -o start
2) python mysqlCtrl.py start'''

def execCmd(cmd):
res = subprocess.Popen(cmd,stdout = subprocess.PIPE,shell = True)
return res.stdout.read()

def chkMySQL():
chk_mysql_process_cmd="ps aux | grep mysqld | grep %s | grep -v grep | wc -l" % dbport
chk_mysql_port_cmd ="netstat -tunlp | grep \":%s\" | wc -l" % dbport

mysql_process_num = execCmd(chk_mysql_process_cmd)
mysql_port_num = execCmd(chk_mysql_process_cmd)

return int(mysql_process_num and mysql_port_num)

def getOpts():
db_cfg = {}
opts, args = getopt.getopt(sys.argv[1:], 'i:h:P:u:p:o:', ['help'])
ops = dict(opts)
db_cfg['instance'] = ops['-i'] if ops.has_key('-i') else app
db_cfg['host'] = ops['-h'] if ops.has_key('-h') else dbhost
db_cfg['user'] = ops['-u'] if ops.has_key('-u') else dbuser
db_cfg['pwd'] = ops['-p'] if ops.has_key('-p') else dbpassword
db_cfg['port'] = ops['-P'] if ops.has_key('-P') else dbport

db_cfg['opt'] = None
if len(args) > 0:
for arg in args:
if operations.count(arg):
db_cfg['opt'] = arg
break

if ops.has_key('-o'):
db_cfg['opt'] = ops['-o']

return db_cfg

def startMySQL(dbconf):
if not chkMySQL():
cmd = "sudo /usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/%s/my%s.cnf &" % (dbconf['instance'],dbconf['port'])
subprocess.Popen(cmd,stderr = subprocess.PIPE,shell=True)
print ">>> Start MySQL \033[32m [ OK ] \033[0m" if chkMySQL() > 0 else '>>> Start MySQL \033[31m [ FAIL ] \033[0m'
else:
print ">>> MySQL is already \033[32m [ EXIST ] \033[0m"

def stopMySQL(dbconf):
if not chkMySQL():
print ">>> Stop MySQL \033[32m [ OK ] \033[0m"
else:
cmd = "sudo /usr/local/mysql/bin/mysqladmin -S /tmp/mysql%s.sock shutdown -u%s -p%s" % (dbconf['port'],dbconf['user'],dbconf['pwd'])
subprocess.Popen(cmd,stderr = subprocess.PIPE,shell=True)
time.sleep(5)
print ">>> Stop MySQL \033[32m [ OK ] \033[0m" if chkMySQL() == 0 else '>>> Stop MySQL \033[31m [ FAIL ] \033[0m'

def enterMySQL(dbconf):
if chkMySQL():
cmd = "/usr/local/mysql/bin/mysql -S /tmp/mysql%s.sock -u%s -p%s" % (dbconf['port'],dbconf['user'],dbconf['pwd'])
os.system(cmd)
else:
print ">>> MySQL is \033[31m [ NOT EXIST ] \033[0m"

if __name__== "__main__":
try:
db_conf = getOpts()
if db_conf['opt'] == 'start':
print '>>> starting MySQL on Port %s ...' % db_conf['port']
startMySQL(db_conf)
elif db_conf['opt'] == 'stop':
print '>>> stopping MySQL on Port %s ...' % db_conf['port']
stopMySQL(db_conf)
elif db_conf['opt'] == 'restart':
print '>>> restarting MySQL on Port %s...' % db_conf['port']
stopMySQL(db_conf)
startMySQL(db_conf)
elif db_conf['opt'] == 'status':
print '>>> MySQL is \033[32m [ RUNNING ] \033[0m on Port %s' % db_conf['port'] if chkMySQL() > 0 else '>>> MySQL is \033[31m [ NOT ON SERVICE ] \033[0m on Port %s' % db_conf['port']
elif db_conf['opt'] == 'enter':
enterMySQL(db_conf)
else:
print '>>> Nothing to do, plz input the right operation ...'
usage()


except getopt.GetoptError, err:
print str(err)
usage()
sys.exit(2)

KeepAlived高可用切换脚本修改--基于 checkMySQL.sh

MySQLglon 发表了文章 • 2 个评论 • 941 次浏览 • 2016-05-10 18:24 • 来自相关话题

最近需要分离一个业务到 MySQL 上,使用 GTID 模型一主一从的复制结构,并使用 KeepAlived 做为高可用切换。
吴总说过,如果在切换的时候从库还没同步完成,会丢失数据,而网络抖动时切换,有可能导致脑裂。
基于这个,对原本简单的 mysql connect ping 做了一个扩展。
脚本中的 monitor 用户,拥有 replication slave 的权限。 
#!/usr/bin/python
#coding: utf-8
# author:hejinlong@yaochufa.com
# 2016-5-15 17:42:15

import sys
import os
import getopt
import MySQLdb
import logging
import subprocess
import datetime
import common as cm


dbhost='127.0.0.1'
dbport=3316
dbuser='monitor'
dbpassword='m0n1tor'
vip='192.168.1.123'
mail_to = '562071793@qq.com'
ka_conf = '/etc/keepalived/keepalived.conf'
app_env = 'online'

def checkMySQL():
global dbhost
global dbport
global dbuser
global dbpassword
global mail_to

shortargs='h:P:'
opts, args=getopt.getopt(sys.argv[1:],shortargs)
for opt, value in opts:
if opt=='-h':
dbhost=value
elif opt=='-P':
dbport=value

db = instanceMySQL(dbhost, dbport, dbuser, dbpassword)
util = Org(vip,mail_to,ka_conf,app_env)

# check mysql
if ( db.connect() != 0 ):
return 1
db.disconnect()

# check network for "Split Brain"
net_status = util.ping_vip()

is_vip = util.check_vip()
if is_vip == 1:#从库,则检查复制状态
repl_status = db.is_slave_sql_thread_done()

# 网络抖动时不切换
if net_status == 1:
return 0

# slave, repl delay
if (is_vip == 1) and (repl_status == 1):
return 1

return 0


class Org:
def __init__(self, vip=None, mail_to=None, conf=None, app_env=None):
self.vip=vip
self.mail_to=mail_to
self.conf=conf
self.app_env = app_env

def execCmd(self,cmd):
res = subprocess.Popen(cmd,stdout = subprocess.PIPE,shell = True)
return res.stdout.read()

def getNetInterface(self):
with open(self.conf, 'r') as f:
for line in f:
if line.find('interface') != -1:
return line.strip().split()[1]

#ping vip
def ping_vip(self):
logging.info('---------------- check network ----------------')
cmd = 'ping ' + self.vip + ' -c 4'
ping_res = os.system(cmd)

logging.info('>>> command: %s :', cmd)
logging.info('>>> %s', ping_res)

# ping_res: greater than 0 network is bad, 0 network is good
if ping_res > 0:
net_interface = self.getNetInterface()
cmd = "ifconfig {0}".format(net_interface) + " | grep 'inet addr:' | awk '{print $2}' | awk -F':' '{print $2}'"
local_ip = self.execCmd(cmd)
logging.info('>>> command:%s', cmd)
logging.info('>>> %s', local_ip)

logging.info('>>> sendmail when network is bad')
subject = '[ {0} ] network is bad!'.format(local_ip.strip())
msg = self.app_env + ' {0} network is bad!'.format(local_ip.strip())
cm.send_alert_mail(subject,msg,mail_to)
return 1
return 0

# is_vip
def check_vip(self):
logging.info('---------------- check vip ----------------')
cmd = "ip addr show | grep %s | wc -l" % self.vip
chk_res = self.execCmd(cmd)

logging.info('>>> command: %s :', cmd)
logging.info('>>> %s', chk_res)

# chk_res: greater than 0 is vip, 0 is not vip
if int(chk_res) == 0:
return 1
return 0


class instanceMySQL:
conn = None
def __init__(self, host=None,port=None, user=None, passwd=None):
self.dbhost= host
self.dbport = int(port)
self.dbuser = user
self.dbpassword = passwd

def is_slave_sql_thread_done(self):
logging.info('---------------- check repl is done ----------------')

self.connect()
sql="show slave status"
cursor = self.conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)
cursor.execute(sql)
result = cursor.fetchall()

logging.info('>>> command: show slave status result')
logging.info('>>> %s', result)

if len(result) == 0:
return 0

row = result[0]
#if( row['Slave_IO_Running'] != 'Yes'):
# return 1
#if( row['Slave_SQL_Running'] != 'Yes'):
# return 1

logging.info('>>> Slave_IO_Running: %s', row['Slave_IO_Running'])
logging.info('>>> Slave_SQL_Running: %s', row['Slave_SQL_Running'])
logging.info('>>> Master_Log_File: %s', row['Master_Log_File'])
logging.info('>>> Relay_Master_Log_File: %s', row['Relay_Master_Log_File'])
logging.info('>>> Read_Master_Log_Pos: %s', row['Read_Master_Log_Pos'])
logging.info('>>> Exec_Master_Log_Pos: %s', row['Exec_Master_Log_Pos'])

if ( row['Master_Log_File'] == row['Relay_Master_Log_File']) and (row['Read_Master_Log_Pos'] == row['Exec_Master_Log_Pos'] ):
print 'repl done'
logging.info('>>> repl status: done')
cursor.close()
self.disconnect()
return 0
cursor.close()
self.disconnect()
logging.info('>>> repl status: delay')
return 1


def connect(self):
logging.info('---------------- connect mysql ----------------')
try:
self.conn=MySQLdb.connect(host="%s"%self.dbhost, port=self.dbport,user="%s"%dbuser, passwd="%s"%self.dbpassword)

logging.info('command: show master status')
sql="show master status"
cursor = self.conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)
cursor.execute(sql)
result = cursor.fetchall()
logging.info('>>> %s', result)

logging.info('>>> connect: OK')
except Exception, e:
#print " Error"
print e
return 1
return 0

def disconnect(self):
logging.info('---------------- disconnect mysql ----------------')
if (self.conn):
self.conn.close()
self.conn = None
logging.info('>>> disconnect: OK')



if __name__== "__main__":
LOG_PATH = 'chk_logs'
EXPIRE_LOGS_DAYS = 3

log_path = os.path.join(sys.path[0],LOG_PATH)
current_date = datetime.datetime.now().strftime('%Y%m%d')
expired_date = datetime.date.today() - datetime.timedelta(days=EXPIRE_LOGS_DAYS)

next_log = 'chk_mysql.' + current_date
expired_log = 'chk_mysql.' + expired_date.strftime('%Y%m%d')
log_file = os.path.join(log_path,next_log)

if not os.path.exists(log_path):
os.mkdir(log_path)

logging.basicConfig(level=logging.DEBUG,
#format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
format='%(asctime)s %(levelname)s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
filename=log_file,
filemode='a')

logging.info(' ')
logging.info(' ')
logging.info(' ')
logging.info('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ init chk logs start ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
logging.info('>>> log_path: %s', log_path)
logging.info('>>> next_log: %s', next_log)
logging.info('>>> expired_log: %s', expired_log)

logs = []
cmd = "dir " + log_path
for i in os.popen(cmd).readlines():
logs.extend( i.split())

logging.info('---------------- logs exists ----------------')
logging.info('>>> %s', logs)

if len(logs) > EXPIRE_LOGS_DAYS:
for i in logs:
if i <= expired_log:
rm_log = os.path.join(log_path,i)
logging.info('>>> removeing expired log: %s',rm_log)
os.remove(rm_log)

logging.info('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ init chk logs end ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
logging.info('###################################### begin checking ######################################')

st=checkMySQL()

if st == 0:
logging.info('Check Code is: %s, means good.', st)
else:
logging.info('Check Code is: %s, means bad.', st)

logging.info('###################################### end checking ######################################')
sys.exit(st)

对 python 不熟,写得不好,请多见谅。
这个脚本还没有加入一主多从的时候,选举新主的判断,大家可以尝试一下。
 
这个脚本有个小坑,永祥踩了,O(∩_∩)O哈哈~
要求配置文件的命名是带端口的,如 my3306.cnf,否则在判断 mysql 进程是否存在的时候会找不到,因为找到 mysqld 进程后,再次筛选端口号的时候就找不着了。
由此可以看出,这个脚本对规范部署的要求高,而且对多实例很管用~~ 查看全部
最近需要分离一个业务到 MySQL 上,使用 GTID 模型一主一从的复制结构,并使用 KeepAlived 做为高可用切换。
吴总说过,如果在切换的时候从库还没同步完成,会丢失数据,而网络抖动时切换,有可能导致脑裂。
基于这个,对原本简单的 mysql connect ping 做了一个扩展。
脚本中的 monitor 用户,拥有 replication slave 的权限。 
#!/usr/bin/python
#coding: utf-8
# author:hejinlong@yaochufa.com
# 2016-5-15 17:42:15

import sys
import os
import getopt
import MySQLdb
import logging
import subprocess
import datetime
import common as cm


dbhost='127.0.0.1'
dbport=3316
dbuser='monitor'
dbpassword='m0n1tor'
vip='192.168.1.123'
mail_to = '562071793@qq.com'
ka_conf = '/etc/keepalived/keepalived.conf'
app_env = 'online'

def checkMySQL():
global dbhost
global dbport
global dbuser
global dbpassword
global mail_to

shortargs='h:P:'
opts, args=getopt.getopt(sys.argv[1:],shortargs)
for opt, value in opts:
if opt=='-h':
dbhost=value
elif opt=='-P':
dbport=value

db = instanceMySQL(dbhost, dbport, dbuser, dbpassword)
util = Org(vip,mail_to,ka_conf,app_env)

# check mysql
if ( db.connect() != 0 ):
return 1
db.disconnect()

# check network for "Split Brain"
net_status = util.ping_vip()

is_vip = util.check_vip()
if is_vip == 1:#从库,则检查复制状态
repl_status = db.is_slave_sql_thread_done()

# 网络抖动时不切换
if net_status == 1:
return 0

# slave, repl delay
if (is_vip == 1) and (repl_status == 1):
return 1

return 0


class Org:
def __init__(self, vip=None, mail_to=None, conf=None, app_env=None):
self.vip=vip
self.mail_to=mail_to
self.conf=conf
self.app_env = app_env

def execCmd(self,cmd):
res = subprocess.Popen(cmd,stdout = subprocess.PIPE,shell = True)
return res.stdout.read()

def getNetInterface(self):
with open(self.conf, 'r') as f:
for line in f:
if line.find('interface') != -1:
return line.strip().split()[1]

#ping vip
def ping_vip(self):
logging.info('---------------- check network ----------------')
cmd = 'ping ' + self.vip + ' -c 4'
ping_res = os.system(cmd)

logging.info('>>> command: %s :', cmd)
logging.info('>>> %s', ping_res)

# ping_res: greater than 0 network is bad, 0 network is good
if ping_res > 0:
net_interface = self.getNetInterface()
cmd = "ifconfig {0}".format(net_interface) + " | grep 'inet addr:' | awk '{print $2}' | awk -F':' '{print $2}'"
local_ip = self.execCmd(cmd)
logging.info('>>> command:%s', cmd)
logging.info('>>> %s', local_ip)

logging.info('>>> sendmail when network is bad')
subject = '[ {0} ] network is bad!'.format(local_ip.strip())
msg = self.app_env + ' {0} network is bad!'.format(local_ip.strip())
cm.send_alert_mail(subject,msg,mail_to)
return 1
return 0

# is_vip
def check_vip(self):
logging.info('---------------- check vip ----------------')
cmd = "ip addr show | grep %s | wc -l" % self.vip
chk_res = self.execCmd(cmd)

logging.info('>>> command: %s :', cmd)
logging.info('>>> %s', chk_res)

# chk_res: greater than 0 is vip, 0 is not vip
if int(chk_res) == 0:
return 1
return 0


class instanceMySQL:
conn = None
def __init__(self, host=None,port=None, user=None, passwd=None):
self.dbhost= host
self.dbport = int(port)
self.dbuser = user
self.dbpassword = passwd

def is_slave_sql_thread_done(self):
logging.info('---------------- check repl is done ----------------')

self.connect()
sql="show slave status"
cursor = self.conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)
cursor.execute(sql)
result = cursor.fetchall()

logging.info('>>> command: show slave status result')
logging.info('>>> %s', result)

if len(result) == 0:
return 0

row = result[0]
#if( row['Slave_IO_Running'] != 'Yes'):
# return 1
#if( row['Slave_SQL_Running'] != 'Yes'):
# return 1

logging.info('>>> Slave_IO_Running: %s', row['Slave_IO_Running'])
logging.info('>>> Slave_SQL_Running: %s', row['Slave_SQL_Running'])
logging.info('>>> Master_Log_File: %s', row['Master_Log_File'])
logging.info('>>> Relay_Master_Log_File: %s', row['Relay_Master_Log_File'])
logging.info('>>> Read_Master_Log_Pos: %s', row['Read_Master_Log_Pos'])
logging.info('>>> Exec_Master_Log_Pos: %s', row['Exec_Master_Log_Pos'])

if ( row['Master_Log_File'] == row['Relay_Master_Log_File']) and (row['Read_Master_Log_Pos'] == row['Exec_Master_Log_Pos'] ):
print 'repl done'
logging.info('>>> repl status: done')
cursor.close()
self.disconnect()
return 0
cursor.close()
self.disconnect()
logging.info('>>> repl status: delay')
return 1


def connect(self):
logging.info('---------------- connect mysql ----------------')
try:
self.conn=MySQLdb.connect(host="%s"%self.dbhost, port=self.dbport,user="%s"%dbuser, passwd="%s"%self.dbpassword)

logging.info('command: show master status')
sql="show master status"
cursor = self.conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)
cursor.execute(sql)
result = cursor.fetchall()
logging.info('>>> %s', result)

logging.info('>>> connect: OK')
except Exception, e:
#print " Error"
print e
return 1
return 0

def disconnect(self):
logging.info('---------------- disconnect mysql ----------------')
if (self.conn):
self.conn.close()
self.conn = None
logging.info('>>> disconnect: OK')



if __name__== "__main__":
LOG_PATH = 'chk_logs'
EXPIRE_LOGS_DAYS = 3

log_path = os.path.join(sys.path[0],LOG_PATH)
current_date = datetime.datetime.now().strftime('%Y%m%d')
expired_date = datetime.date.today() - datetime.timedelta(days=EXPIRE_LOGS_DAYS)

next_log = 'chk_mysql.' + current_date
expired_log = 'chk_mysql.' + expired_date.strftime('%Y%m%d')
log_file = os.path.join(log_path,next_log)

if not os.path.exists(log_path):
os.mkdir(log_path)

logging.basicConfig(level=logging.DEBUG,
#format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
format='%(asctime)s %(levelname)s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
filename=log_file,
filemode='a')

logging.info(' ')
logging.info(' ')
logging.info(' ')
logging.info('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ init chk logs start ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
logging.info('>>> log_path: %s', log_path)
logging.info('>>> next_log: %s', next_log)
logging.info('>>> expired_log: %s', expired_log)

logs = []
cmd = "dir " + log_path
for i in os.popen(cmd).readlines():
logs.extend( i.split())

logging.info('---------------- logs exists ----------------')
logging.info('>>> %s', logs)

if len(logs) > EXPIRE_LOGS_DAYS:
for i in logs:
if i <= expired_log:
rm_log = os.path.join(log_path,i)
logging.info('>>> removeing expired log: %s',rm_log)
os.remove(rm_log)

logging.info('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ init chk logs end ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
logging.info('###################################### begin checking ######################################')

st=checkMySQL()

if st == 0:
logging.info('Check Code is: %s, means good.', st)
else:
logging.info('Check Code is: %s, means bad.', st)

logging.info('###################################### end checking ######################################')
sys.exit(st)

对 python 不熟,写得不好,请多见谅。
这个脚本还没有加入一主多从的时候,选举新主的判断,大家可以尝试一下。
 
这个脚本有个小坑,永祥踩了,O(∩_∩)O哈哈~
要求配置文件的命名是带端口的,如 my3306.cnf,否则在判断 mysql 进程是否存在的时候会找不到,因为找到 mysqld 进程后,再次筛选端口号的时候就找不着了。
由此可以看出,这个脚本对规范部署的要求高,而且对多实例很管用~~

Linux后台运行命令的三种方法

Linuxglon 发表了文章 • 0 个评论 • 608 次浏览 • 2016-04-15 23:53 • 来自相关话题

后台运行命令有下面3中方法:

1、在命令后面加 &
    有可能会在关闭当前终端的时候中断退出
 
2、使用 nohup
    如:nohup sleep 100 &
    会在当前目录生成一个 nohup.out 文件,会收集这个命令在执行过程中产生的日志
    在 crt 这些工具的某些版本也会出现在关闭当前终端的时候中断退出(参考大师兄的分享),这时候可以把命令写到脚本中,然后后台执行脚本。
    使用 jobs 命令可以看到这些后台任务
 
3、使用 screen 工具
    1)安装:yum install -y screen
    2)使用:
    step1:打开 screen 窗口:
        直接打开: screen 
        在打开 screen 窗口的时候,可以给这个窗口命名:screen -S 窗口名
    step2:在 screen 窗口执行命令
    step3:退出 screen 窗口
       使用 ctrl+a+d 暂时退出 screen 窗口,命令会在后台继续运行
       使用 ctrl + d 或者输入 exit 命令来真正退出当前的 screen 窗口
    step4:查看使用 screen 运行的后台进程列表
       screen -ls 
       或者使用 ps 工具:
       ps aux | grep -E '命令1 | 命令2 | ...' 
       # 可以查看多个在 screen 虚拟出来的终端中跑的后台进程
       # 但是使用 ps aux | grep screen 是看不到的 screen 进程的, screen 并不是进程
    step5:进入运行某个命令的 screen 窗口
       screen -r 进程ID号
       或者 
       screen -r 窗口名
    

    
  查看全部
后台运行命令有下面3中方法:

1、在命令后面加 &
    有可能会在关闭当前终端的时候中断退出
 
2、使用 nohup
    如:nohup sleep 100 &
    会在当前目录生成一个 nohup.out 文件,会收集这个命令在执行过程中产生的日志
    在 crt 这些工具的某些版本也会出现在关闭当前终端的时候中断退出(参考大师兄的分享),这时候可以把命令写到脚本中,然后后台执行脚本。
    使用 jobs 命令可以看到这些后台任务
 
3、使用 screen 工具
    1)安装:yum install -y screen
    2)使用:
    step1:打开 screen 窗口:
        直接打开: screen 
        在打开 screen 窗口的时候,可以给这个窗口命名:screen -S 窗口名
    step2:在 screen 窗口执行命令
    step3:退出 screen 窗口
       使用 ctrl+a+d 暂时退出 screen 窗口,命令会在后台继续运行
       使用 ctrl + d 或者输入 exit 命令来真正退出当前的 screen 窗口
    step4:查看使用 screen 运行的后台进程列表
       screen -ls 
       或者使用 ps 工具:
       ps aux | grep -E '命令1 | 命令2 | ...' 
       # 可以查看多个在 screen 虚拟出来的终端中跑的后台进程
       # 但是使用 ps aux | grep screen 是看不到的 screen 进程的, screen 并不是进程
    step5:进入运行某个命令的 screen 窗口
       screen -r 进程ID号
       或者 
       screen -r 窗口名
    

    
 

Mongodb 基于验证的副本集

mongodbA128_huanggr 发表了文章 • 0 个评论 • 615 次浏览 • 2016-04-08 18:56 • 来自相关话题

做基于验证的副本集
1、准备三台虚拟机 192.168.1.237,192.168.1.231,192.168.1.232


2、分别在每台机器上建立mongodb副本集文件夹,建用户
groupadd mongo
useradd -g mongo -d /data/mongodb mongo

#存放mongodb数据文件
mkdir -p /data/mongodb/replset/data
mkdir /data/mongodb/conf
chown -R mongo.monog /data/mongodb


#进入mongodb文件夹 ;本次实验用提mongodb3.2.4 官方建议用3.2版本 
#下载地址 wget http://downloads.mongodb.org/l ... 4.tgz

tar xvf mongodb-linux-x86_64-3.2.4.tgz -C /data/mongodb
cd  /data/mongodb && mv mongodb-linux-x86_64-3.0.6 mongodb

配置文件 
cat conf/mongod.conf 
#port
port = 27017
#data dir
dbpath = /data/mongodb/replset/data
#log dir
logpath = /data/mongodb/replset/mongo.log
logappend = true
#Daemon
fork = true
#auth = true #此处是开验证的,暂时不开,所以用#隔开

在每台机器上用mongo用户启动mongodb
su - mongo
/data/mongodb/mongodb/bin/mongod --config /data/mongodb/conf/mongod1.conf --replSet repset &   
#上面的repset是副本集名称

接下来是配置副本集

[root@mongo mongodb]# ./mongodb/bin/mongo
MongoDB shell version: 3.2.4
connecting to: test
Server has startup warnings: 
2016-04-08T11:19:00.306+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2016-04-08T11:19:00.306+0800 I CONTROL  [initandlisten] 

repset:PRIMARY> use admin
switched to db admin
repset:PRIMARY> config = { _id:"repset", members:[
... ... ... {_id:0,host:"192.168.1.237:27018",priority:8},
... ... ... {_id:1,host:"192.168.1.231:27018",priority:8},
... ... ... {_id:2,host:"192.168.1.232:27018",priority:8}]};
以上的priority:8 是权重 三个节点都 是同样的权重。

回车返回以下信息:
{
        "_id" : "repset",
        "members" : [
                {
                        "_id" : 0,
                        "host" : "192.168.1.237:27018" ,
                        "priority" : 8
                },
                {
                        "_id" : 1,
                        "host" : "192.168.1.231:27018",
                        "priority" : 8
                },
                {
                        "_id" : 2,
                        "host" : "192.168.1.232:27018",
                        "priority" : 8
                }
        ]
}


#初始化副本集配置
repset:PRIMARY> rs.initiate(config);
返回OK

#查看集群节点的状态 主节点"stateStr" :"PRIMARY"  其它两个副节点 "stateStr" : "SECONDARY"
repset:PRIMARY> rs.status();
{
        "set" : "repset",
        "date" : ISODate("2016-04-08T03:24:18.758Z"),
        "myState" : 1,
        "members" : [
                {
                        "_id" : 0,
                        "name" : "192.168.1.237:27018",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 402,
                        "optime" : Timestamp(1460084236, 1),
                        "optimeDate" : ISODate("2016-04-08T02:57:16Z"),
                        "electionTime" : Timestamp(1460085562, 1),
                        "electionDate" : ISODate("2016-04-08T03:19:22Z"),
                        "configVersion" : 1,
                        "self" : true
                },
                {
                        "_id" : 1,
                        "name" : "192.168.1.231:27018",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 295,
                        "optime" : Timestamp(1460084236, 1),
                        "optimeDate" : ISODate("2016-04-08T02:57:16Z"),
                        "lastHeartbeat" : ISODate("2016-04-08T03:24:17.870Z"),
                        "lastHeartbeatRecv" : ISODate("2016-04-08T03:24:16.818Z"),
                        "pingMs" : 1,
                        "lastHeartbeatMessage" : "could not find member to sync from",
                        "configVersion" : 1
                },
                {
                        "_id" : 2,
                        "name" : "192.168.1.232:27018",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 205,
                        "optime" : Timestamp(1460084236, 1),
                        "optimeDate" : ISODate("2016-04-08T02:57:16Z"),
                        "lastHeartbeat" : ISODate("2016-04-08T03:24:17.895Z"),
                        "lastHeartbeatRecv" : ISODate("2016-04-08T03:24:18.434Z"),
                        "pingMs" : 1,
                        "configVersion" : 1
                }
        ],
        "ok" : 1
}


OK看到上面的信息就代表副本集配置成功了!
接下来呢就是创建管理用户了

去到主节点上操作创建用户,请注意从上面 的信息来看,我们知道192.168.1.237是目前副本集的主节点,它的状态是PRIMARY,我要建用户要进它里面去创建

/data/mongodb/mongodb/bin/mongo --port 27018 #注意了 如果你是用默认端口27017 那就不用指定--port
repset:PRIMARY> use admin #建用户要切换到admin用户

建系统管理用户
db.createUser(
   {
     user: "root",
     pwd: "loho_mongo",
     roles:[{role:"root",db:"admin"}]
   });

建数据库管理员

db.createUser(
   {
     user: "dbroot",
     pwd: "mongodb",
     roles:[{role:"userAdminAnyDatabase",db:"admin"}]
   });

建好管理用户我们 停掉副本集群 
先停主节点 kill -2 `pgrep mongo`
再把其它两个节点停了,注意一定要用kill -2 不要用kill -9 
把各个节点上的mongod.conf配置文件 改一下,开启验证
#port
port = 27017
#data dir
dbpath = /data/mongodb/replset/data
#log dir
logpath = /data/mongodb/replset/mongo.log
logappend = true
#Daemon
fork = true
auth = true

接下来是做keyFile 文件 在主节点上
openssl  rand -base64 90 >/data/mongodb/keyfile
chmod 600 /data/mongodb/keyfile

把主节点 上的 keyFile拷贝到副本节点 上 然后启动mongodb,注意把keyfile放统一目录,方便管理。
启动mongo,注意一点就是现在副本集的权重都是一样的,启动后主节点有可能又是另外一个节点,其它副节点是没有读和写的权限的
./mongodb/bin/mongod --config /data/mongodb/conf/mongod.conf --keyFile /data/mongodb/replset/keyfile --replSet repset &

三个节点启后 就看到了 副本集群又恢复了 这时要用之前创建的管理账号验证登陆才能去做建库 建用户的操作了

主节点登陆
/data/mongodb/mongodb/bin/mongo --port 27018
repset:PRIMARY>use admin
repset:PRIMARY>db.auth("root","loho_mongo") #验证管理用户,返回1是验证成功的
1

然后就可以做操作了,程序用户得另建例如
repset:PRIMARY>use jd
repset:PRIMARY>db.usr.insert({'name':'hello_world'});
repset:PRIMARY>db.createUser(
          {
      user: "jd_cx",
      pwd: "jd_2016",
      roles:
        [{role : "readWrite",    db:"jd"}]
    }
 );


程序连接mogodb复制集的方法(开发要看的!)http://www.mongoing.com/archives/2642



  查看全部
做基于验证的副本集
1、准备三台虚拟机 192.168.1.237,192.168.1.231,192.168.1.232


2、分别在每台机器上建立mongodb副本集文件夹,建用户
groupadd mongo
useradd -g mongo -d /data/mongodb mongo

#存放mongodb数据文件
mkdir -p /data/mongodb/replset/data
mkdir /data/mongodb/conf
chown -R mongo.monog /data/mongodb


#进入mongodb文件夹 ;本次实验用提mongodb3.2.4 官方建议用3.2版本 
#下载地址 wget http://downloads.mongodb.org/l ... 4.tgz

tar xvf mongodb-linux-x86_64-3.2.4.tgz -C /data/mongodb
cd  /data/mongodb && mv mongodb-linux-x86_64-3.0.6 mongodb

配置文件 
cat conf/mongod.conf 
#port
port = 27017
#data dir
dbpath = /data/mongodb/replset/data
#log dir
logpath = /data/mongodb/replset/mongo.log
logappend = true
#Daemon
fork = true
#auth = true #此处是开验证的,暂时不开,所以用#隔开

在每台机器上用mongo用户启动mongodb
su - mongo
/data/mongodb/mongodb/bin/mongod --config /data/mongodb/conf/mongod1.conf --replSet repset &   
#上面的repset是副本集名称

接下来是配置副本集

[root@mongo mongodb]# ./mongodb/bin/mongo
MongoDB shell version: 3.2.4
connecting to: test
Server has startup warnings: 
2016-04-08T11:19:00.306+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2016-04-08T11:19:00.306+0800 I CONTROL  [initandlisten] 

repset:PRIMARY> use admin
switched to db admin
repset:PRIMARY> config = { _id:"repset", members:[
... ... ... {_id:0,host:"192.168.1.237:27018",priority:8},
... ... ... {_id:1,host:"192.168.1.231:27018",priority:8},
... ... ... {_id:2,host:"192.168.1.232:27018",priority:8}]};
以上的priority:8 是权重 三个节点都 是同样的权重。

回车返回以下信息:
{
        "_id" : "repset",
        "members" : [
                {
                        "_id" : 0,
                        "host" : "192.168.1.237:27018" ,
                        "priority" : 8
                },
                {
                        "_id" : 1,
                        "host" : "192.168.1.231:27018",
                        "priority" : 8
                },
                {
                        "_id" : 2,
                        "host" : "192.168.1.232:27018",
                        "priority" : 8
                }
        ]
}


#初始化副本集配置
repset:PRIMARY> rs.initiate(config);
返回OK

#查看集群节点的状态 主节点"stateStr" :"PRIMARY"  其它两个副节点 "stateStr" : "SECONDARY"
repset:PRIMARY> rs.status();
{
        "set" : "repset",
        "date" : ISODate("2016-04-08T03:24:18.758Z"),
        "myState" : 1,
        "members" : [
                {
                        "_id" : 0,
                        "name" : "192.168.1.237:27018",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 402,
                        "optime" : Timestamp(1460084236, 1),
                        "optimeDate" : ISODate("2016-04-08T02:57:16Z"),
                        "electionTime" : Timestamp(1460085562, 1),
                        "electionDate" : ISODate("2016-04-08T03:19:22Z"),
                        "configVersion" : 1,
                        "self" : true
                },
                {
                        "_id" : 1,
                        "name" : "192.168.1.231:27018",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 295,
                        "optime" : Timestamp(1460084236, 1),
                        "optimeDate" : ISODate("2016-04-08T02:57:16Z"),
                        "lastHeartbeat" : ISODate("2016-04-08T03:24:17.870Z"),
                        "lastHeartbeatRecv" : ISODate("2016-04-08T03:24:16.818Z"),
                        "pingMs" : 1,
                        "lastHeartbeatMessage" : "could not find member to sync from",
                        "configVersion" : 1
                },
                {
                        "_id" : 2,
                        "name" : "192.168.1.232:27018",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 205,
                        "optime" : Timestamp(1460084236, 1),
                        "optimeDate" : ISODate("2016-04-08T02:57:16Z"),
                        "lastHeartbeat" : ISODate("2016-04-08T03:24:17.895Z"),
                        "lastHeartbeatRecv" : ISODate("2016-04-08T03:24:18.434Z"),
                        "pingMs" : 1,
                        "configVersion" : 1
                }
        ],
        "ok" : 1
}


OK看到上面的信息就代表副本集配置成功了!
接下来呢就是创建管理用户了

去到主节点上操作创建用户,请注意从上面 的信息来看,我们知道192.168.1.237是目前副本集的主节点,它的状态是PRIMARY,我要建用户要进它里面去创建

/data/mongodb/mongodb/bin/mongo --port 27018 #注意了 如果你是用默认端口27017 那就不用指定--port
repset:PRIMARY> use admin #建用户要切换到admin用户

建系统管理用户
db.createUser(
   {
     user: "root",
     pwd: "loho_mongo",
     roles:[{role:"root",db:"admin"}]
   });

建数据库管理员

db.createUser(
   {
     user: "dbroot",
     pwd: "mongodb",
     roles:[{role:"userAdminAnyDatabase",db:"admin"}]
   });

建好管理用户我们 停掉副本集群 
先停主节点 kill -2 `pgrep mongo`
再把其它两个节点停了,注意一定要用kill -2 不要用kill -9 
把各个节点上的mongod.conf配置文件 改一下,开启验证
#port
port = 27017
#data dir
dbpath = /data/mongodb/replset/data
#log dir
logpath = /data/mongodb/replset/mongo.log
logappend = true
#Daemon
fork = true
auth = true

接下来是做keyFile 文件 在主节点上
openssl  rand -base64 90 >/data/mongodb/keyfile
chmod 600 /data/mongodb/keyfile

把主节点 上的 keyFile拷贝到副本节点 上 然后启动mongodb,注意把keyfile放统一目录,方便管理。
启动mongo,注意一点就是现在副本集的权重都是一样的,启动后主节点有可能又是另外一个节点,其它副节点是没有读和写的权限的
./mongodb/bin/mongod --config /data/mongodb/conf/mongod.conf --keyFile /data/mongodb/replset/keyfile --replSet repset &

三个节点启后 就看到了 副本集群又恢复了 这时要用之前创建的管理账号验证登陆才能去做建库 建用户的操作了

主节点登陆
/data/mongodb/mongodb/bin/mongo --port 27018
repset:PRIMARY>use admin
repset:PRIMARY>db.auth("root","loho_mongo") #验证管理用户,返回1是验证成功的
1

然后就可以做操作了,程序用户得另建例如
repset:PRIMARY>use jd
repset:PRIMARY>db.usr.insert({'name':'hello_world'});
repset:PRIMARY>db.createUser(
          {
      user: "jd_cx",
      pwd: "jd_2016",
      roles:
        [{role : "readWrite",    db:"jd"}]
    }
 );


程序连接mogodb复制集的方法(开发要看的!)http://www.mongoing.com/archives/2642



 

mysql GTID从库突然断电导致1062错误 除了重做从库 有没有快速修复的办法

回复

MySQLhufuxin 发起了问题 • 1 人关注 • 0 个回复 • 1206 次浏览 • 2016-04-05 15:47 • 来自相关话题