def SetBatchData(self, get): if sys.version_info[0] == 2: get.path = get.path.encode('utf-8') if get.type == '1' or get.type == '2': session['selected'] = get return public.returnMsg(True, 'FILE_ALL_TIPS') elif get.type == '3': for key in json.loads(get.data): try: if sys.version_info[0] == 2: key = key.encode('utf-8') filename = get.path + '/' + key if not self.CheckDir(filename): return public.returnMsg(False, 'FILE_DANGER') os.system('chmod -R ' + get.access + " '" + filename + "'") os.system('chown -R ' + get.user + ':' + get.user + " '" + filename + "'") except: continue public.WriteLog('TYPE_FILE', 'FILE_ALL_ACCESS') return public.returnMsg(True, 'FILE_ALL_ACCESS') else: import shutil isRecyle = os.path.exists('data/recycle_bin.pl') path = get.path get.data = json.loads(get.data) l = len(get.data) i = 0 for key in get.data: try: if sys.version_info[0] == 2: key = key.encode('utf-8') filename = path + '/' + key get.path = filename if not os.path.exists(filename): continue i += 1 public.writeSpeed(key, i, l) if os.path.isdir(filename): if not self.CheckDir(filename): return public.returnMsg(False, 'FILE_DANGER') os.system("chattr -R -i " + filename) if isRecyle: self.Mv_Recycle_bin(get) else: shutil.rmtree(filename) else: if key == '.user.ini': if l > 1: continue os.system('chattr -i ' + filename) if isRecyle: self.Mv_Recycle_bin(get) else: os.remove(filename) except: continue public.writeSpeed(None, 0, 0) public.WriteLog('TYPE_FILE', 'FILE_ALL_DEL') return public.returnMsg(True, 'FILE_ALL_DEL')
def SetBatchData(self,get): get.path = get.path.encode('utf-8'); if get.type == '1' or get.type == '2': import web web.ctx.session.selected = get return public.returnMsg(True,'FILE_ALL_TIPS') elif get.type == '3': for key in get.data: try: filename = get.path+'/'+key.encode('utf-8'); if not self.CheckDir(filename): return public.returnMsg(False,'FILE_DANGER'); os.system('chmod -R '+get.access+" '"+filename+"'") os.system('chown -R '+get.user+':'+get.user+" '"+filename+"'") except: continue; public.WriteLog('TYPE_FILE','FILE_ALL_ACCESS') return public.returnMsg(True,'FILE_ALL_ACCESS') else: import shutil isRecyle = os.path.exists('data/recycle_bin.pl') path = get.path l = len(get.data); i = 0; for key in get.data: try: filename = path + '/'+key.encode('utf-8'); get.path = filename; if not os.path.exists(filename): continue i += 1; public.writeSpeed(key,i,l); if os.path.isdir(filename): if not self.CheckDir(filename): return public.returnMsg(False,'FILE_DANGER'); if isRecyle: self.Mv_Recycle_bin(get) else: shutil.rmtree(filename) else: if key == '.user.ini': os.system('chattr -i ' + filename); if isRecyle: self.Mv_Recycle_bin(get) else: os.remove(filename) except: continue; public.writeSpeed(None,0,0); public.WriteLog('TYPE_FILE','FILE_ALL_DEL') return public.returnMsg(True,'FILE_ALL_DEL')
def closeRecycleBinApi(self): rPath = self.rPath os.system('which chattr && chattr -R -i ' + rPath) rlist = os.listdir(rPath) i = 0 l = len(rlist) for name in rlist: i += 1 path = rPath + name public.writeSpeed(name, i, l) if os.path.isdir(path): shutil.rmtree(path) else: os.remove(path) public.writeSpeed(None, 0, 0) public.writeLog('文件管理', '已清空回收站!') return public.returnJson(True, '已清空回收站!')
def BatchPaste(self,get): import shutil,web get.path = get.path.encode('utf-8'); if not self.CheckDir(get.path): return public.returnMsg(False,'FILE_DANGER'); i = 0; l = len(web.ctx.session.selected.data); if get.type == '1': for key in web.ctx.session.selected.data: i += 1 public.writeSpeed(key,i,l); try: sfile = web.ctx.session.selected.path + '/' + key.encode('utf-8') dfile = get.path + '/' + key.encode('utf-8') if os.path.isdir(sfile): shutil.copytree(sfile,dfile) else: shutil.copyfile(sfile,dfile) except: continue; public.WriteLog('TYPE_FILE','FILE_ALL_COPY',(web.ctx.session.selected.path,get.path)) else: for key in web.ctx.session.selected.data: try: i += 1 public.writeSpeed(key,i,l); sfile = web.ctx.session.selected.path + '/' + key.encode('utf-8') dfile = get.path + '/' + key.encode('utf-8') shutil.move(sfile,dfile) except: continue; public.WriteLog('TYPE_FILE','FILE_ALL_MOTE',(web.ctx.session.selected.path,get.path)) public.writeSpeed(None,0,0); errorCount = len(web.ctx.session.selected.data) - i del(web.ctx.session.selected) return public.returnMsg(True,'FILE_ALL',(str(i),str(errorCount)));
def Close_Recycle_bin(self, get): rPath = '/www/Recycle_bin/' os.system('chattr -R -i ' + rPath) import database, shutil rlist = os.listdir(rPath) i = 0 l = len(rlist) for name in rlist: i += 1 path = rPath + name public.writeSpeed(name, i, l) if name.find('BTDB_') != -1: database.database().DeleteTo(path) continue if os.path.isdir(path): #os.system('rm -rf ' + path); shutil.rmtree(path) else: #os.system('rm -f ' + path); os.remove(path) public.writeSpeed(None, 0, 0) public.WriteLog('TYPE_FILE', 'FILE_CLOSE_RECYCLE_BIN') return public.returnMsg(True, 'FILE_CLOSE_RECYCLE_BIN')
def Close_Recycle_bin(self,get): rPath = '/www/Recycle_bin/' os.system('chattr -R -i ' + rPath) import database,shutil; rlist = os.listdir(rPath) i = 0; l = len(rlist); for name in rlist: i += 1; path = rPath + name; public.writeSpeed(name,i,l); if name.find('BTDB_') != -1: database.database().DeleteTo(path); continue; if os.path.isdir(path): #os.system('rm -rf ' + path); shutil.rmtree(path); else: #os.system('rm -f ' + path); os.remove(path); public.writeSpeed(None,0,0); public.WriteLog('TYPE_FILE','FILE_CLOSE_RECYCLE_BIN'); return public.returnMsg(True,'FILE_CLOSE_RECYCLE_BIN');
def BatchPaste(self, get): import shutil if sys.version_info[0] == 2: get.path = get.path.encode('utf-8') if not self.CheckDir(get.path): return public.returnMsg(False, 'FILE_DANGER') i = 0 myfiles = json.loads(session['selected']['data']) l = len(myfiles) if get.type == '1': for key in myfiles: i += 1 public.writeSpeed(key, i, l) try: if sys.version_info[0] == 2: sfile = session['selected']['path'] + '/' + key.encode( 'utf-8') dfile = get.path + '/' + key.encode('utf-8') else: sfile = session['selected']['path'] + '/' + key dfile = get.path + '/' + key if os.path.isdir(sfile): shutil.copytree(sfile, dfile) else: shutil.copyfile(sfile, dfile) stat = os.stat(sfile) os.chown(dfile, stat.st_uid, stat.st_gid) except: continue public.WriteLog('TYPE_FILE', 'FILE_ALL_COPY', (session['selected']['path'], get.path)) else: for key in myfiles: try: i += 1 public.writeSpeed(key, i, l) if sys.version_info[0] == 2: sfile = session['selected']['path'] + '/' + key.encode( 'utf-8') dfile = get.path + '/' + key.encode('utf-8') else: sfile = session['selected']['path'] + '/' + key dfile = get.path + '/' + key shutil.move(sfile, dfile) except: continue public.WriteLog('TYPE_FILE', 'FILE_ALL_MOTE', (session['selected']['path'], get.path)) public.writeSpeed(None, 0, 0) errorCount = len(myfiles) - i del (session['selected']) return public.returnMsg(True, 'FILE_ALL', (str(i), str(errorCount)))
def batchPasteApi(self): path = request.form.get('path', '').encode('utf-8') stype = request.form.get('type', '').encode('utf-8') # filename = request.form.get('filename', '').encode('utf-8') import shutil if not self.checkDir(path): return public.returnJson(False, '请不要花样作死!') i = 0 myfiles = json.loads(session['selected']['data']) l = len(myfiles) if stype == '1': for key in myfiles: i += 1 public.writeSpeed(key, i, l) try: sfile = session['selected'][ 'path'] + '/' + key.encode('utf-8') dfile = path + '/' + key.encode('utf-8') if os.path.isdir(sfile): shutil.copytree(sfile, dfile) else: shutil.copyfile(sfile, dfile) stat = os.stat(sfile) os.chown(dfile, stat.st_uid, stat.st_gid) except: continue msg = public.getInfo('从[{1}]批量复制到[{2}]成功', (session['selected']['path'], path,)) public.writeLog('文件管理', msg) else: for key in myfiles: try: i += 1 public.writeSpeed(key, i, l) sfile = session['selected'][ 'path'] + '/' + key.encode('utf-8') dfile = path + '/' + key.encode('utf-8') shutil.move(sfile, dfile) except: continue msg = public.getInfo('从[{1}]批量移动到[{2}]成功', (session['selected']['path'], path,)) public.writeLog('文件管理', msg) public.writeSpeed(None, 0, 0) errorCount = len(myfiles) - i del(session['selected']) msg = public.getInfo('批量操作成功[{1}],失败[{2}]', (str(i), str(errorCount))) return public.returnJson(True, msg)
def BatchPaste(self, get): import shutil, web if not self.CheckDir(get.path): return public.returnMsg(False, 'FILE_DANGER') i = 0 l = len(web.ctx.session.selected.data) if get.type == '1': for key in web.ctx.session.selected.data: i += 1 public.writeSpeed(key, i, l) try: sfile = web.ctx.session.selected.path + '/' + key dfile = get.path + '/' + key if os.path.isdir(sfile): shutil.copytree(sfile, dfile) else: shutil.copyfile(sfile, dfile) stat = os.stat(sfile) os.chown(dfile, stat.st_uid, stat.st_gid) except: continue public.WriteLog('TYPE_FILE', 'FILE_ALL_COPY', (web.ctx.session.selected.path, get.path)) else: for key in web.ctx.session.selected.data: try: i += 1 public.writeSpeed(key, i, l) sfile = web.ctx.session.selected.path + '/' + key dfile = get.path + '/' + key shutil.move(sfile, dfile) except: continue public.WriteLog('TYPE_FILE', 'FILE_ALL_MOTE', (web.ctx.session.selected.path, get.path)) public.writeSpeed(None, 0, 0) errorCount = len(web.ctx.session.selected.data) - i del (web.ctx.session.selected) return public.returnMsg(True, 'FILE_ALL', (str(i), str(errorCount)))
def SetSlave(self, get): if not self.GetPort(get): return public.returnMsg(False, '请确定数据库是否已经开启') if not self.CheckBinLog(): return public.returnMsg(False, '请先开启Mysql二进制日志') sconf = public.readFile(self.__mfile) # 备份需要同步的数据库 masterinfo = self.BackUpMasterDbs(get) try: bkstatus = masterinfo["msg"] except: bkstatus = False if bkstatus: return bkstatus __dbpass = public.M('config').where('id=?', (1, )).getField('mysql_root') slave_version = masterinfo["slave_version"] create_replicate_sql = "" # Mysql5.5版本 if "5.5" in slave_version: create_replicate_sql += "CHANGE MASTER TO MASTER_HOST='%s',MASTER_PORT=%s,MASTER_USER='******',MASTER_PASSWORD='******',MASTER_LOG_FILE='%s',MASTER_LOG_POS=%s" % ( masterinfo["master_ip"], masterinfo["master_port"], masterinfo["slave_user"], masterinfo["slave_pass"], masterinfo["logfile"], masterinfo["logpos"]) # Mysql5.6+版本 addconf = """ log-slave-updates=true enforce-gtid-consistency=true gtid-mode=on""" if "5.5" not in slave_version and not re.match("10", slave_version): if not re.search("gtid-mode=on", sconf): sconf = re.sub("\[mysqld\]", "[mysqld]" + addconf, sconf) create_replicate_sql += "CHANGE MASTER TO MASTER_HOST='%s',MASTER_PORT=%s,MASTER_USER='******',MASTER_PASSWORD='******',MASTER_AUTO_POSITION = 1" % ( masterinfo["master_ip"], masterinfo["master_port"], masterinfo["slave_user"], masterinfo["slave_pass"]) # 构造要同步的数据库配置 replicate_dbs = "" if masterinfo["replicate_dbs"][0] != "alldatabases": for d in masterinfo["replicate_dbs"]: replicate_dbs += "\nreplicate-wild-do-table = %s.%s" % (d, "%") else: sconf = re.sub("replicate-wild-do-table\s*=\s*[\w\%\.\_\-]+", "", sconf) print(replicate_dbs) try: serverid = masterinfo["slave_id"] except: serverid = [int(masterinfo["master_id"]) + 1] localip = public.ExecShell("ip a")[0] netip = public.readFile("%s/data/iplist.txt") index = 0 try: for i in masterinfo["slave_ip"]: if i in localip or i in netip: index += masterinfo["slave_ip"].index("i") break if not index: return public.returnMsg(False, '主库没有设置该主机为从服务器,请先设置主服务器后再配置从库') except: pass serverid = serverid[index] if not re.search("replicate-wild-do-table", sconf): sconf = re.sub("server-id\s*=\s*\d+", "server-id = %s%s" % (serverid, replicate_dbs), sconf) public.writeFile(self.__mfile, sconf) # 导入主库数据库 try: pid_old = public.ExecShell( "ps aux|grep 'mysql.sock'|awk 'NR==1 {print $2}'")[0].split( "\n")[0] self.WriteLog("旧PID %s" % pid_old) pid_new = pid_old public.writeFile("/tmp/mysqlpid", "") for i in range(10): if i == 1: os.system("/etc/init.d/mysqld restart &") time.sleep(10) pid_new = public.ExecShell( "ps aux|grep 'mysql.sock'|awk 'NR==1 {print $2}'" )[0].split("\n")[0] self.WriteLog("新PID %s" % pid_new) if pid_old == pid_new: time.sleep(10) pid_new = public.ExecShell( "ps aux|grep 'mysql.sock'|awk 'NR==1 {print $2}'" )[0].split("\n")[0] else: public.writeFile("/tmp/mysqlpid", "ok") break pm.panelMysql().execute("stop slave") pm.panelMysql().execute("reset master") pm.panelMysql().execute("reset slave all") self.WriteLog("开始导入数据库") speed = public.getSpeed() public.writeSpeed("导入数据库", 1, speed["total"]) error = public.ExecShell( "nohup /usr/bin/mysql -uroot -p%s < %s &" % (__dbpass, masterinfo["backsqlpath"])) self.WriteLog(str(error)) except Exception as e: self.WriteLog("导入数据库失败 %s" % e) return public.ReturnMsg(False, "导入失败") threading.Thread(target=self.SetSpeed()).start() self.WriteLog("导入数据库完成") self.WriteLog("删除备份的数据库文件") os.system("rm -f %s" % masterinfo["backsqlpath"]) os.system("rm -f /tmp/mysqlpid") self.WriteLog("重启mysql") pid_old = public.ExecShell( "ps aux|grep 'mysql.sock'|awk 'NR==1 {print $2}'")[0].split( "\n")[0] self.WriteLog("旧PID %s" % pid_old) pid_new = "" public.writeFile("/tmp/mysqlpid", "") restart = 0 for i in range(10): if i == 1: os.system("/etc/init.d/mysqld restart &") time.sleep(10) pid_new = public.ExecShell( "ps aux|grep 'mysql.sock'|awk 'NR==1 {print $2}'" )[0].split("\n")[0] self.WriteLog("新PID %s" % pid_new) if pid_old == pid_new: time.sleep(10) pid_new = public.ExecShell( "ps aux|grep 'mysql.sock'|awk 'NR==1 {print $2}'" )[0].split("\n")[0] else: public.writeFile("/tmp/mysqlpid", "ok") restart += 1 break if restart == 0: return public.ReturnMsg(False, "导入数据后重启失败") public.writeSpeed("重启数据库", int(1), int(2)) threading.Thread(target=self.SetSpeed()).start() self.WriteLog("mysql重启完成") # 写入同步的数据库到面板数据库 for i in masterinfo["replicate_dbs_info"]: if not i: continue localdb = public.M('databases').where('name=?', (i[2], )).select() if not localdb: public.M('databases').add(("name,username,password,accept,ps"), (i[2], i[3], i[4], i[5], i[6])) # 完整复制将主root密码写入到从的面板 if masterinfo["replicate_dbs"][0] == "alldatabases": self.WriteLog("因为是完整同步,修改从库面板密码为主库") public.M('config').where('id=?', (1, )).setField('mysql_root', masterinfo["slave_ips"]) result = str(pm.panelMysql().query("select version()")[0]) self.WriteLog(result) if result == "1045": public.M('config').where('id=?', (1, )).setField( 'mysql_root', __dbpass) # Mairadb10.*版本 if re.match("10", slave_version): set_slave_pos_sql = "SET GLOBAL gtid_slave_pos='%s'" % masterinfo[ "gtid"] # 需要在数据重启后配置 pm.panelMysql().query(set_slave_pos_sql) create_replicate_sql += "CHANGE MASTER TO MASTER_HOST='%s',MASTER_PORT=%s,MASTER_USER='******',MASTER_PASSWORD='******',master_use_gtid=slave_pos" % ( masterinfo["master_ip"], masterinfo["master_port"], masterinfo["slave_user"], masterinfo["slave_pass"]) self.WriteLog("停止从服务") pm.panelMysql().query("stop slave") self.WriteLog("修改从服务器的主服务器信息") pm.panelMysql().query(create_replicate_sql) self.WriteLog("启动从服务") pm.panelMysql().query("start slave") time.sleep(2) self.WriteLog("获取从状态") slavestatus = pm.panelMysql().query("show slave status")[0] self.WriteLog(str(slavestatus)) self.WriteLog("创建Slave监控用户") create_status_user = "******" % ( "user" + masterinfo["slave_user"], masterinfo["master_ip"], "pass" + masterinfo["slave_pass"]) grant_status_user = "******" % ( "user" + masterinfo["slave_user"], masterinfo["master_ip"]) pm.panelMysql().execute(create_status_user) pm.panelMysql().execute(grant_status_user) n = 0 try: for i in slavestatus: if i == "Yes": n += 1 except: return public.returnMsg(False, '获取主从状态失败') if n == 2: print("设置成功") self.WriteLog("删除btmysql用户") self.__ExceSql('delete from mysql.user where user="******"', masterinfo=masterinfo) if masterinfo["replicate_dbs"][0] != "alldatabases": self.WriteLog("删除从btmysql用户") pm.panelMysql().execute( "delete from mysql.user where user='******'") self.WriteLog("设置成功") os.system("rm -f %s" % self.totalspeedfile) return public.returnMsg(True, '设置成功') else: self.WriteLog("设置失败") os.system("rm -f %s" % self.totalspeedfile) return public.returnMsg(True, '设置失败')
def BackUpMasterDbs(self, get): import MySQLdb bakpath = "/www/backup/database" # 是否为ip iprep = "(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})\.(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})\.(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})\.(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})" if re.search(iprep, get.master_ip): master_ip = re.search(iprep, get.master_ip).group() else: print('请输入正确的IP地址') return public.returnMsg(False, '请输入正确的IP地址') ip = self.GetLocalIP() for i in ip: if i == master_ip: return public.returnMsg(False, '不能输入本机的IP') # 解码 masterinfo = json.loads(base64.b64decode(get.keys)) masterinfo["master_ip"] = master_ip # slave_version = pm.panelMysql().query("select version()")[0][0].split("-")[0] slave_version = self.GetVersion() masterinfo["slave_version"] = slave_version # 写入data.json供设置速度使用 self.WriteLog(json.dumps(masterinfo)) public.writeFile(self.datafile, json.dumps(masterinfo)) if not self.CheckPort(master_ip, masterinfo["master_port"]): return public.returnMsg( False, '无法访问从服务器<br>请确认安全组是否已经放行<br>Mysql端口:%s' % masterinfo["master_port"]) if slave_version in masterinfo["master_version"]: try: master_port = int(masterinfo["master_port"]) except Exception as e: return public.returnMsg(False, e) try: db = MySQLdb.connect(host=masterinfo["master_ip"], port=master_port, user="******", passwd=masterinfo["btmysql"], charset="utf8") cur = db.cursor() except: return public.returnMsg( False, '无法连接主服务器,请确定主服务器 IP端口是否正确,安全组是否已经放行Mysql端口') # 开始备份 backsqlpath = "%s/masterslave.sql" % (bakpath) backsh = "nohup mysqldump -h%s -P%s -u%s -p%s --master-data=2 --skip-lock-tables --single-transaction %s%s 1> %s 2>/dev/null&" if masterinfo["replicate_dbs"][0] == "alldatabases": print("Starting backup of databases alldatabases") self.WriteLog("开始备份数据库") # 统计数据库大小 cur.execute( "select concat(round(sum(data_length/1024/1024),2),'MB') as data from information_schema.tables" ) total_db = int(float(cur.fetchall()[0][0].split("M")[0])) print(total_db) if total_db == 0: total_db = 2 public.writeSpeed("备份数据库", 1, total_db) # 开始备份数据库 try: self.WriteLog("备份数据库 %s" % "alldatabases") error = public.ExecShell( backsh % (masterinfo["master_ip"], masterinfo["master_port"], "btmysql", masterinfo["btmysql"], "--all-databases", "", backsqlpath))[1] if "error" in error or "not exist" in error: return public.returnMsg( False, '数据库备份失败 %s\n错误信息:%s\n ,请检测主库是否有问题' % ("alldatabases", error)) except: self.WriteLog("备份失败 %s" % "alldatabases") return public.returnMsg(False, '数据库备份失败 %s' % "alldatabases") threading.Thread(target=self.SetSpeed()).start() else: total_db = 1 replicate_dbs = "" cur.execute("use information_schema") for d in masterinfo["replicate_dbs"]: replicate_dbs += " %s " % d # 统计数据库大小 cur.execute( "select concat(round(sum(data_length/1024/1024),2),'MB') as data from tables where table_schema='%s'" % d) a = cur.fetchall()[0][0] if a: total_db += float(a.split("M")[0]) print(total_db) public.writeSpeed("备份数据库", 1, int(total_db)) print("Starting backup of databases %s" % replicate_dbs) # 开始备份数据库 try: self.WriteLog("备份数据库 %s" % replicate_dbs) error = public.ExecShell( backsh % (masterinfo["master_ip"], masterinfo["master_port"], "btmysql", masterinfo["btmysql"], "--databases", replicate_dbs, backsqlpath))[1] if "error" in error or "not exist" in error: return public.returnMsg( False, '数据库备份失败 %s\n错误信息:%s\n ,请检测主库是否有问题' % ("replicate_dbs", error)) except: self.WriteLog("备份失败 %s" % replicate_dbs) return public.returnMsg(False, '数据库备份失败 %s' % replicate_dbs) threading.Thread(target=self.SetSpeed()).start() self.WriteLog("备份成功") masterlogdata = public.ExecShell("head -n 50 %s" % backsqlpath) try: masterlogdata = masterlogdata[0] rep = "CHANGE MASTER TO MASTER_LOG_FILE='([\w\-\.]+)',\s*MASTER_LOG_POS=(\d+);" logfile = re.search(rep, masterlogdata).group(1) logpos = re.search(rep, masterlogdata).group(2) except: return public.returnMsg(False, '获取Master信息失败') try: gtid = self.__ExceSql('SELECT BINLOG_GTID_POS("%s", %s)' % (logfile, logpos), masterinfo=masterinfo)[0].split("\n")[1] except: gtid = "" db.close() public.writeFile("%s/log.txt" % bakpath, str([logfile, logpos])) masterinfo["logfile"] = logfile masterinfo["logpos"] = logpos masterinfo["gtid"] = gtid masterinfo["backsqlpath"] = backsqlpath public.writeFile("%s/plugin/masterslave/data.json" % self.setpath, json.dumps(masterinfo)) public.writeFile("/tmp/mysql.log", masterinfo, "a+") return masterinfo else: self.WriteLog("mysql版本不一致 主版本%s 从版本%s" % (masterinfo["master_version"], slave_version)) return public.returnMsg( False, 'mysql版本不一致 主版本%s 从版本%s' % (masterinfo["master_version"], slave_version))
def SetSpeed(self): data = public.getSpeed() bakpath = "/www/backup/database/masterslave.sql" if data["title"] == "导入数据库": self.SetTotalSpeed({"total": "80"}) conffile = "%s/plugin/masterslave/data.json" % self.setpath masterinfo = json.loads(public.readFile(conffile)) public.writeSpeed(data["title"], 1, data["total"]) while True: data = public.getSpeed() time.sleep(1) if public.ExecShell("ps aux|grep 'mysql -uroot -p'|wc -l" )[0].split("\n")[0] == "2": public.writeSpeed(data["title"], data["total"], data["total"]) break if data["used"] < data["total"]: if masterinfo["replicate_dbs"][0] == "alldatabases": used = float(pm.panelMysql().query( "select concat(round(sum(data_length/1024/1024),2),'MB') as data from information_schema.tables" )[0][0].split("M")[0]) else: used = 0 try: for i in masterinfo["replicate_dbs"]: used += float(pm.panelMysql().query( "select concat(round(sum(data_length/1024/1024),2),'MB') as data from tables where table_schema='%s'" % i)[0][0].split("M")[0]) except: used = data["total"] public.writeSpeed(data["title"], int(used), data["total"]) else: public.writeSpeed(data["title"], data["total"], data["total"]) break if data["title"] == "备份数据库": self.SetTotalSpeed({"total": "30"}) while True: data = public.getSpeed() time.sleep(1) if public.ExecShell("ps aux|grep 'mysqldump -h'|wc -l" )[0].split("\n")[0] == "2": public.writeSpeed(data["title"], data["total"], data["total"]) break if data["used"] < data["total"]: # used = int(public.ExecShell("du -sm |awk '{print $1}'" % bakpath)[0].split("M")[0]) used = int( public.ExecShell("du -sm %s|awk '{print $1}'" % bakpath)[0].split("\n")[0]) if used > data["total"]: used = data["total"] public.writeSpeed(data["title"], int(used), data["total"]) else: public.writeSpeed(data["title"], data["total"], data["total"]) if data["title"] == "重启数据库": self.SetTotalSpeed({"total": "99"}) n = 0 while True: data = public.getSpeed() time.sleep(1) if n == 100: break if public.readFile("/tmp/mysqlpid"): public.writeSpeed(data["title"], data["total"], data["total"]) self.SetTotalSpeed({"total": "100"}) os.system("rm -f /tmp/mysqlpid") break n += 1
def BackUpMasterDbs(self,get): import MySQLdb bakpath = "/www/backup/database" # 判断输入url是否为ip iprep = "(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})\.(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})\.(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})\.(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})" if re.search(iprep, get.master_ip): master_ip = re.search(iprep, get.master_ip).group() else: print('请输入正确的IP地址') return public.returnMsg(False, '请输入正确的IP地址') ip = self.GetLocalIP() for i in ip: if i == master_ip: return public.returnMsg(False, '不能输入本机的IP') # 解码 masterinfo = json.loads(base64.b64decode(get.keys)) masterinfo["master_ip"] = master_ip slave_version = pm.panelMysql().query("select version()")[0][0].split("-")[0] masterinfo["slave_version"] = slave_version # 写入data.json供设置速度使用 self.WriteLog(json.dumps(masterinfo)) public.writeFile("%s/plugin/masterslave/data.json" % self.setpath, json.dumps(masterinfo)) if not self.CheckPort(master_ip, masterinfo["master_port"]): return public.returnMsg(False, '无法访问从服务器<br>请确认安全组是否已经放行<br>Mysql端口:%s' % masterinfo["slave_port"]) if slave_version == masterinfo["master_version"]: #开始锁表 try: db = MySQLdb.connect(host=masterinfo["master_ip"],port=masterinfo["master_port"], user="******", passwd=masterinfo["btmysql"], charset="utf8") cur = db.cursor() except: return public.returnMsg(False, '无法连接主服务器,请确定主服务器 IP端口是否正确,安全组是否已经放行Mysql端口') print("主库开始锁表") self.WriteLog("主库开始锁表") cur.execute("flush tables with read lock;") # baktime = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) print("Set Master to readonly mode") # 开始备份 backsqlpath = "%s/masterslave.sql" % (bakpath) backsh = "nohup mysqldump -h%s -P%s -u%s -p%s %s%s 1> %s 2>/dev/null&" if masterinfo["replicate_dbs"][0] == "alldatabases": print("Starting backup of databases alldatabases") self.WriteLog("开始备份数据库") # 统计数据库大小 cur.execute("select concat(round(sum(data_length/1024/1024),2),'MB') as data from information_schema.tables") total_db = int(float(cur.fetchall()[0][0].split("M")[0])) print(total_db) if total_db == 0: total_db = 2 public.writeSpeed("备份数据库",1,total_db) # 开始备份数据库 try: self.WriteLog("备份数据库 %s" % "alldatabases") error = public.ExecShell(backsh % (masterinfo["master_ip"], masterinfo["master_port"], "btmysql", masterinfo["btmysql"],"--all-databases","",backsqlpath))[1] if "error" in error: return public.returnMsg(False, '数据库备份失败 %s\n错误信息:%s\n ,请检测主库是否有问题' % ("alldatabases", error)) except: self.WriteLog("备份失败 %s" % "alldatabases") return public.returnMsg(False, '数据库备份失败 %s' % "alldatabases") threading.Thread(target=self.SetSpeed()).start() else: total_db = 1 replicate_dbs = "" cur.execute("use information_schema") for d in masterinfo["replicate_dbs"]: replicate_dbs += " %s " % d # 统计数据库大小 cur.execute("select concat(round(sum(data_length/1024/1024),2),'MB') as data from tables where table_schema='%s'" % d) a = cur.fetchall()[0][0] if a: total_db += float(a.split("M")[0]) print(total_db) public.writeSpeed("备份数据库", 1, int(total_db)) print("Starting backup of databases %s" % replicate_dbs) # 开始备份数据库 try: self.WriteLog("备份数据库 %s" % replicate_dbs) error = public.ExecShell(backsh % ( masterinfo["master_ip"], masterinfo["master_port"], "btmysql", masterinfo["btmysql"], "--databases", replicate_dbs, backsqlpath))[1] if "error" in error: return public.returnMsg(False, '数据库备份失败 %s\n错误信息:%s\n ,请检测主库是否有问题' % ("replicate_dbs", error)) except: self.WriteLog("备份失败 %s" % replicate_dbs) return public.returnMsg(False, '数据库备份失败 %s' % replicate_dbs) threading.Thread(target=self.SetSpeed()).start() self.WriteLog("备份成功") masterloginfo = self.__ExceSql("show master status",masterinfo=masterinfo)[0].split("\n")[1].split("\t") logfile = masterloginfo[0] logpos = masterloginfo[1] try: gtid = self.__ExceSql('SELECT BINLOG_GTID_POS("%s", %s)' % (logfile,logpos),masterinfo=masterinfo)[0].split("\n")[1] except: gtid = "" print("主库解锁表") self.WriteLog("主库解锁表") cur.execute("unlock tables;") db.close() public.writeFile("%s/log.txt" % bakpath,str([logfile,logpos])) masterinfo["logfile"] = logfile masterinfo["logpos"] = logpos masterinfo["gtid"] = gtid masterinfo["backsqlpath"] = backsqlpath public.writeFile("%s/plugin/masterslave/data.json" % self.setpath, json.dumps(masterinfo)) public.writeFile("/tmp/mysql.log", masterinfo, "a+") return masterinfo else: self.WriteLog("mysql版本不一致") return public.returnMsg(False, 'mysql版本不一致')
def setBatchDataApi(self): path = request.form.get('path', '').encode('utf-8') stype = request.form.get('type', '').encode('utf-8') access = request.form.get('access', '').encode('utf-8') user = request.form.get('user', '').encode('utf-8') data = request.form.get('data') if stype == '1' or stype == '2': session['selected'] = { 'path': path, 'type': stype, 'access': access, 'user': user, 'data': data } return public.returnJson(True, '标记成功,请在目标目录点击粘贴所有按钮!') elif stype == '3': for key in json.loads(data): try: key = key.encode('utf-8') filename = path + '/' + key if not self.checkDir(filename): return public.returnJson(False, 'FILE_DANGER') os.system('chmod -R ' + access + " '" + filename + "'") os.system('chown -R ' + user + ':' + user + " '" + filename + "'") except: continue public.writeLog('文件管理', '批量设置权限成功!') return public.returnJson(True, '批量设置权限成功!') else: import shutil isRecyle = os.path.exists('data/recycle_bin.pl') data = json.loads(data) l = len(data) i = 0 for key in data: try: filename = path + '/' + key.encode('utf-8') topath = filename if not os.path.exists(filename): continue i += 1 public.writeSpeed(key, i, l) if os.path.isdir(filename): if not self.checkDir(filename): return public.returnJson(False, '请不要花样作死!') if isRecyle: self.mvRecycleBin(topath) else: shutil.rmtree(filename) else: if key == '.user.ini': os.system('which chattr && chattr -i ' + filename) if isRecyle: self.mvRecycleBin(topath) else: os.remove(filename) except: continue public.writeSpeed(None, 0, 0) public.writeLog('文件管理', '批量删除成功!') return public.returnJson(True, '批量删除成功!')