mirror of
https://github.com/midoks/mdserver-web.git
synced 2026-10-20 08:25:50 +08:00
update
This commit is contained in:
@@ -72,6 +72,9 @@ replicate-ignore-db = performance_schema
|
|||||||
replicate-ignore-db = mysql
|
replicate-ignore-db = mysql
|
||||||
replicate-ignore-db = test
|
replicate-ignore-db = test
|
||||||
|
|
||||||
|
master_info_repository = table
|
||||||
|
relay_log_info_repository = table
|
||||||
|
|
||||||
default_storage_engine = InnoDB
|
default_storage_engine = InnoDB
|
||||||
innodb_data_home_dir = {$SERVER_APP_PATH}/data
|
innodb_data_home_dir = {$SERVER_APP_PATH}/data
|
||||||
innodb_data_file_path = ibdata1:10M:autoextend
|
innodb_data_file_path = ibdata1:10M:autoextend
|
||||||
|
|||||||
@@ -68,6 +68,9 @@ replicate-ignore-db = performance_schema
|
|||||||
replicate-ignore-db = mysql
|
replicate-ignore-db = mysql
|
||||||
replicate-ignore-db = test
|
replicate-ignore-db = test
|
||||||
|
|
||||||
|
master_info_repository = table
|
||||||
|
relay_log_info_repository = table
|
||||||
|
|
||||||
default_storage_engine = InnoDB
|
default_storage_engine = InnoDB
|
||||||
innodb_data_home_dir = {$SERVER_APP_PATH}/data
|
innodb_data_home_dir = {$SERVER_APP_PATH}/data
|
||||||
innodb_data_file_path = ibdata1:10M:autoextend
|
innodb_data_file_path = ibdata1:10M:autoextend
|
||||||
|
|||||||
+207
-147
@@ -101,6 +101,14 @@ def getDbPort():
|
|||||||
return tmp.groups()[0].strip()
|
return tmp.groups()[0].strip()
|
||||||
|
|
||||||
|
|
||||||
|
def getDbServerId():
|
||||||
|
file = getConf()
|
||||||
|
content = mw.readFile(file)
|
||||||
|
rep = 'server-id\s*=\s*(.*)'
|
||||||
|
tmp = re.search(rep, content)
|
||||||
|
return tmp.groups()[0].strip()
|
||||||
|
|
||||||
|
|
||||||
def getSocketFile():
|
def getSocketFile():
|
||||||
file = getConf()
|
file = getConf()
|
||||||
content = mw.readFile(file)
|
content = mw.readFile(file)
|
||||||
@@ -1863,27 +1871,34 @@ def getMasterRepSlaveUserCmd(version):
|
|||||||
|
|
||||||
mode = recognizeDbMode()
|
mode = recognizeDbMode()
|
||||||
|
|
||||||
|
sid = getDbServerId()
|
||||||
|
channel_name = ""
|
||||||
|
if sid != '':
|
||||||
|
channel_name = " for channel 'r{}';".format(sid)
|
||||||
|
|
||||||
if mode == "gtid":
|
if mode == "gtid":
|
||||||
sql = "CHANGE MASTER TO MASTER_HOST='" + ip + "', MASTER_PORT=" + port + ", MASTER_USER='" + \
|
sql = "CHANGE MASTER TO MASTER_HOST='" + ip + "', MASTER_PORT=" + port + ", MASTER_USER='" + \
|
||||||
clist[0]['username'] + "', MASTER_PASSWORD='" + \
|
clist[0]['username'] + "', MASTER_PASSWORD='" + \
|
||||||
clist[0]['password'] + "', MASTER_AUTO_POSITION=1"
|
clist[0]['password'] + "', MASTER_AUTO_POSITION=1" + channel_name
|
||||||
if version == '8.0':
|
if version == '8.0':
|
||||||
sql = "CHANGE REPLICATION SOURCE TO SOURCE_HOST='" + ip + "', SOURCE_PORT=" + port + ", SOURCE_USER='" + \
|
sql = "CHANGE REPLICATION SOURCE TO SOURCE_HOST='" + ip + "', SOURCE_PORT=" + port + ", SOURCE_USER='" + \
|
||||||
clist[0]['username'] + "', SOURCE_PASSWORD='" + \
|
clist[0]['username'] + "', SOURCE_PASSWORD='" + \
|
||||||
clist[0]['password'] + "', MASTER_AUTO_POSITION=1"
|
clist[0]['password'] + \
|
||||||
|
"', MASTER_AUTO_POSITION=1" + channel_name
|
||||||
else:
|
else:
|
||||||
sql = "CHANGE MASTER TO MASTER_HOST='" + ip + "', MASTER_PORT=" + port + ", MASTER_USER='" + \
|
sql = "CHANGE MASTER TO MASTER_HOST='" + ip + "', MASTER_PORT=" + port + ", MASTER_USER='" + \
|
||||||
clist[0]['username'] + "', MASTER_PASSWORD='" + \
|
clist[0]['username'] + "', MASTER_PASSWORD='" + \
|
||||||
clist[0]['password'] + \
|
clist[0]['password'] + \
|
||||||
"', MASTER_LOG_FILE='" + mstatus[0]["File"] + \
|
"', MASTER_LOG_FILE='" + mstatus[0]["File"] + \
|
||||||
"',MASTER_LOG_POS=" + str(mstatus[0]["Position"])
|
"',MASTER_LOG_POS=" + str(mstatus[0]["Position"]) + channel_name
|
||||||
|
|
||||||
if version == "8.0":
|
if version == "8.0":
|
||||||
sql = "CHANGE REPLICATION SOURCE TO SOURCE_HOST='" + ip + "', SOURCE_PORT=" + port + ", SOURCE_USER='" + \
|
sql = "CHANGE REPLICATION SOURCE TO SOURCE_HOST='" + ip + "', SOURCE_PORT=" + port + ", SOURCE_USER='" + \
|
||||||
clist[0]['username'] + "', SOURCE_PASSWORD='" + \
|
clist[0]['username'] + "', SOURCE_PASSWORD='" + \
|
||||||
clist[0]['password'] + \
|
clist[0]['password'] + \
|
||||||
"', SOURCE_LOG_FILE='" + mstatus[0]["File"] + \
|
"', SOURCE_LOG_FILE='" + mstatus[0]["File"] + \
|
||||||
"',SOURCE_LOG_POS=" + str(mstatus[0]["Position"])
|
"',SOURCE_LOG_POS=" + \
|
||||||
|
str(mstatus[0]["Position"]) + channel_name
|
||||||
|
|
||||||
data = {}
|
data = {}
|
||||||
data['cmd'] = sql
|
data['cmd'] = sql
|
||||||
@@ -2154,22 +2169,10 @@ def updateSlaveSSH(version=''):
|
|||||||
|
|
||||||
|
|
||||||
def getSlaveList(version=''):
|
def getSlaveList(version=''):
|
||||||
|
|
||||||
db = pMysqlDb()
|
db = pMysqlDb()
|
||||||
dlist = db.query('show slave status')
|
dlist = db.query('show slave status')
|
||||||
ret = []
|
|
||||||
for x in range(0, len(dlist)):
|
|
||||||
tmp = {}
|
|
||||||
tmp['Master_User'] = dlist[x]["Master_User"]
|
|
||||||
tmp['Master_Host'] = dlist[x]["Master_Host"]
|
|
||||||
tmp['Master_Port'] = dlist[x]["Master_Port"]
|
|
||||||
tmp['Master_Log_File'] = dlist[x]["Master_Log_File"]
|
|
||||||
tmp['Slave_IO_Running'] = dlist[x]["Slave_IO_Running"]
|
|
||||||
tmp['Slave_SQL_Running'] = dlist[x]["Slave_SQL_Running"]
|
|
||||||
ret.append(tmp)
|
|
||||||
data = {}
|
data = {}
|
||||||
data['data'] = ret
|
data['data'] = dlist
|
||||||
|
|
||||||
return mw.getJson(data)
|
return mw.getJson(data)
|
||||||
|
|
||||||
|
|
||||||
@@ -2193,100 +2196,149 @@ def initSlaveStatus(version=''):
|
|||||||
return initSlaveStatusSyncUser(version)
|
return initSlaveStatusSyncUser(version)
|
||||||
|
|
||||||
|
|
||||||
|
def parseSlaveSyncCmd(cmd):
|
||||||
|
a = {}
|
||||||
|
if cmd.lower().find('for') > 0:
|
||||||
|
cmd_tmp = cmd.split('for')
|
||||||
|
cmd = cmd_tmp[0].strip()
|
||||||
|
|
||||||
|
pattern_c = r"channel \'(.*)\';"
|
||||||
|
match_val = re.match(pattern_c, cmd_tmp[1].strip(), re.I)
|
||||||
|
if match_val:
|
||||||
|
m_groups = match_val.groups()
|
||||||
|
a['channel'] = m_groups[0]
|
||||||
|
vlist = cmd.split(',')
|
||||||
|
for i in vlist:
|
||||||
|
tmp = i.strip()
|
||||||
|
tmp_a = tmp.split(" ")
|
||||||
|
real_tmp = tmp_a[len(tmp_a) - 1]
|
||||||
|
kv = real_tmp.split("=")
|
||||||
|
a[kv[0]] = kv[1].replace("'", '').replace("'", '').replace(";", '')
|
||||||
|
return a
|
||||||
|
|
||||||
|
|
||||||
def initSlaveStatusSyncUser(version=''):
|
def initSlaveStatusSyncUser(version=''):
|
||||||
conn = pSqliteDb('slave_sync_user')
|
conn = pSqliteDb('slave_sync_user')
|
||||||
data = conn.field('ip,port,user,pass,mode,cmd').find()
|
slave_data = conn.field('ip,port,user,pass,mode,cmd').select()
|
||||||
if len(data) < 1:
|
if len(slave_data) < 1:
|
||||||
return mw.returnJson(False, '需要先添加同步用户配置!')
|
return mw.returnJson(False, '需要先添加同步用户配置!')
|
||||||
|
|
||||||
# print(data)
|
# print(data)
|
||||||
db = pMysqlDb()
|
pdb = pMysqlDb()
|
||||||
dlist = db.query('show slave status')
|
if len(slave_data) == 1:
|
||||||
if len(dlist) > 0:
|
dlist = pdb.query('show slave status')
|
||||||
return mw.returnJson(False, '已经初始化好了zz...')
|
if len(dlist) > 0:
|
||||||
|
return mw.returnJson(False, '已经初始化好了zz...')
|
||||||
u = data
|
|
||||||
|
|
||||||
mode_name = 'classic'
|
|
||||||
if u['mode'] == '1':
|
|
||||||
mode_name = 'gtid'
|
|
||||||
|
|
||||||
|
msg = ''
|
||||||
local_mode = recognizeDbMode()
|
local_mode = recognizeDbMode()
|
||||||
if local_mode != mode_name:
|
for x in range(len(slave_data)):
|
||||||
return mw.returnJson(False, '同步模式不一致!')
|
slave_t = slave_data[x]
|
||||||
|
mode_name = 'classic'
|
||||||
|
base_t = 'IP:' + slave_t['ip'] + ",PORT:" + \
|
||||||
|
slave_t['port'] + ",USER:" + slave_t['user']
|
||||||
|
|
||||||
t = db.query(u['cmd'])
|
if slave_t['mode'] == '1':
|
||||||
# print(t)
|
mode_name = 'gtid'
|
||||||
db.query("start slave user='{}' password='{}';".format(
|
|
||||||
u['user'], u['pass']))
|
if local_mode != mode_name:
|
||||||
return mw.returnJson(True, '初始化成功!')
|
msg += base_t + '->同步模式不一致'
|
||||||
|
continue
|
||||||
|
|
||||||
|
cmd_sql = slave_t['cmd']
|
||||||
|
if cmd_sql == '':
|
||||||
|
msg += base_t + '->同步命令不能为空'
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
pinfo = parseSlaveSyncCmd(cmd_sql)
|
||||||
|
except Exception as e:
|
||||||
|
return mw.returnJson(False, base_t + '->CMD同步命令不合规范!')
|
||||||
|
# print(u['cmd'])
|
||||||
|
t = pdb.query(cmd_sql)
|
||||||
|
isError = isSqlError(t)
|
||||||
|
if isError:
|
||||||
|
return isError
|
||||||
|
|
||||||
|
# pdb.query("start slave user='{}' password='{}';".format(
|
||||||
|
# u['user'], u['pass']))
|
||||||
|
|
||||||
|
pdb.query("start slave")
|
||||||
|
pdb.query("start all slaves")
|
||||||
|
|
||||||
|
if msg == '':
|
||||||
|
msg = '初始化成功!'
|
||||||
|
return mw.returnJson(True, msg)
|
||||||
|
|
||||||
|
|
||||||
def initSlaveStatusSSH(version=''):
|
def initSlaveStatusSSH(version=''):
|
||||||
db = pMysqlDb()
|
db = pMysqlDb()
|
||||||
dlist = db.query('show slave status')
|
dlist = db.query('show slave status')
|
||||||
if len(dlist) > 0:
|
|
||||||
return mw.returnJson(False, '已经初始化好了zz...')
|
|
||||||
|
|
||||||
conn = pSqliteDb('slave_id_rsa')
|
conn = pSqliteDb('slave_id_rsa')
|
||||||
data = conn.field('ip,port,id_rsa').find()
|
ssh_list = conn.field('ip,port,id_rsa,db_user').select()
|
||||||
|
|
||||||
if len(data) < 1:
|
if len(ssh_list) < 1:
|
||||||
return mw.returnJson(False, '需要先配置【[主]SSH配置】!')
|
return mw.returnJson(False, '需要先配置【[主]SSH配置】!')
|
||||||
|
|
||||||
SSH_PRIVATE_KEY = "/tmp/t_ssh.txt"
|
local_mode = recognizeDbMode()
|
||||||
ip = data['ip']
|
|
||||||
master_port = data['port']
|
|
||||||
mw.writeFile(SSH_PRIVATE_KEY, data['id_rsa'].replace('\\n', '\n'))
|
|
||||||
|
|
||||||
import paramiko
|
import paramiko
|
||||||
paramiko.util.log_to_file('paramiko.log')
|
paramiko.util.log_to_file('paramiko.log')
|
||||||
ssh = paramiko.SSHClient()
|
ssh = paramiko.SSHClient()
|
||||||
|
|
||||||
try:
|
db.query('stop slave')
|
||||||
|
db.query('reset slave all')
|
||||||
|
for data in ssh_list:
|
||||||
|
ip = data['ip']
|
||||||
|
SSH_PRIVATE_KEY = "/tmp/t_ssh_" + ip + ".txt"
|
||||||
|
master_port = data['port']
|
||||||
|
mw.writeFile(SSH_PRIVATE_KEY, data['id_rsa'].replace('\\n', '\n'))
|
||||||
mw.execShell("chmod 600 " + SSH_PRIVATE_KEY)
|
mw.execShell("chmod 600 " + SSH_PRIVATE_KEY)
|
||||||
key = paramiko.RSAKey.from_private_key_file(SSH_PRIVATE_KEY)
|
try:
|
||||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
key = paramiko.RSAKey.from_private_key_file(SSH_PRIVATE_KEY)
|
||||||
ssh.connect(hostname=ip, port=int(master_port),
|
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||||
username='root', pkey=key)
|
ssh.connect(hostname=ip, port=int(master_port),
|
||||||
|
username='root', pkey=key)
|
||||||
|
|
||||||
cmd = 'cd /www/server/mdserver-web && python3 plugins/mysql/index.py get_master_rep_slave_user_cmd {"username":"","db":""}'
|
db_user = data['db_user']
|
||||||
stdin, stdout, stderr = ssh.exec_command(cmd)
|
cmd = 'cd /www/server/mdserver-web && source bin/activate && python3 plugins/mysql-yum/index.py get_master_rep_slave_user_cmd {"username":"' + db_user + '","db":""}'
|
||||||
result = stdout.read()
|
stdin, stdout, stderr = ssh.exec_command(cmd)
|
||||||
result = result.decode('utf-8')
|
result = stdout.read()
|
||||||
cmd_data = json.loads(result)
|
result = result.decode('utf-8')
|
||||||
|
if result.strip() == "":
|
||||||
|
return mw.returnJson(False, '[主][' + ip + ']:获取同步命令失败!')
|
||||||
|
|
||||||
if not cmd_data['status']:
|
cmd_data = json.loads(result)
|
||||||
return mw.returnJson(False, '[主]:' + cmd_data['msg'])
|
if not cmd_data['status']:
|
||||||
|
return mw.returnJson(False, '[主][' + ip + ']:' + cmd_data['msg'])
|
||||||
|
|
||||||
local_mode = recognizeDbMode()
|
if local_mode != cmd_data['data']['mode']:
|
||||||
if local_mode != cmd_data['data']['mode']:
|
return mw.returnJson(False, '[主][' + ip + ']:【{}】从【{}】,运行模式不一致!'.format(cmd_data['data']['mode'], local_mode))
|
||||||
return mw.returnJson(False, '主【{}】从【{}】,运行模式不一致!'.format(cmd_data['data']['mode'], local_mode))
|
|
||||||
|
|
||||||
u = cmd_data['data']['info']
|
u = cmd_data['data']['info']
|
||||||
ps = u['username'] + "|" + u['password']
|
|
||||||
conn.where('ip=?', (ip,)).setField('ps', ps)
|
|
||||||
db.query('stop slave')
|
|
||||||
|
|
||||||
# 保证同步IP一致
|
ps = u['username'] + "|" + u['password']
|
||||||
cmd = cmd_data['data']['cmd']
|
print(ps)
|
||||||
if cmd.find('SOURCE_HOST') > -1:
|
conn.where('ip=?', (ip,)).setField('ps', ps)
|
||||||
cmd = re.sub(r"SOURCE_HOST='(.*)'",
|
db.query('stop slave')
|
||||||
"SOURCE_HOST='" + ip + "'", cmd, 1)
|
|
||||||
|
|
||||||
if cmd.find('MASTER_HOST') > -1:
|
# 保证同步IP一致
|
||||||
cmd = re.sub(r"MASTER_HOST='(.*)'",
|
cmd = cmd_data['data']['cmd']
|
||||||
"MASTER_HOST='" + ip + "'", cmd, 1)
|
if cmd.find('SOURCE_HOST') > -1:
|
||||||
db.query(cmd)
|
cmd = re.sub(r"SOURCE_HOST='(.*?)'",
|
||||||
db.query("start slave user='{}' password='{}';".format(
|
"SOURCE_HOST='" + ip + "'", cmd, 1)
|
||||||
u['username'], u['password']))
|
|
||||||
except Exception as e:
|
|
||||||
return mw.returnJson(False, 'SSH认证配置连接失败!' + str(e))
|
|
||||||
|
|
||||||
ssh.close()
|
if cmd.find('MASTER_HOST') > -1:
|
||||||
time.sleep(1)
|
cmd = re.sub(r"MASTER_HOST='(.*?)'",
|
||||||
os.system("rm -rf " + SSH_PRIVATE_KEY)
|
"MASTER_HOST='" + ip + "'", cmd, 1)
|
||||||
|
db.query(cmd)
|
||||||
|
ssh.close()
|
||||||
|
if os.path.exists(SSH_PRIVATE_KEY):
|
||||||
|
os.system("rm -rf " + SSH_PRIVATE_KEY)
|
||||||
|
except Exception as e:
|
||||||
|
return mw.returnJson(False, '[主][' + ip + ']:SSH认证配置连接失败!' + str(e))
|
||||||
|
db.query('start slave')
|
||||||
return mw.returnJson(True, '初始化成功!')
|
return mw.returnJson(True, '初始化成功!')
|
||||||
|
|
||||||
|
|
||||||
@@ -2296,60 +2348,37 @@ def setSlaveStatus(version=''):
|
|||||||
return mw.returnJson(False, '需要先设置同步配置')
|
return mw.returnJson(False, '需要先设置同步配置')
|
||||||
|
|
||||||
mode = mw.readFile(mode_file)
|
mode = mw.readFile(mode_file)
|
||||||
if mode == 'ssh':
|
pdb = pMysqlDb()
|
||||||
return setSlaveStatusSSH(version)
|
dlist = pdb.query('show slave status')
|
||||||
if mode == 'sync-user':
|
|
||||||
return setSlaveStatusSyncUser(version)
|
|
||||||
|
|
||||||
|
|
||||||
def setSlaveStatusSyncUser(version=''):
|
|
||||||
db = pMysqlDb()
|
|
||||||
dlist = db.query('show slave status')
|
|
||||||
if len(dlist) == 0:
|
if len(dlist) == 0:
|
||||||
return mw.returnJson(False, '需要手动添加同步账户或者执行初始化!')
|
return mw.returnJson(False, '需要手动添加同步账户或者执行初始化!')
|
||||||
|
|
||||||
if len(dlist) > 0 and (dlist[0]["Slave_IO_Running"] == 'Yes' or dlist[0]["Slave_SQL_Running"] == 'Yes'):
|
for v in dlist:
|
||||||
db.query('stop slave')
|
connection_name = ''
|
||||||
else:
|
cmd = "slave"
|
||||||
ip = dlist[0]['Master_Host']
|
if 'Channel_Name' in v:
|
||||||
conn = pSqliteDb('slave_sync_user')
|
ch_name = v['Channel_Name']
|
||||||
data = conn.field('ip,port,user,pass,mode,cmd').find()
|
cmd = "slave for channel '{}'".format(ch_name)
|
||||||
if len(data) == 0:
|
|
||||||
return mw.returnJson(False, '没有数据无法重启!')
|
|
||||||
user = data['user']
|
|
||||||
apass = data['pass']
|
|
||||||
|
|
||||||
db.query("start slave")
|
if (v["Slave_IO_Running"] == 'Yes' or v["Slave_SQL_Running"] == 'Yes'):
|
||||||
# db.query("start slave user='{}' password='{}';".format(user, apass))
|
pdb.query("stop {}".format(cmd))
|
||||||
|
else:
|
||||||
return mw.returnJson(True, '设置成功!')
|
pdb.query("start {}".format(cmd))
|
||||||
|
|
||||||
|
|
||||||
def setSlaveStatusSSH(version=''):
|
|
||||||
|
|
||||||
db = pMysqlDb()
|
|
||||||
dlist = db.query('show slave status')
|
|
||||||
if len(dlist) == 0:
|
|
||||||
return mw.returnJson(False, '需要手动添加主服务命令或者执行[初始化]!')
|
|
||||||
|
|
||||||
if len(dlist) > 0 and (dlist[0]["Slave_IO_Running"] == 'Yes' or dlist[0]["Slave_SQL_Running"] == 'Yes'):
|
|
||||||
db.query('stop slave')
|
|
||||||
else:
|
|
||||||
ip = dlist[0]['Master_Host']
|
|
||||||
conn = pSqliteDb('slave_id_rsa')
|
|
||||||
data = conn.field('ip,ps').where("ip=?", (ip,)).find()
|
|
||||||
if len(data) == 0:
|
|
||||||
return mw.returnJson(False, '没有数据无法重启!')
|
|
||||||
u = data['ps'].split("|")
|
|
||||||
db.query("start slave user='{}' password='{}';".format(u[0], u[1]))
|
|
||||||
|
|
||||||
return mw.returnJson(True, '设置成功!')
|
return mw.returnJson(True, '设置成功!')
|
||||||
|
|
||||||
|
|
||||||
def deleteSlave(version=''):
|
def deleteSlave(version=''):
|
||||||
|
args = getArgs()
|
||||||
db = pMysqlDb()
|
db = pMysqlDb()
|
||||||
dlist = db.query('stop slave')
|
if 'sign' in args:
|
||||||
dlist = db.query('reset slave all')
|
sign = args['sign']
|
||||||
|
db.query("stop slave for channel '{}'".format(sign))
|
||||||
|
db.query("reset slave all for channel '{}'".format(sign))
|
||||||
|
else:
|
||||||
|
db.query('stop slave')
|
||||||
|
db.query('reset slave all')
|
||||||
|
|
||||||
return mw.returnJson(True, '删除成功!')
|
return mw.returnJson(True, '删除成功!')
|
||||||
|
|
||||||
|
|
||||||
@@ -2385,11 +2414,13 @@ def dumpMysqlData(version=''):
|
|||||||
|
|
||||||
############### --- 重要 同步---- ###########
|
############### --- 重要 同步---- ###########
|
||||||
|
|
||||||
|
def asyncTmpfile():
|
||||||
|
path = '/tmp/mysql_yum_async_status.txt'
|
||||||
|
return path
|
||||||
|
|
||||||
|
|
||||||
def writeDbSyncStatus(data):
|
def writeDbSyncStatus(data):
|
||||||
path = '/tmp/db_async_status.txt'
|
path = asyncTmpfile()
|
||||||
# status_data['code'] = 1
|
|
||||||
# status_data['msg'] = '主服务器备份完成...'
|
|
||||||
# status_data['progress'] = 30
|
|
||||||
mw.writeFile(path, json.dumps(data))
|
mw.writeFile(path, json.dumps(data))
|
||||||
|
|
||||||
|
|
||||||
@@ -2407,16 +2438,22 @@ def doFullSync(version=''):
|
|||||||
|
|
||||||
def doFullSyncUser(version=''):
|
def doFullSyncUser(version=''):
|
||||||
args = getArgs()
|
args = getArgs()
|
||||||
data = checkArgs(args, ['db'])
|
data = checkArgs(args, ['db', 'sign'])
|
||||||
if not data[0]:
|
if not data[0]:
|
||||||
return data[1]
|
return data[1]
|
||||||
|
|
||||||
sync_db = args['db']
|
sync_db = args['db']
|
||||||
|
sync_sign = args['sign']
|
||||||
|
|
||||||
db = pMysqlDb()
|
db = pMysqlDb()
|
||||||
|
|
||||||
conn = pSqliteDb('slave_sync_user')
|
conn = pSqliteDb('slave_sync_user')
|
||||||
data = conn.field('ip,port,user,pass,mode,cmd').find()
|
if sync_sign != '':
|
||||||
|
data = conn.field('ip,port,user,pass,mode,cmd').where(
|
||||||
|
'ip=?', (sync_sign,)).find()
|
||||||
|
else:
|
||||||
|
data = conn.field('ip,port,user,pass,mode,cmd').find()
|
||||||
|
|
||||||
user = data['user']
|
user = data['user']
|
||||||
apass = data['pass']
|
apass = data['pass']
|
||||||
port = data['port']
|
port = data['port']
|
||||||
@@ -2433,9 +2470,10 @@ def doFullSyncUser(version=''):
|
|||||||
writeDbSyncStatus({'code': 1, 'msg': '远程导出数据...', 'progress': 20})
|
writeDbSyncStatus({'code': 1, 'msg': '远程导出数据...', 'progress': 20})
|
||||||
|
|
||||||
if not os.path.exists(bak_file):
|
if not os.path.exists(bak_file):
|
||||||
dump_sql_data = getServerDir() + "/bin/mysqldump " + dmp_option + " --force --opt --default-character-set=utf8 --single-transaction -h" + ip + " -P" + \
|
dump_sql_data = getServerDir() + "/bin/mysqldump " + dmp_option + " --force --opt --default-character-set=utf8 --single-transaction -h" + ip + " -P" + \
|
||||||
port + " -u" + user + " -p" + apass + \
|
port + " -u" + user + " -p\"" + apass + \
|
||||||
" --ssl-mode=DISABLED " + sync_db + " > " + bak_file
|
"\" --ssl-mode=DISABLED " + sync_db + " > " + bak_file
|
||||||
|
# print(dump_sql_data)
|
||||||
mw.execShell(dump_sql_data)
|
mw.execShell(dump_sql_data)
|
||||||
|
|
||||||
writeDbSyncStatus({'code': 2, 'msg': '本地导入数据...', 'progress': 40})
|
writeDbSyncStatus({'code': 2, 'msg': '本地导入数据...', 'progress': 40})
|
||||||
@@ -2452,21 +2490,30 @@ def doFullSyncUser(version=''):
|
|||||||
db.query("start slave")
|
db.query("start slave")
|
||||||
|
|
||||||
writeDbSyncStatus({'code': 6, 'msg': '从库重启完成...', 'progress': 100})
|
writeDbSyncStatus({'code': 6, 'msg': '从库重启完成...', 'progress': 100})
|
||||||
os.system("rm -rf " + bak_file)
|
|
||||||
|
if os.path.exists(bak_file):
|
||||||
|
os.system("rm -rf " + bak_file)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def doFullSyncSSH(version=''):
|
def doFullSyncSSH(version=''):
|
||||||
|
|
||||||
args = getArgs()
|
args = getArgs()
|
||||||
data = checkArgs(args, ['db'])
|
data = checkArgs(args, ['db', 'sign'])
|
||||||
if not data[0]:
|
if not data[0]:
|
||||||
return data[1]
|
return data[1]
|
||||||
|
|
||||||
|
sync_db = args['db']
|
||||||
|
sync_sign = args['sign']
|
||||||
|
|
||||||
db = pMysqlDb()
|
db = pMysqlDb()
|
||||||
|
|
||||||
id_rsa_conn = pSqliteDb('slave_id_rsa')
|
id_rsa_conn = pSqliteDb('slave_id_rsa')
|
||||||
data = id_rsa_conn.field('ip,port,db_user,id_rsa').find()
|
if sync_sign != '':
|
||||||
|
data = id_rsa_conn.field('ip,port,db_user,id_rsa').where(
|
||||||
|
'ip=?', (sync_sign,)).find()
|
||||||
|
else:
|
||||||
|
data = id_rsa_conn.field('ip,port,db_user,id_rsa').find()
|
||||||
|
|
||||||
SSH_PRIVATE_KEY = "/tmp/mysql_sync_id_rsa.txt"
|
SSH_PRIVATE_KEY = "/tmp/mysql_sync_id_rsa.txt"
|
||||||
id_rsa = data['id_rsa'].replace('\\n', '\n')
|
id_rsa = data['id_rsa'].replace('\\n', '\n')
|
||||||
@@ -2508,7 +2555,8 @@ def doFullSyncSSH(version=''):
|
|||||||
writeDbSyncStatus({'code': 0, 'msg': '登录Master成功...', 'progress': 5})
|
writeDbSyncStatus({'code': 0, 'msg': '登录Master成功...', 'progress': 5})
|
||||||
|
|
||||||
dbname = args['db']
|
dbname = args['db']
|
||||||
cmd = "cd /www/server/mdserver-web && python3 plugins/mysql/index.py dump_mysql_data {\"db\":'" + dbname + "'}"
|
cmd = "cd /www/server/mdserver-web && source bin/activate && python3 " + \
|
||||||
|
getPluginDir() + "/index.py dump_mysql_data {\"db\":'" + dbname + "'}"
|
||||||
print(cmd)
|
print(cmd)
|
||||||
stdin, stdout, stderr = ssh.exec_command(cmd)
|
stdin, stdout, stderr = ssh.exec_command(cmd)
|
||||||
result = stdout.read()
|
result = stdout.read()
|
||||||
@@ -2531,7 +2579,10 @@ def doFullSyncSSH(version=''):
|
|||||||
if copy_status == None:
|
if copy_status == None:
|
||||||
writeDbSyncStatus({'code': 2, 'msg': '数据同步本地完成...', 'progress': 40})
|
writeDbSyncStatus({'code': 2, 'msg': '数据同步本地完成...', 'progress': 40})
|
||||||
|
|
||||||
cmd = 'cd /www/server/mdserver-web && python3 plugins/mysql/index.py get_master_rep_slave_user_cmd {"username":"' + db_user + '","db":""}'
|
cmd = 'cd /www/server/mdserver-web && source bin/activate && python3 ' + \
|
||||||
|
getPluginDir() + \
|
||||||
|
'/index.py get_master_rep_slave_user_cmd {"username":"' + \
|
||||||
|
db_user + '","db":""}'
|
||||||
stdin, stdout, stderr = ssh.exec_command(cmd)
|
stdin, stdout, stderr = ssh.exec_command(cmd)
|
||||||
result = stdout.read()
|
result = stdout.read()
|
||||||
result = result.decode('utf-8')
|
result = result.decode('utf-8')
|
||||||
@@ -2543,10 +2594,12 @@ def doFullSyncSSH(version=''):
|
|||||||
cmd = cmd_data['data']['cmd']
|
cmd = cmd_data['data']['cmd']
|
||||||
# 保证同步IP一致
|
# 保证同步IP一致
|
||||||
if cmd.find('SOURCE_HOST') > -1:
|
if cmd.find('SOURCE_HOST') > -1:
|
||||||
cmd = re.sub(r"SOURCE_HOST='(.*)'", "SOURCE_HOST='" + ip + "'", cmd, 1)
|
cmd = re.sub(r"SOURCE_HOST='(.*?)'",
|
||||||
|
"SOURCE_HOST='" + ip + "'", cmd, 1)
|
||||||
|
|
||||||
if cmd.find('MASTER_HOST') > -1:
|
if cmd.find('MASTER_HOST') > -1:
|
||||||
cmd = re.sub(r"MASTER_HOST='(.*)'", "SOURCE_HOST='" + ip + "'", cmd, 1)
|
cmd = re.sub(r"MASTER_HOST='(.*?)'",
|
||||||
|
"MASTER_HOST='" + ip + "'", cmd, 1)
|
||||||
|
|
||||||
db.query(cmd)
|
db.query(cmd)
|
||||||
uinfo = cmd_data['data']['info']
|
uinfo = cmd_data['data']['info']
|
||||||
@@ -2560,6 +2613,8 @@ def doFullSyncSSH(version=''):
|
|||||||
mw.execShell("cd /tmp && gzip -d dump.sql.gz")
|
mw.execShell("cd /tmp && gzip -d dump.sql.gz")
|
||||||
cmd = root_dir + "/bin/mysql -S " + msock + \
|
cmd = root_dir + "/bin/mysql -S " + msock + \
|
||||||
" -uroot -p" + pwd + " < /tmp/dump.sql"
|
" -uroot -p" + pwd + " < /tmp/dump.sql"
|
||||||
|
|
||||||
|
print(cmd)
|
||||||
import_data = mw.execShell(cmd)
|
import_data = mw.execShell(cmd)
|
||||||
if import_data[0] == '':
|
if import_data[0] == '':
|
||||||
print(import_data[1])
|
print(import_data[1])
|
||||||
@@ -2569,8 +2624,9 @@ def doFullSyncSSH(version=''):
|
|||||||
writeDbSyncStatus({'code': 5, 'msg': '导入数据失败...', 'progress': 100})
|
writeDbSyncStatus({'code': 5, 'msg': '导入数据失败...', 'progress': 100})
|
||||||
return 'fail'
|
return 'fail'
|
||||||
|
|
||||||
db.query("start slave user='{}' password='{}';".format(
|
# "start slave user='{}' password='{}';".format(uinfo['username'], uinfo['password'])
|
||||||
uinfo['username'], uinfo['password']))
|
|
||||||
|
db.query("start slave")
|
||||||
writeDbSyncStatus({'code': 6, 'msg': '从库重启完成...', 'progress': 100})
|
writeDbSyncStatus({'code': 6, 'msg': '从库重启完成...', 'progress': 100})
|
||||||
|
|
||||||
os.system("rm -rf " + SSH_PRIVATE_KEY)
|
os.system("rm -rf " + SSH_PRIVATE_KEY)
|
||||||
@@ -2584,12 +2640,16 @@ def fullSync(version=''):
|
|||||||
if not data[0]:
|
if not data[0]:
|
||||||
return data[1]
|
return data[1]
|
||||||
|
|
||||||
status_file = '/tmp/db_async_status.txt'
|
sign = ''
|
||||||
|
if 'sign' in args:
|
||||||
|
sign = args['sign']
|
||||||
|
|
||||||
|
status_file = asyncTmpfile()
|
||||||
if args['begin'] == '1':
|
if args['begin'] == '1':
|
||||||
cmd = 'cd ' + mw.getRunDir() + ' && python3 ' + \
|
cmd = 'cd ' + mw.getRunDir() + ' && python3 ' + getPluginDir() + \
|
||||||
getPluginDir() + \
|
'/index.py do_full_sync {"db":"' + \
|
||||||
'/index.py do_full_sync {"db":"' + args['db'] + '"} &'
|
args['db'] + '","sign":"' + sign + '"} &'
|
||||||
print(cmd)
|
# print(cmd)
|
||||||
mw.execShell(cmd)
|
mw.execShell(cmd)
|
||||||
return json.dumps({'code': 0, 'msg': '同步数据中!', 'progress': 0})
|
return json.dumps({'code': 0, 'msg': '同步数据中!', 'progress': 0})
|
||||||
|
|
||||||
|
|||||||
@@ -162,34 +162,6 @@ function myPort(){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//数据库存储信置
|
|
||||||
function changeMySQLDataPath(act) {
|
|
||||||
if (act != undefined) {
|
|
||||||
layer.confirm(lan.soft.mysql_to_msg, { closeBtn: 2, icon: 3 }, function() {
|
|
||||||
var datadir = $("#datadir").val();
|
|
||||||
var data = 'datadir=' + datadir;
|
|
||||||
var loadT = layer.msg(lan.soft.mysql_to_msg1, { icon: 16, time: 0, shade: [0.3, '#000'] });
|
|
||||||
$.post('/database?action=SetDataDir', data, function(rdata) {
|
|
||||||
layer.close(loadT)
|
|
||||||
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 5 });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$.post('/database?action=GetMySQLInfo', '', function(rdata) {
|
|
||||||
var LimitCon = '<p class="conf_p">\
|
|
||||||
<input id="datadir" class="phpUploadLimit bt-input-text mr5" style="width:350px;" type="text" value="' + rdata.datadir + '" name="datadir">\
|
|
||||||
<span onclick="ChangePath(\'datadir\')" class="glyphicon glyphicon-folder-open cursor mr20" style="width:auto"></span><button class="btn btn-success btn-sm" onclick="changeMySQLDataPath(1)">' + lan.soft.mysql_to + '</button>\
|
|
||||||
</p>';
|
|
||||||
$(".soft-man-con").html(LimitCon);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//数据库配置状态
|
//数据库配置状态
|
||||||
function myPerfOpt() {
|
function myPerfOpt() {
|
||||||
//获取MySQL配置
|
//获取MySQL配置
|
||||||
@@ -1691,12 +1663,12 @@ function getMasterRepSlaveListPage(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function deleteSlave(){
|
function deleteSlave(sign){
|
||||||
myPost('delete_slave', {}, function(data){
|
myPost('delete_slave', {sign:sign}, function(data){
|
||||||
var rdata = $.parseJSON(data.data);
|
var rdata = $.parseJSON(data.data);
|
||||||
showMsg(rdata['msg'], function(){
|
showMsg(rdata['msg'], function(){
|
||||||
masterOrSlaveConf();
|
masterOrSlaveConf();
|
||||||
},{},3000);
|
},{icon:rdata.status?1:2,time:3000},3000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1704,28 +1676,70 @@ function deleteSlave(){
|
|||||||
function getFullSyncStatus(db){
|
function getFullSyncStatus(db){
|
||||||
var timeId = null;
|
var timeId = null;
|
||||||
|
|
||||||
var btn = '<div class="table_toolbar" style="left:0px;"><span data-status="init" class="sync btn btn-default btn-sm" id="begin_full_sync" title="">开始</span></div>';
|
myPost('get_slave_list', {page:1,page_size:100}, function(data){
|
||||||
var loadOpen = layer.open({
|
var rdata = $.parseJSON(data.data);
|
||||||
type: 1,
|
var rsource = rdata.data;
|
||||||
title: '全量同步['+db+']',
|
|
||||||
area: '500px',
|
if (db == 'ALL' && rsource.length>1){
|
||||||
content:"<div class='bt-form pd20 c6'>\
|
layer.msg("多主不支持该模式!",{icon:2});
|
||||||
<div class='divtable mtb10'>\
|
return;
|
||||||
<span id='full_msg'></span>\
|
|
||||||
<div class='progress'>\
|
|
||||||
<div class='progress-bar' role='progressbar' aria-valuenow='0' aria-valuemin='0' aria-valuemax='100' style='min-width: 2em;'>0%</div>\
|
|
||||||
</div>\
|
|
||||||
</div>\
|
|
||||||
"+btn+"\
|
|
||||||
</div>",
|
|
||||||
cancel: function(){
|
|
||||||
clearInterval(timeId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var dataSource = '';
|
||||||
|
if (rsource.length>1){
|
||||||
|
var sourceList = '';
|
||||||
|
for (var i = 0; i < rsource.length; i++) {
|
||||||
|
if ('Channel_Name' in rsource[i]){
|
||||||
|
sourceList += '<option val="'+rsource[i]['Master_Host']+'">'+rsource[i]['Master_Host']+'</option>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dataSource = "<p class='line' style='text-align:center;'>\
|
||||||
|
<span>同步数据源:</span>\
|
||||||
|
<select class='bt-input-text' name='data_source' style='width:200px;'>" + sourceList + "</select>\
|
||||||
|
</p>";
|
||||||
|
}
|
||||||
|
|
||||||
|
layer.open({
|
||||||
|
type: 1,
|
||||||
|
title: '全量同步['+db+']',
|
||||||
|
area: '500px',
|
||||||
|
content:"<div class='bt-form pd15'>\
|
||||||
|
<div class='divtable mtb10'>\
|
||||||
|
"+dataSource+"\
|
||||||
|
<span id='full_msg'></span>\
|
||||||
|
<div class='progress'>\
|
||||||
|
<div class='progress-bar' role='progressbar' aria-valuenow='0' aria-valuemin='0' aria-valuemax='100' style='min-width: 2em;'>0%</div>\
|
||||||
|
</div>\
|
||||||
|
</div>\
|
||||||
|
<div class='table_toolbar' style='left:0px;'>\
|
||||||
|
<span data-status='init' class='sync btn btn-default btn-sm' id='begin_full_sync'>开始</span>\
|
||||||
|
</div>\
|
||||||
|
</div>",
|
||||||
|
cancel: function(){
|
||||||
|
clearInterval(timeId);
|
||||||
|
},
|
||||||
|
success:function(){
|
||||||
|
$('#begin_full_sync').click(function(){
|
||||||
|
var val = $(this).data('status');
|
||||||
|
var sign = $('select[name="data_source"]').val();
|
||||||
|
if (val == 'init'){
|
||||||
|
fullSync(db, sign, 1);
|
||||||
|
timeId = setInterval(function(){
|
||||||
|
fullSync(db,sign,0);
|
||||||
|
}, 1000);
|
||||||
|
$(this).data('status','starting');
|
||||||
|
} else {
|
||||||
|
layer.msg("正在同步中..",{icon:0});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function fullSync(db,begin){
|
function fullSync(db,sign,begin){
|
||||||
|
|
||||||
myPostN('full_sync', {db:db,begin:begin}, function(data){
|
myPostN('full_sync', {db:db,sign:sign,begin:begin}, function(data){
|
||||||
var rdata = $.parseJSON(data.data);
|
var rdata = $.parseJSON(data.data);
|
||||||
$('#full_msg').text(rdata['msg']);
|
$('#full_msg').text(rdata['msg']);
|
||||||
$('.progress-bar').css('width',rdata['progress']+'%');
|
$('.progress-bar').css('width',rdata['progress']+'%');
|
||||||
@@ -1920,18 +1934,29 @@ function addSlaveSyncUser(ip=''){
|
|||||||
<div class='line'><span class='tname'>同步账户</span><div class='info-r'><input name='user' class='bt-input-text mr5' type='text' style='width:330px;' value='"+user+"'></div></div>\
|
<div class='line'><span class='tname'>同步账户</span><div class='info-r'><input name='user' class='bt-input-text mr5' type='text' style='width:330px;' value='"+user+"'></div></div>\
|
||||||
<div class='line'><span class='tname'>同步密码</span><div class='info-r'><input name='pass' class='bt-input-text mr5' type='text' style='width:330px;' value='"+pass+"'></div></div>\
|
<div class='line'><span class='tname'>同步密码</span><div class='info-r'><input name='pass' class='bt-input-text mr5' type='text' style='width:330px;' value='"+pass+"'></div></div>\
|
||||||
<div class='line'>\
|
<div class='line'>\
|
||||||
<span class='tname'>CMD[最好填好]</span>\
|
<span class='tname'>CMD[必须填写]</span>\
|
||||||
<div class='info-r'><textarea class='bt-input-text mr5' row='20' cols='30' name='cmd' style='width:330px;height:150px;'></textarea></div>\
|
<div class='info-r'><textarea class='bt-input-text mr5' row='20' cols='30' name='cmd' style='width:330px;height:150px;'></textarea></div>\
|
||||||
</div>\
|
</div>\
|
||||||
<input type='hidden' name='mode' value='"+mode+"' />\
|
<input type='hidden' name='mode' value='"+mode+"' />\
|
||||||
</form>",
|
</form>",
|
||||||
success:function(){
|
success:function(){
|
||||||
$('textarea[name="cmd"]').html(cmd);
|
$('textarea[name="cmd"]').html(cmd);
|
||||||
|
|
||||||
$('textarea[name="cmd"]').change(function(){
|
$('textarea[name="cmd"]').change(function(){
|
||||||
var val = $(this).val();
|
var val = $(this).val();
|
||||||
var vlist = val.split(',');
|
|
||||||
var a = {};
|
var a = {};
|
||||||
|
if (val.toLowerCase().indexOf('for')>0){
|
||||||
|
cmd_tmp = val.split('for');
|
||||||
|
val = cmd_tmp[0].trim();
|
||||||
|
|
||||||
|
const channel_str = cmd_tmp[1].trim();
|
||||||
|
const ch_reg = /channel \'(.*)\';/;
|
||||||
|
var match_val = channel_str.match(ch_reg);
|
||||||
|
if (match_val.length>1){
|
||||||
|
a['channel'] = match_val[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var vlist = val.split(',');
|
||||||
for (var i in vlist) {
|
for (var i in vlist) {
|
||||||
var tmp = toTrim(vlist[i]);
|
var tmp = toTrim(vlist[i]);
|
||||||
var tmp_a = tmp.split(" ");
|
var tmp_a = tmp.split(" ");
|
||||||
@@ -2098,7 +2123,7 @@ function getSlaveUserList(){
|
|||||||
layerId = layer.open({
|
layerId = layer.open({
|
||||||
type: 1,
|
type: 1,
|
||||||
title: '同步账户列表',
|
title: '同步账户列表',
|
||||||
area: '500px',
|
area: '600px',
|
||||||
content:"<div class='bt-form pd20 c6'>\
|
content:"<div class='bt-form pd20 c6'>\
|
||||||
<div class='divtable mtb10'>\
|
<div class='divtable mtb10'>\
|
||||||
<div><table class='table table-hover get-slave-ssh-list'>\
|
<div><table class='table table-hover get-slave-ssh-list'>\
|
||||||
@@ -2122,7 +2147,7 @@ function getSlaveSSHList(page=1){
|
|||||||
layerId = layer.open({
|
layerId = layer.open({
|
||||||
type: 1,
|
type: 1,
|
||||||
title: 'SSH列表',
|
title: 'SSH列表',
|
||||||
area: '500px',
|
area: '600px',
|
||||||
content:"<div class='bt-form pd20 c6'>\
|
content:"<div class='bt-form pd20 c6'>\
|
||||||
<div class='divtable mtb10'>\
|
<div class='divtable mtb10'>\
|
||||||
<div><table class='table table-hover get-slave-ssh-list'>\
|
<div><table class='table table-hover get-slave-ssh-list'>\
|
||||||
@@ -2230,10 +2255,16 @@ function masterOrSlaveConf(version=''){
|
|||||||
myPost('get_slave_list', _data, function(data){
|
myPost('get_slave_list', _data, function(data){
|
||||||
var rdata = $.parseJSON(data.data);
|
var rdata = $.parseJSON(data.data);
|
||||||
var list = '';
|
var list = '';
|
||||||
|
|
||||||
|
var isHasSign = false;
|
||||||
for(i in rdata.data){
|
for(i in rdata.data){
|
||||||
|
|
||||||
var v = rdata.data[i];
|
var v = rdata.data[i];
|
||||||
var status = "<a class='btlink db_error'>异常</>";
|
if ('Channel_Name' in v){
|
||||||
|
isHasSign = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var status = "<a data-id="+i+" class='btlink db_error'>异常</>";
|
||||||
if (v['Slave_SQL_Running'] == 'Yes' && v['Slave_IO_Running'] == 'Yes'){
|
if (v['Slave_SQL_Running'] == 'Yes' && v['Slave_IO_Running'] == 'Yes'){
|
||||||
status = "正常";
|
status = "正常";
|
||||||
}
|
}
|
||||||
@@ -2245,13 +2276,23 @@ function masterOrSlaveConf(version=''){
|
|||||||
list += '<td>' + rdata.data[i]['Master_Log_File'] +'</td>';
|
list += '<td>' + rdata.data[i]['Master_Log_File'] +'</td>';
|
||||||
list += '<td>' + rdata.data[i]['Slave_IO_Running'] +'</td>';
|
list += '<td>' + rdata.data[i]['Slave_IO_Running'] +'</td>';
|
||||||
list += '<td>' + rdata.data[i]['Slave_SQL_Running'] +'</td>';
|
list += '<td>' + rdata.data[i]['Slave_SQL_Running'] +'</td>';
|
||||||
|
|
||||||
|
if (isHasSign){
|
||||||
|
list += '<td>' + v['Channel_Name'] +'</td>';
|
||||||
|
}
|
||||||
|
|
||||||
list += '<td>' + status +'</td>';
|
list += '<td>' + status +'</td>';
|
||||||
list += '<td style="text-align:right">' +
|
list += '<td style="text-align:right">' +
|
||||||
'<a href="javascript:;" class="btlink" onclick="deleteSlave()" title="删除">删除</a>' +
|
'<a data-id="'+i+'" href="javascript:;" class="btlink btn_delete_slave" title="删除">删除</a>' +
|
||||||
'</td>';
|
'</td>';
|
||||||
list += '</tr>';
|
list += '</tr>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var signThead_th = '';
|
||||||
|
if (isHasSign){
|
||||||
|
var signThead_th = '<th>标识</th>';
|
||||||
|
}
|
||||||
|
|
||||||
var con = '<div class="divtable mtb10">\
|
var con = '<div class="divtable mtb10">\
|
||||||
<div class="tablescroll">\
|
<div class="tablescroll">\
|
||||||
<table id="DataBody" class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0" style="border: 0 none;">\
|
<table id="DataBody" class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0" style="border: 0 none;">\
|
||||||
@@ -2262,6 +2303,7 @@ function masterOrSlaveConf(version=''){
|
|||||||
<th>日志</th>\
|
<th>日志</th>\
|
||||||
<th>IO</th>\
|
<th>IO</th>\
|
||||||
<th>SQL</th>\
|
<th>SQL</th>\
|
||||||
|
'+signThead_th+'\
|
||||||
<th>状态</th>\
|
<th>状态</th>\
|
||||||
<th style="text-align:right;">操作</th></tr></thead>\
|
<th style="text-align:right;">操作</th></tr></thead>\
|
||||||
<tbody>\
|
<tbody>\
|
||||||
@@ -2276,22 +2318,74 @@ function masterOrSlaveConf(version=''){
|
|||||||
// </div>
|
// </div>
|
||||||
$(".table_slave_status_list").html(con);
|
$(".table_slave_status_list").html(con);
|
||||||
|
|
||||||
$('.db_error').click(function(){
|
$(".btn_delete_slave").click(function(){
|
||||||
|
var id = $(this).data('id');
|
||||||
|
var v = rdata.data[id];
|
||||||
|
if ('Channel_Name' in v){
|
||||||
|
deleteSlave(v['Channel_Name']);
|
||||||
|
} else{
|
||||||
|
deleteSlave();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.db_error').click(function(){
|
||||||
|
var id = $(this).data('id');
|
||||||
|
var info = rdata.data[id];
|
||||||
|
|
||||||
|
var err_line = "";
|
||||||
|
err_line +="<tr>\
|
||||||
|
<td>IO错误</td>\
|
||||||
|
<td>"+ (info['Last_IO_Error'] == '' ? '无':info['Last_IO_Error'])+"</td>\
|
||||||
|
</tr>";
|
||||||
|
err_line +="<tr>\
|
||||||
|
<td>SQL错误</td>\
|
||||||
|
<td>"+(info['Last_SQL_Error'] == '' ? '无':info['Last_SQL_Error'])+"</td>\
|
||||||
|
</tr>";
|
||||||
|
|
||||||
|
err_line +="<tr>\
|
||||||
|
<td>状态</td>\
|
||||||
|
<td>"+(info['Slave_SQL_Running_State'] == '' ? '无':info['Slave_SQL_Running_State']) +"</td>\
|
||||||
|
</tr>";
|
||||||
|
|
||||||
layer.open({
|
layer.open({
|
||||||
type: 1,
|
type: 1,
|
||||||
title: '同步异常信息',
|
title: '同步异常信息',
|
||||||
area: '500px',
|
area: ['600px','300px'],
|
||||||
content:"<form class='bt-form pd20 pb70'>\
|
btn:['复制错误',"取消"],
|
||||||
<div class='line'>"+v['Error']+"</div>\
|
content:"<form class='bt-form pd15'>\
|
||||||
<div class='bt-form-submit-btn'>\
|
<div class='divtable mtb10'>\
|
||||||
<button type='button' class='btn btn-success btn-sm btn-title class-copy-db-err'>复制</button>\
|
<div class='tablescroll'>\
|
||||||
|
<table class='table table-hover' width='100%' cellspacing='0' cellpadding='0' border='0' style='border: 0 none;'>\
|
||||||
|
<thead><tr>\
|
||||||
|
<th style='width:80px;'>类型</th>\
|
||||||
|
<th>内容</th>\
|
||||||
|
</tr></thead>\
|
||||||
|
<tbody>"+ err_line +"</tbody>\
|
||||||
|
</table>\
|
||||||
|
</div>\
|
||||||
</div>\
|
</div>\
|
||||||
</form>",
|
</form>",
|
||||||
success:function(){
|
success:function(){
|
||||||
copyText(v['Error']);
|
// copyText(v['Error']);
|
||||||
$('.class-copy-db-err').click(function(){
|
// $('.class-copy-db-err').click(function(){
|
||||||
copyText(v['Error']);
|
// copyText(v['Error']);
|
||||||
});
|
// });
|
||||||
|
},
|
||||||
|
yes:function(){
|
||||||
|
if (info['Last_IO_Error'] != ''){
|
||||||
|
copyText(info['Last_IO_Error']);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info['Last_SQL_Error'] != ''){
|
||||||
|
copyText(info['Last_SQL_Error']);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info['Slave_SQL_Running_State'] != ''){
|
||||||
|
copyText(info['Slave_SQL_Running_State']);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
+12
-4
@@ -2477,7 +2477,7 @@ def initSlaveStatusSyncUser(version=''):
|
|||||||
# u['user'], u['pass']))
|
# u['user'], u['pass']))
|
||||||
|
|
||||||
pdb.query("start slave")
|
pdb.query("start slave")
|
||||||
pdb.query("start all slaves ")
|
pdb.query("start all slaves")
|
||||||
|
|
||||||
if msg == '':
|
if msg == '':
|
||||||
msg = '初始化成功!'
|
msg = '初始化成功!'
|
||||||
@@ -2514,7 +2514,11 @@ def initSlaveStatusSSH(version=''):
|
|||||||
ssh.connect(hostname=ip, port=int(master_port),
|
ssh.connect(hostname=ip, port=int(master_port),
|
||||||
username='root', pkey=key)
|
username='root', pkey=key)
|
||||||
|
|
||||||
cmd = 'cd /www/server/mdserver-web && source bin/activate && python3 plugins/mysql/index.py get_master_rep_slave_user_cmd {"username":"","db":""}'
|
db_user = data['db_user']
|
||||||
|
cmd = 'cd /www/server/mdserver-web && source bin/activate && python3 ' + \
|
||||||
|
getPluginDir() + \
|
||||||
|
'/index.py get_master_rep_slave_user_cmd {"username":"' + \
|
||||||
|
db_user + '","db":""}'
|
||||||
stdin, stdout, stderr = ssh.exec_command(cmd)
|
stdin, stdout, stderr = ssh.exec_command(cmd)
|
||||||
result = stdout.read()
|
result = stdout.read()
|
||||||
result = result.decode('utf-8')
|
result = result.decode('utf-8')
|
||||||
@@ -2768,7 +2772,8 @@ def doFullSyncSSH(version=''):
|
|||||||
writeDbSyncStatus({'code': 0, 'msg': '登录Master成功...', 'progress': 5})
|
writeDbSyncStatus({'code': 0, 'msg': '登录Master成功...', 'progress': 5})
|
||||||
|
|
||||||
dbname = args['db']
|
dbname = args['db']
|
||||||
cmd = "cd /www/server/mdserver-web && source bin/activate && python3 plugins/mysql/index.py dump_mysql_data {\"db\":'" + dbname + "'}"
|
cmd = "cd /www/server/mdserver-web && source bin/activate && python3 " + \
|
||||||
|
getPluginDir() + "/index.py dump_mysql_data {\"db\":'" + dbname + "'}"
|
||||||
print(cmd)
|
print(cmd)
|
||||||
stdin, stdout, stderr = ssh.exec_command(cmd)
|
stdin, stdout, stderr = ssh.exec_command(cmd)
|
||||||
result = stdout.read()
|
result = stdout.read()
|
||||||
@@ -2791,7 +2796,10 @@ def doFullSyncSSH(version=''):
|
|||||||
if copy_status == None:
|
if copy_status == None:
|
||||||
writeDbSyncStatus({'code': 2, 'msg': '数据同步本地完成...', 'progress': 40})
|
writeDbSyncStatus({'code': 2, 'msg': '数据同步本地完成...', 'progress': 40})
|
||||||
|
|
||||||
cmd = 'cd /www/server/mdserver-web && source bin/activate && python3 plugins/mysql/index.py get_master_rep_slave_user_cmd {"username":"' + db_user + '","db":""}'
|
cmd = 'cd /www/server/mdserver-web && source bin/activate && python3 ' + \
|
||||||
|
getPluginDir() + \
|
||||||
|
'/index.py get_master_rep_slave_user_cmd {"username":"' + \
|
||||||
|
db_user + '","db":""}'
|
||||||
stdin, stdout, stderr = ssh.exec_command(cmd)
|
stdin, stdout, stderr = ssh.exec_command(cmd)
|
||||||
result = stdout.read()
|
result = stdout.read()
|
||||||
result = result.decode('utf-8')
|
result = result.decode('utf-8')
|
||||||
|
|||||||
@@ -162,34 +162,6 @@ function myPort(){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//数据库存储信置
|
|
||||||
function changeMySQLDataPath(act) {
|
|
||||||
if (act != undefined) {
|
|
||||||
layer.confirm(lan.soft.mysql_to_msg, { closeBtn: 2, icon: 3 }, function() {
|
|
||||||
var datadir = $("#datadir").val();
|
|
||||||
var data = 'datadir=' + datadir;
|
|
||||||
var loadT = layer.msg(lan.soft.mysql_to_msg1, { icon: 16, time: 0, shade: [0.3, '#000'] });
|
|
||||||
$.post('/database?action=SetDataDir', data, function(rdata) {
|
|
||||||
layer.close(loadT)
|
|
||||||
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 5 });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$.post('/database?action=GetMySQLInfo', '', function(rdata) {
|
|
||||||
var LimitCon = '<p class="conf_p">\
|
|
||||||
<input id="datadir" class="phpUploadLimit bt-input-text mr5" style="width:350px;" type="text" value="' + rdata.datadir + '" name="datadir">\
|
|
||||||
<span onclick="changePath(\'datadir\')" class="glyphicon glyphicon-folder-open cursor mr20" style="width:auto"></span><button class="btn btn-success btn-sm" onclick="changeMySQLDataPath(1)">' + lan.soft.mysql_to + '</button>\
|
|
||||||
</p>';
|
|
||||||
$(".soft-man-con").html(LimitCon);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//数据库配置状态
|
//数据库配置状态
|
||||||
function myPerfOpt() {
|
function myPerfOpt() {
|
||||||
//获取MySQL配置
|
//获取MySQL配置
|
||||||
|
|||||||
Reference in New Issue
Block a user