系统内存不足导致OOM 错杀MySQL进程

MySQLlixd 回复了问题 • 2 人关注 • 1 个回复 • 15 次浏览 • 2016-07-16 10:12 • 来自相关话题

Keepalived在故障切换过程中出现多个检查脚本进程初探

回复

MySQLglon 发起了问题 • 4 人关注 • 0 个回复 • 20 次浏览 • 2016-05-26 10:53 • 来自相关话题

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

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

redis_520_1(0).jpg

 Hello 大家好,

    很高兴告诉大家,Redis中国用户组经过一个多月的紧张筹备,终于在今天这个美好的日子和大家见面了!希望有更多的Redis爱好者加入到我们当中,共同致力为Redis技术的推广和应用,... 查看全部
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 发表了文章 • 0 个评论 • 24 次浏览 • 2016-05-16 17:27 • 来自相关话题

脚本还比较傻瓜,要求 MySQL 规范化部署。
basedir = /usr/local/mysql
datadir = /data/mysql/appname/data
conf_path: /data/mysql/appname/my%port.cnf
s... 查看全部
脚本还比较傻瓜,要求 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 发表了文章 • 0 个评论 • 68 次浏览 • 2016-05-10 18:24 • 来自相关话题

最近需要分离一个业务到 MySQL 上,使用 GTID 模型一主一从的复制结构,并使用 KeepAlived 做为高可用切换。
吴总说过,如果在切换的时候从库还没同步完成,会丢失数据,而网络抖动时切换,有可能导致脑裂。
基于这个,对原本简单的 mysql ... 查看全部
最近需要分离一个业务到 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 个评论 • 17 次浏览 • 2016-04-15 23:53 • 来自相关话题

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

1、在命令后面加 &
    有可能会在关闭当前终端的时候中断退出
 
2、使用 nohup
    如:nohup sleep 100 &
    会在当前目录生成一个 nohup.out 文件,会收集这个命令... 查看全部
后台运行命令有下面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 窗口名
    

    
 

同为nosql 请允许我发mongodb的文章 基于验证的副本集

Redis/memcachedA128_huanggr 发表了文章 • 0 个评论 • 15 次浏览 • 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 /... 查看全部
做基于验证的副本集
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 个回复 • 15 次浏览 • 2016-04-05 15:47 • 来自相关话题

主站目录脚本自动更新

LinuxA128_huanggr 发表了文章 • 0 个评论 • 49 次浏览 • 2016-03-24 21:38 • 来自相关话题

今接到开发的一个要求,写个脚本,更新主站目录文件 ,要求,先把更新的文件和要更新的文件 分别备份
然后再进行更新覆盖.这样 话就不用每次更新都要人工去做繁琐的事。脚本考虑到了文件是不定的,随时会变更每一个文件。脚本运行前把更新文件目录压缩后上传到目录,运行脚本... 查看全部
今接到开发的一个要求,写个脚本,更新主站目录文件 ,要求,先把更新的文件和要更新的文件 分别备份
然后再进行更新覆盖.这样 话就不用每次更新都要人工去做繁琐的事。脚本考虑到了文件是不定的,随时会变更每一个文件。脚本运行前把更新文件目录压缩后上传到目录,运行脚本就行了。

例如开发要更新user目录下的这几个文件 :

user
├── user/access.log
└── user/public_html
├── user/public_html/css
│ ├── user/public_html/css/admin_main.css
│ └── user/public_html/css/user.css
├── user/public_html/img
│ └── user/public_html/img/spirit.png
└── user/public_html/WEB-INF
└── user/public_html/WEB-INF/jsp
└── user/public_html/WEB-INF/jsp/errorPage.jsp

#!/bin/bash


#backup changed deploy
upload=/home/loho88/upload/deploy
changed=/home/loho88/upload/changed

javaproj=/data/www/java-proj/
backup=/home/loho88/upload/backup

date1=`date +%F_%T`
cp $upload/*.zip $changed/loho_"$date1".zip
mv $upload/*.zip /tmp/lin
unzip /tmp/lin/*.zip -d $upload
wcc=`ls -l $upload|grep drw|awk '{print $9}'|wc -l`

for i in `seq $wcc`;do
ml=`ls -l $upload |grep "drw"|awk '{print $9}'|sed -n "$i"p`
mkdir $backup/deploy_"$ml"_"$date1"
cd $upload
tree -f $ml|grep "\." |awk '{print $NF}'>/tmp/aa
ls -R "$upload"/$ml/|grep "\.">/tmp/aaa
hs=`cat /tmp/aaa|wc -l`
for ii in `seq $hs`;do
wj=`sed -n "$ii"p /tmp/aaa`
wj2=`sed -n "$ii"p /tmp/aa`
cd $javaproj
cp -r -f --parents $wj2 $backup/deploy_"$ml"_"$date1"
cp -r -f "$upload"/$wj2 "$javaproj"$wj2

done
:>/tmp/aa
:>/tmp/aaa
rm -fr "$upload"/* && rm -fr /tmp/lin/*
done

官方半同步和增强半同步的问题?

MySQLhuzilin 回复了问题 • 2 人关注 • 1 个回复 • 22 次浏览 • 2016-03-15 17:19 • 来自相关话题