From 6c40e92a1538a7ea4151b3380b28483b218ac7b2 Mon Sep 17 00:00:00 2001
From: midoks
Date: Sun, 7 Aug 2022 20:44:20 +0800
Subject: [PATCH] mariadb
---
class/core/config_api.py | 2 +-
plugins/mariadb/index.py | 5 +-
plugins/mariadb/scripts/backup.py | 125 ++
plugins/postgresql/js/postgresql.js | 2035 +++++++++++++++++++++++++++
scripts/init.d/mw.tpl | 2 +-
5 files changed, 2164 insertions(+), 5 deletions(-)
create mode 100755 plugins/mariadb/scripts/backup.py
create mode 100755 plugins/postgresql/js/postgresql.js
diff --git a/class/core/config_api.py b/class/core/config_api.py
index af27dc128..429b3346d 100755
--- a/class/core/config_api.py
+++ b/class/core/config_api.py
@@ -16,7 +16,7 @@ from flask import request
class config_api:
# mariadb 优化
- __version = '0.8.6.15'
+ __version = '0.8.6.16'
def __init__(self):
pass
diff --git a/plugins/mariadb/index.py b/plugins/mariadb/index.py
index feaf904c3..9ba058bd2 100755
--- a/plugins/mariadb/index.py
+++ b/plugins/mariadb/index.py
@@ -668,9 +668,8 @@ def setDbBackup():
if not data[0]:
return data[1]
- scDir = mw.getRunDir() + '/scripts/backup.py'
-
- cmd = 'python ' + scDir + ' database ' + args['name'] + ' 3'
+ scDir = getPluginDir() + '/scripts/backup.py'
+ cmd = 'python3 ' + scDir + ' database ' + args['name'] + ' 3'
os.system(cmd)
return mw.returnJson(True, 'ok')
diff --git a/plugins/mariadb/scripts/backup.py b/plugins/mariadb/scripts/backup.py
new file mode 100755
index 000000000..21ef91d10
--- /dev/null
+++ b/plugins/mariadb/scripts/backup.py
@@ -0,0 +1,125 @@
+# coding: utf-8
+#-----------------------------
+# 网站备份工具
+#-----------------------------
+
+import sys
+import os
+
+if sys.platform != 'darwin':
+ os.chdir('/www/server/mdserver-web')
+
+
+chdir = os.getcwd()
+sys.path.append(chdir + '/class/core')
+
+# reload(sys)
+# sys.setdefaultencoding('utf-8')
+
+
+import mw
+import db
+import time
+
+
+class backupTools:
+
+ def backupDatabase(self, name, count):
+ db_path = mw.getServerDir() + '/mariadb'
+ db_name = 'mysql'
+ name = mw.M('databases').dbPos(db_path, 'mysql').where(
+ 'name=?', (name,)).getField('name')
+ startTime = time.time()
+ if not name:
+ endDate = time.strftime('%Y/%m/%d %X', time.localtime())
+ log = "数据库[" + name + "]不存在!"
+ print("★[" + endDate + "] " + log)
+ print(
+ "----------------------------------------------------------------------------")
+ return
+
+ backup_path = mw.getRootDir() + '/backup/database'
+ if not os.path.exists(backup_path):
+ mw.execShell("mkdir -p " + backup_path)
+
+ filename = backup_path + "/db_" + name + "_" + \
+ time.strftime('%Y%m%d_%H%M%S', time.localtime()) + ".sql.gz"
+
+ import re
+ mysql_root = mw.M('config').dbPos(db_path, db_name).where(
+ "id=?", (1,)).getField('mysql_root')
+
+ mycnf = mw.readFile(db_path + '/etc/my.cnf')
+ rep = "\[mysqldump\]\nuser=root"
+ sea = "[mysqldump]\n"
+ subStr = sea + "user=root\npassword=" + mysql_root + "\n"
+ mycnf = mycnf.replace(sea, subStr)
+ if len(mycnf) > 100:
+ mw.writeFile(db_path + '/etc/my.cnf', mycnf)
+
+ # mw.execShell(db_path + "/bin/mysqldump --opt --default-character-set=utf8 " +
+ # name + " | gzip > " + filename)
+
+ # mw.execShell(db_path + "/bin/mysqldump --skip-lock-tables --default-character-set=utf8 " +
+ # name + " | gzip > " + filename)
+
+ mw.execShell(db_path + "/bin/mysqldump --single-transaction --quick --default-character-set=utf8 " +
+ name + " | gzip > " + filename)
+
+ if not os.path.exists(filename):
+ endDate = time.strftime('%Y/%m/%d %X', time.localtime())
+ log = "数据库[" + name + "]备份失败!"
+ print("★[" + endDate + "] " + log)
+ print(
+ "----------------------------------------------------------------------------")
+ return
+
+ mycnf = mw.readFile(db_path + '/etc/my.cnf')
+ mycnf = mycnf.replace(subStr, sea)
+ if len(mycnf) > 100:
+ mw.writeFile(db_path + '/etc/my.cnf', mycnf)
+
+ endDate = time.strftime('%Y/%m/%d %X', time.localtime())
+ outTime = time.time() - startTime
+ pid = mw.M('databases').dbPos(db_path, db_name).where(
+ 'name=?', (name,)).getField('id')
+
+ mw.M('backup').add('type,name,pid,filename,addtime,size', (1, os.path.basename(
+ filename), pid, filename, endDate, os.path.getsize(filename)))
+ log = "数据库[" + name + "]备份成功,用时[" + str(round(outTime, 2)) + "]秒"
+ mw.writeLog('计划任务', log)
+ print("★[" + endDate + "] " + log)
+ print("|---保留最新的[" + count + "]份备份")
+ print("|---文件名:" + filename)
+
+ # 清理多余备份
+ backups = mw.M('backup').where(
+ 'type=? and pid=?', ('1', pid)).field('id,filename').select()
+
+ num = len(backups) - int(count)
+ if num > 0:
+ for backup in backups:
+ mw.execShell("rm -f " + backup['filename'])
+ mw.M('backup').where('id=?', (backup['id'],)).delete()
+ num -= 1
+ print("|---已清理过期备份文件:" + backup['filename'])
+ if num < 1:
+ break
+
+ def backupDatabaseAll(self, save):
+ db_path = mw.getServerDir() + '/mariadb'
+ db_name = 'mysql'
+ databases = mw.M('databases').dbPos(
+ db_path, db_name).field('name').select()
+ for database in databases:
+ self.backupDatabase(database['name'], save)
+
+
+if __name__ == "__main__":
+ backup = backupTools()
+ type = sys.argv[1]
+ if type == 'database':
+ if sys.argv[2] == 'ALL':
+ backup.backupDatabaseAll(sys.argv[3])
+ else:
+ backup.backupDatabase(sys.argv[2], sys.argv[3])
diff --git a/plugins/postgresql/js/postgresql.js b/plugins/postgresql/js/postgresql.js
new file mode 100755
index 000000000..afcbdf340
--- /dev/null
+++ b/plugins/postgresql/js/postgresql.js
@@ -0,0 +1,2035 @@
+function str2Obj(str){
+ var data = {};
+ kv = str.split('&');
+ for(i in kv){
+ v = kv[i].split('=');
+ data[v[0]] = v[1];
+ }
+ return data;
+}
+
+function myPost(method,args,callback, title){
+
+ var _args = null;
+ if (typeof(args) == 'string'){
+ _args = JSON.stringify(str2Obj(args));
+ } else {
+ _args = JSON.stringify(args);
+ }
+
+ var _title = '正在获取...';
+ if (typeof(title) != 'undefined'){
+ _title = title;
+ }
+
+ var loadT = layer.msg(_title, { icon: 16, time: 0, shade: 0.3 });
+ $.post('/plugins/run', {name:'postgresql', func:method, args:_args}, function(data) {
+ layer.close(loadT);
+ if (!data.status){
+ layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
+ return;
+ }
+
+ if(typeof(callback) == 'function'){
+ callback(data);
+ }
+ },'json');
+}
+
+function myPostN(method,args,callback, title){
+
+ var _args = null;
+ if (typeof(args) == 'string'){
+ _args = JSON.stringify(str2Obj(args));
+ } else {
+ _args = JSON.stringify(args);
+ }
+
+ var _title = '正在获取...';
+ if (typeof(title) != 'undefined'){
+ _title = title;
+ }
+ $.post('/plugins/run', {name:'postgresql', func:method, args:_args}, function(data) {
+ if(typeof(callback) == 'function'){
+ callback(data);
+ }
+ },'json');
+}
+
+function myAsyncPost(method,args){
+ var _args = null;
+ if (typeof(args) == 'string'){
+ _args = JSON.stringify(str2Obj(args));
+ } else {
+ _args = JSON.stringify(args);
+ }
+
+ var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
+ return syncPost('/plugins/run', {name:'mysql', func:method, args:_args});
+}
+
+function runInfo(){
+ myPost('run_info','',function(data){
+
+ var rdata = $.parseJSON(data.data);
+ if (typeof(rdata['status']) != 'undefined'){
+ layer.msg(rdata['msg'],{icon:0,time:2000,shade: [0.3, '#000']});
+ return;
+ }
+
+ var cache_size = ((parseInt(rdata.Qcache_hits) / (parseInt(rdata.Qcache_hits) + parseInt(rdata.Qcache_inserts))) * 100).toFixed(2) + '%';
+ if (cache_size == 'NaN%') cache_size = 'OFF';
+ var Con = '\
+ \
+ 启动时间 | ' + getLocalTime(rdata.Run) + ' | 每秒查询 | ' + parseInt(rdata.Questions / rdata.Uptime) + ' |
\
+ 总连接次数 | ' + rdata.Connections + ' | 每秒事务 | ' + parseInt((parseInt(rdata.Com_commit) + parseInt(rdata.Com_rollback)) / rdata.Uptime) + ' |
\
+ 发送 | ' + toSize(rdata.Bytes_sent) + ' | File | ' + rdata.File + ' |
\
+ 接收 | ' + toSize(rdata.Bytes_received) + ' | Position | ' + rdata.Position + ' |
\
+ \
+
\
+
\
+ | | | | \
+ \
+ 活动/峰值连接数 | ' + rdata.Threads_running + '/' + rdata.Max_used_connections + ' | 若值过大,增加max_connections |
\
+ 线程缓存命中率 | ' + ((1 - rdata.Threads_created / rdata.Connections) * 100).toFixed(2) + '% | 若过低,增加thread_cache_size |
\
+ 索引命中率 | ' + ((1 - rdata.Key_reads / rdata.Key_read_requests) * 100).toFixed(2) + '% | 若过低,增加key_buffer_size |
\
+ Innodb索引命中率 | ' + ((1 - rdata.Innodb_buffer_pool_reads / rdata.Innodb_buffer_pool_read_requests) * 100).toFixed(2) + '% | 若过低,增加innodb_buffer_pool_size |
\
+ 查询缓存命中率 | ' + cache_size + ' | ' + lan.soft.mysql_status_ps5 + ' |
\
+ 创建临时表到磁盘 | ' + ((rdata.Created_tmp_disk_tables / rdata.Created_tmp_tables) * 100).toFixed(2) + '% | 若过大,尝试增加tmp_table_size |
\
+ 已打开的表 | ' + rdata.Open_tables + ' | 若过大,增加table_cache_size |
\
+ 没有使用索引的量 | ' + rdata.Select_full_join + ' | 若不为0,请检查数据表的索引是否合理 |
\
+ 没有索引的JOIN量 | ' + rdata.Select_range_check + ' | 若不为0,请检查数据表的索引是否合理 |
\
+ 排序后的合并次数 | ' + rdata.Sort_merge_passes + ' | 若值过大,增加sort_buffer_size |
\
+ 锁表次数 | ' + rdata.Table_locks_waited + ' | 若值过大,请考虑增加您的数据库性能 |
\
+ \
+
';
+ $(".soft-man-con").html(Con);
+ });
+}
+
+
+function myDbPos(){
+ myPost('my_db_pos','',function(data){
+ var con = '';
+ $(".soft-man-con").html(con);
+
+ $('#btn_change_path').click(function(){
+ var datadir = $("input[name='datadir']").val();
+ myPost('set_db_pos','datadir='+datadir,function(data){
+ var rdata = $.parseJSON(data.data);
+ layer.msg(rdata.msg,{icon:rdata.status ? 1 : 5,time:2000,shade: [0.3, '#000']});
+ });
+ });
+ });
+}
+
+function myPort(){
+ myPost('my_port','',function(data){
+ var con = '';
+ $(".soft-man-con").html(con);
+
+ $('#btn_change_port').click(function(){
+ var port = $("input[name='port']").val();
+ myPost('set_my_port','port='+port,function(data){
+ var rdata = $.parseJSON(data.data);
+ if (rdata.status){
+ layer.msg('修改成功!',{icon:1,time:2000,shade: [0.3, '#000']});
+ } else {
+ layer.msg(rdata.msg,{icon:1,time:2000,shade: [0.3, '#000']});
+ }
+ });
+ });
+ });
+}
+
+
+//数据库存储信置
+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 = '\
+ \
+ \
+
';
+ $(".soft-man-con").html(LimitCon);
+ });
+}
+
+
+
+
+//数据库配置状态
+function myPerfOpt() {
+ //获取MySQL配置
+ myPost('db_status','',function(data){
+ var rdata = $.parseJSON(data.data);
+ // console.log(rdata);
+ var key_buffer_size = toSizeM(rdata.mem.key_buffer_size);
+ var query_cache_size = toSizeM(rdata.mem.query_cache_size);
+ var tmp_table_size = toSizeM(rdata.mem.tmp_table_size);
+ var innodb_buffer_pool_size = toSizeM(rdata.mem.innodb_buffer_pool_size);
+ var innodb_additional_mem_pool_size = toSizeM(rdata.mem.innodb_additional_mem_pool_size);
+ var innodb_log_buffer_size = toSizeM(rdata.mem.innodb_log_buffer_size);
+
+ var sort_buffer_size = toSizeM(rdata.mem.sort_buffer_size);
+ var read_buffer_size = toSizeM(rdata.mem.read_buffer_size);
+ var read_rnd_buffer_size = toSizeM(rdata.mem.read_rnd_buffer_size);
+ var join_buffer_size = toSizeM(rdata.mem.join_buffer_size);
+ var thread_stack = toSizeM(rdata.mem.thread_stack);
+ var binlog_cache_size = toSizeM(rdata.mem.binlog_cache_size);
+
+ var a = key_buffer_size + query_cache_size + tmp_table_size + innodb_buffer_pool_size + innodb_additional_mem_pool_size + innodb_log_buffer_size;
+ var b = sort_buffer_size + read_buffer_size + read_rnd_buffer_size + join_buffer_size + thread_stack + binlog_cache_size;
+ var memSize = a + rdata.mem.max_connections * b;
+
+
+ var memCon = '\
+
最大使用内存: \
+ \
+ ' + lan.soft.mysql_set_maxmem + ': MB\
+
\
+
key_buffer_sizeMB, ' + lan.soft.mysql_set_key_buffer_size + '
\
+
query_cache_sizeMB, ' + lan.soft.mysql_set_query_cache_size + '
\
+
tmp_table_sizeMB, ' + lan.soft.mysql_set_tmp_table_size + '
\
+
innodb_buffer_pool_sizeMB, ' + lan.soft.mysql_set_innodb_buffer_pool_size + '
\
+
innodb_log_buffer_sizeMB, ' + lan.soft.mysql_set_innodb_log_buffer_size + '
\
+
innodb_additional_mem_pool_sizeMB
\
+
sort_buffer_sizeKB * ' + lan.soft.mysql_set_conn + ', ' + lan.soft.mysql_set_sort_buffer_size + '
\
+
read_buffer_sizeKB * ' + lan.soft.mysql_set_conn + ', ' + lan.soft.mysql_set_read_buffer_size + '
\
+
read_rnd_buffer_sizeKB * ' + lan.soft.mysql_set_conn + ', ' + lan.soft.mysql_set_read_rnd_buffer_size + '
\
+
join_buffer_sizeKB * ' + lan.soft.mysql_set_conn + ', ' + lan.soft.mysql_set_join_buffer_size + '
\
+
thread_stackKB * ' + lan.soft.mysql_set_conn + ', ' + lan.soft.mysql_set_thread_stack + '
\
+
binlog_cache_sizeKB * ' + lan.soft.mysql_set_conn + ', ' + lan.soft.mysql_set_binlog_cache_size + '
\
+
thread_cache_size ' + lan.soft.mysql_set_thread_cache_size + '
\
+
table_open_cache ' + lan.soft.mysql_set_table_open_cache + '
\
+
max_connections ' + lan.soft.mysql_set_max_connections + '
\
+
\
+
'
+
+ $(".soft-man-con").html(memCon);
+
+ $(".conf_p input[name*='size'],.conf_p input[name='max_connections'],.conf_p input[name='thread_stack']").change(function() {
+ comMySqlMem();
+ });
+
+ $(".conf_p select[name='mysql_set']").change(function() {
+ mySQLMemOpt($(this).val());
+ comMySqlMem();
+ });
+ });
+}
+
+function reBootMySqld(){
+ pluginOpService('mysql','restart','');
+}
+
+
+//设置MySQL配置参数
+function setMySQLConf() {
+ $.post('/system/system_total', '', function(memInfo) {
+ var memSize = memInfo['memTotal'];
+ var setSize = parseInt($("input[name='memSize']").val());
+
+ if(memSize < setSize){
+ var errMsg = "错误,内存分配过高!物理内存: {1}MB
最大使用内存: {2}MB
可能造成的后果: 导致数据库不稳定,甚至无法启动MySQLd服务!";
+ var msg = errMsg.replace('{1}',memSize).replace('{2}',setSize);
+ layer.msg(msg,{icon:2,time:5000});
+ return;
+ }
+
+ var query_cache_size = parseInt($("input[name='query_cache_size']").val());
+ var query_cache_type = 0;
+ if (query_cache_size > 0) {
+ query_cache_type = 1;
+ }
+ var data = {
+ key_buffer_size: parseInt($("input[name='key_buffer_size']").val()),
+ query_cache_size: query_cache_size,
+ query_cache_type: query_cache_type,
+ tmp_table_size: parseInt($("input[name='tmp_table_size']").val()),
+ max_heap_table_size: parseInt($("input[name='tmp_table_size']").val()),
+ innodb_buffer_pool_size: parseInt($("input[name='innodb_buffer_pool_size']").val()),
+ innodb_log_buffer_size: parseInt($("input[name='innodb_log_buffer_size']").val()),
+ sort_buffer_size: parseInt($("input[name='sort_buffer_size']").val()),
+ read_buffer_size: parseInt($("input[name='read_buffer_size']").val()),
+ read_rnd_buffer_size: parseInt($("input[name='read_rnd_buffer_size']").val()),
+ join_buffer_size: parseInt($("input[name='join_buffer_size']").val()),
+ thread_stack: parseInt($("input[name='thread_stack']").val()),
+ binlog_cache_size: parseInt($("input[name='binlog_cache_size']").val()),
+ thread_cache_size: parseInt($("input[name='thread_cache_size']").val()),
+ table_open_cache: parseInt($("input[name='table_open_cache']").val()),
+ max_connections: parseInt($("input[name='max_connections']").val())
+ };
+
+ myPost('set_db_status', data, function(data){
+ var rdata = $.parseJSON(data.data);
+ showMsg(rdata.msg,function(){
+ reBootMySqld();
+ },{ icon: rdata.status ? 1 : 2 });
+ });
+ },'json');
+}
+
+
+//MySQL内存优化方案
+function mySQLMemOpt(opt) {
+ var query_size = parseInt($("input[name='query_cache_size']").val());
+ switch (opt) {
+ case '0':
+ $("input[name='key_buffer_size']").val(8);
+ if (query_size) $("input[name='query_cache_size']").val(4);
+ $("input[name='tmp_table_size']").val(8);
+ $("input[name='innodb_buffer_pool_size']").val(16);
+ $("input[name='sort_buffer_size']").val(256);
+ $("input[name='read_buffer_size']").val(256);
+ $("input[name='read_rnd_buffer_size']").val(128);
+ $("input[name='join_buffer_size']").val(128);
+ $("input[name='thread_stack']").val(256);
+ $("input[name='binlog_cache_size']").val(32);
+ $("input[name='thread_cache_size']").val(4);
+ $("input[name='table_open_cache']").val(32);
+ $("input[name='max_connections']").val(500);
+ break;
+ case '1':
+ $("input[name='key_buffer_size']").val(128);
+ if (query_size) $("input[name='query_cache_size']").val(64);
+ $("input[name='tmp_table_size']").val(64);
+ $("input[name='innodb_buffer_pool_size']").val(256);
+ $("input[name='sort_buffer_size']").val(768);
+ $("input[name='read_buffer_size']").val(768);
+ $("input[name='read_rnd_buffer_size']").val(512);
+ $("input[name='join_buffer_size']").val(1024);
+ $("input[name='thread_stack']").val(256);
+ $("input[name='binlog_cache_size']").val(64);
+ $("input[name='thread_cache_size']").val(64);
+ $("input[name='table_open_cache']").val(128);
+ $("input[name='max_connections']").val(100);
+ break;
+ case '2':
+ $("input[name='key_buffer_size']").val(256);
+ if (query_size) $("input[name='query_cache_size']").val(128);
+ $("input[name='tmp_table_size']").val(384);
+ $("input[name='innodb_buffer_pool_size']").val(384);
+ $("input[name='sort_buffer_size']").val(768);
+ $("input[name='read_buffer_size']").val(768);
+ $("input[name='read_rnd_buffer_size']").val(512);
+ $("input[name='join_buffer_size']").val(2048);
+ $("input[name='thread_stack']").val(256);
+ $("input[name='binlog_cache_size']").val(64);
+ $("input[name='thread_cache_size']").val(96);
+ $("input[name='table_open_cache']").val(192);
+ $("input[name='max_connections']").val(200);
+ break;
+ case '3':
+ $("input[name='key_buffer_size']").val(384);
+ if (query_size) $("input[name='query_cache_size']").val(192);
+ $("input[name='tmp_table_size']").val(512);
+ $("input[name='innodb_buffer_pool_size']").val(512);
+ $("input[name='sort_buffer_size']").val(1024);
+ $("input[name='read_buffer_size']").val(1024);
+ $("input[name='read_rnd_buffer_size']").val(768);
+ $("input[name='join_buffer_size']").val(2048);
+ $("input[name='thread_stack']").val(256);
+ $("input[name='binlog_cache_size']").val(128);
+ $("input[name='thread_cache_size']").val(128);
+ $("input[name='table_open_cache']").val(384);
+ $("input[name='max_connections']").val(300);
+ break;
+ case '4':
+ $("input[name='key_buffer_size']").val(512);
+ if (query_size) $("input[name='query_cache_size']").val(256);
+ $("input[name='tmp_table_size']").val(1024);
+ $("input[name='innodb_buffer_pool_size']").val(1024);
+ $("input[name='sort_buffer_size']").val(2048);
+ $("input[name='read_buffer_size']").val(2048);
+ $("input[name='read_rnd_buffer_size']").val(1024);
+ $("input[name='join_buffer_size']").val(4096);
+ $("input[name='thread_stack']").val(384);
+ $("input[name='binlog_cache_size']").val(192);
+ $("input[name='thread_cache_size']").val(192);
+ $("input[name='table_open_cache']").val(1024);
+ $("input[name='max_connections']").val(400);
+ break;
+ case '5':
+ $("input[name='key_buffer_size']").val(1024);
+ if (query_size) $("input[name='query_cache_size']").val(384);
+ $("input[name='tmp_table_size']").val(2048);
+ $("input[name='innodb_buffer_pool_size']").val(4096);
+ $("input[name='sort_buffer_size']").val(4096);
+ $("input[name='read_buffer_size']").val(4096);
+ $("input[name='read_rnd_buffer_size']").val(2048);
+ $("input[name='join_buffer_size']").val(8192);
+ $("input[name='thread_stack']").val(512);
+ $("input[name='binlog_cache_size']").val(256);
+ $("input[name='thread_cache_size']").val(256);
+ $("input[name='table_open_cache']").val(2048);
+ $("input[name='max_connections']").val(500);
+ break;
+ }
+}
+
+//计算MySQL内存开销
+function comMySqlMem() {
+ var key_buffer_size = parseInt($("input[name='key_buffer_size']").val());
+ var query_cache_size = parseInt($("input[name='query_cache_size']").val());
+ var tmp_table_size = parseInt($("input[name='tmp_table_size']").val());
+ var innodb_buffer_pool_size = parseInt($("input[name='innodb_buffer_pool_size']").val());
+ var innodb_additional_mem_pool_size = parseInt($("input[name='innodb_additional_mem_pool_size']").val());
+ var innodb_log_buffer_size = parseInt($("input[name='innodb_log_buffer_size']").val());
+
+ var sort_buffer_size = $("input[name='sort_buffer_size']").val() / 1024;
+ var read_buffer_size = $("input[name='read_buffer_size']").val() / 1024;
+ var read_rnd_buffer_size = $("input[name='read_rnd_buffer_size']").val() / 1024;
+ var join_buffer_size = $("input[name='join_buffer_size']").val() / 1024;
+ var thread_stack = $("input[name='thread_stack']").val() / 1024;
+ var binlog_cache_size = $("input[name='binlog_cache_size']").val() / 1024;
+ var max_connections = $("input[name='max_connections']").val();
+
+ var a = key_buffer_size + query_cache_size + tmp_table_size + innodb_buffer_pool_size + innodb_additional_mem_pool_size + innodb_log_buffer_size
+ var b = sort_buffer_size + read_buffer_size + read_rnd_buffer_size + join_buffer_size + thread_stack + binlog_cache_size
+ var memSize = a + max_connections * b
+ $("input[name='memSize']").val(memSize.toFixed(2));
+}
+
+function syncGetDatabase(){
+ myPost('sync_get_databases', null, function(data){
+ var rdata = $.parseJSON(data.data);
+ showMsg(rdata.msg,function(){
+ dbList();
+ },{ icon: rdata.status ? 1 : 2 });
+ });
+}
+
+function syncToDatabase(type){
+ var data = [];
+ $('input[type="checkbox"].check:checked').each(function () {
+ if (!isNaN($(this).val())) data.push($(this).val());
+ });
+ var postData = 'type='+type+'&ids='+JSON.stringify(data);
+ myPost('sync_to_databases', postData, function(data){
+ var rdata = $.parseJSON(data.data);
+ // console.log(rdata);
+ showMsg(rdata.msg,function(){
+ dbList();
+ },{ icon: rdata.status ? 1 : 2 });
+ });
+}
+
+function setRootPwd(type, pwd){
+ if (type==1){
+ var data = $("#mod_pwd").serialize();
+ myPost('set_root_pwd', data, function(data){
+ var rdata = $.parseJSON(data.data);
+ // console.log(rdata);
+ showMsg(rdata.msg,function(){
+ dbList();
+ $('.layui-layer-close1').click();
+ },{icon: rdata.status ? 1 : 2});
+ });
+ return;
+ }
+
+ var index = layer.open({
+ type: 1,
+ skin: 'demo-class',
+ area: '500px',
+ title: '修改数据库密码',
+ closeBtn: 1,
+ shift: 5,
+ shadeClose: true,
+ content: "
",
+ });
+
+ $('#my_mod_close').click(function(){
+ $('.layui-layer-close1').click();
+ });
+}
+
+function showHidePass(obj){
+ var a = "glyphicon-eye-open";
+ var b = "glyphicon-eye-close";
+
+ if($(obj).hasClass(a)){
+ $(obj).removeClass(a).addClass(b);
+ $(obj).prev().text($(obj).prev().attr('data-pw'))
+ }
+ else{
+ $(obj).removeClass(b).addClass(a);
+ $(obj).prev().text('***');
+ }
+}
+
+function copyPass(password){
+ var clipboard = new ClipboardJS('#bt_copys');
+ clipboard.on('success', function (e) {
+ layer.msg('复制成功',{icon:1,time:2000});
+ });
+
+ clipboard.on('error', function (e) {
+ layer.msg('复制失败,浏览器不兼容!',{icon:2,time:2000});
+ });
+ $("#bt_copys").attr('data-clipboard-text',password);
+ $("#bt_copys").click();
+}
+
+function checkSelect(){
+ setTimeout(function () {
+ var num = $('input[type="checkbox"].check:checked').length;
+ // console.log(num);
+ if (num == 1) {
+ $('button[batch="true"]').hide();
+ $('button[batch="false"]').show();
+ }else if (num>1){
+ $('button[batch="true"]').show();
+ $('button[batch="false"]').show();
+ }else{
+ $('button[batch="true"]').hide();
+ $('button[batch="false"]').hide();
+ }
+ },5)
+}
+
+function setDbRw(id,username,val){
+ myPost('get_db_rw',{id:id,username:username,rw:val}, function(data){
+ var rdata = $.parseJSON(data.data);
+ // layer.msg(rdata.msg,{icon:rdata.status ? 1 : 5,shade: [0.3, '#000']});
+ showMsg(rdata.msg, function(){
+ dbList();
+ },{icon:rdata.status ? 1 : 5,shade: [0.3, '#000']}, 2000);
+
+ });
+}
+
+function setDbAccess(username){
+ myPost('get_db_access','username='+username, function(data){
+ var rdata = $.parseJSON(data.data);
+ if (!rdata.status){
+ layer.msg(rdata.msg,{icon:2,shade: [0.3, '#000']});
+ return;
+ }
+
+ var index = layer.open({
+ type: 1,
+ area: '500px',
+ title: '设置数据库权限',
+ closeBtn: 1,
+ shift: 5,
+ btn:["提交","取消"],
+ shadeClose: true,
+ content: "",
+ success:function(){
+ if (rdata.msg == '127.0.0.1'){
+ $('select[name="dataAccess"]').find("option[value='127.0.0.1']").attr("selected",true);
+ } else if (rdata.msg == '%'){
+ $('select[name="dataAccess"]').find('option[value="%"]').attr("selected",true);
+ } else if ( rdata.msg == 'ip' ){
+ $('select[name="dataAccess"]').find('option[value="ip"]').attr("selected",true);
+ $('select[name="dataAccess"]').after("");
+ } else {
+ $('select[name="dataAccess"]').find('option[value="ip"]').attr("selected",true);
+ $('select[name="dataAccess"]').after("");
+ }
+
+ $('select[name="dataAccess"]').change(function(){
+ var v = $(this).val();
+ if (v == 'ip'){
+ $(this).after("");
+ } else {
+ $('#dataAccess_subid').remove();
+ }
+ });
+ },
+ yes:function(index){
+ var data = $("#set_db_access").serialize();
+ data = decodeURIComponent(data);
+ var dataObj = str2Obj(data);
+ if(!dataObj['access']){
+ dataObj['access'] = dataObj['dataAccess'];
+ if ( dataObj['dataAccess'] == 'ip'){
+ if (dataObj['address']==''){
+ layer.msg('IP地址不能空!',{icon:2,shade: [0.3, '#000']});
+ return;
+ }
+ dataObj['access'] = dataObj['address'];
+ }
+ }
+ dataObj['username'] = username;
+ myPost('set_db_access', dataObj, function(data){
+ var rdata = $.parseJSON(data.data);
+ showMsg(rdata.msg,function(){
+ layer.close(index);
+ dbList();
+ },{icon: rdata.status ? 1 : 2});
+ });
+ }
+ });
+
+ });
+}
+
+function setDbPass(id, username, password){
+
+ var index = layer.open({
+ type: 1,
+ area: '500px',
+ title: '修改数据库密码',
+ closeBtn: 1,
+ shift: 5,
+ shadeClose: true,
+ btn:["提交","关闭"],
+ content: "",
+ yes:function(index){
+ var data = $("#mod_pwd").serialize();
+ myPost('set_user_pwd', data, function(data){
+ var rdata = $.parseJSON(data.data);
+ showMsg(rdata.msg,function(){
+ layer.close(index);
+ dbList();
+ },{icon: rdata.status ? 1 : 2});
+ });
+ }
+ });
+}
+
+function addDatabase(type){
+ if (type==1){
+ var data = $("#add_db").serialize();
+ data = decodeURIComponent(data);
+ var dataObj = str2Obj(data);
+ if(!dataObj['address']){
+ dataObj['address'] = dataObj['dataAccess'];
+ }
+ myPost('add_db', dataObj, function(data){
+ var rdata = $.parseJSON(data.data);
+ showMsg(rdata.msg,function(){
+ if (rdata.status){
+ dbList();
+ }
+ $('.layui-layer-close1').click();
+ },{icon: rdata.status ? 1 : 2},600);
+ });
+ return;
+ }
+ var index = layer.open({
+ type: 1,
+ skin: 'demo-class',
+ area: '500px',
+ title: '添加数据库',
+ closeBtn: 1,
+ shift: 5,
+ shadeClose: true,
+ content: "",
+ });
+
+ $("input[name='name']").keyup(function(){
+ var v = $(this).val();
+ $("input[name='db_user']").val(v);
+ $("input[name='ps']").val(v);
+ });
+
+ $('#my_mod_close').click(function(){
+ $('.layui-layer-close1').click();
+ });
+ $('select[name="dataAccess"]').change(function(){
+ var v = $(this).val();
+ if (v == 'ip'){
+ $(this).after("");
+ } else {
+ $('#dataAccess_subid').remove();
+ }
+ });
+}
+
+function delDb(id, name){
+ safeMessage('删除['+name+']','您真的要删除['+name+']吗?',function(){
+ var data='id='+id+'&name='+name
+ myPost('del_db', data, function(data){
+ var rdata = $.parseJSON(data.data);
+ showMsg(rdata.msg,function(){
+ dbList();
+ $('.layui-layer-close1').click();
+ },{icon: rdata.status ? 1 : 2}, 600);
+ });
+ });
+}
+
+function delDbBatch(){
+ var arr = [];
+ $('input[type="checkbox"].check:checked').each(function () {
+ var _val = $(this).val();
+ var _name = $(this).parent().next().text();
+ if (!isNaN(_val)) {
+ arr.push({'id':_val,'name':_name});
+ }
+ });
+
+ safeMessage('批量删除数据库','您共选择了[2]个数据库,删除后将无法恢复,真的要删除吗?',function(){
+ var i = 0;
+ $(arr).each(function(){
+ var data = myAsyncPost('del_db', this);
+ var rdata = $.parseJSON(data.data);
+ if (!rdata.status){
+ layer.msg(rdata.msg,{icon:2,time:2000,shade: [0.3, '#000']});
+ }
+ i++;
+ });
+
+ var msg = '成功删除['+i+']个数据库!';
+ showMsg(msg,function(){
+ dbList();
+ },{icon: 1}, 600);
+ });
+}
+
+
+function setDbPs(id, name, obj) {
+ var _span = $(obj);
+ var _input = $("");
+ _span.hide().after(_input);
+ _input.focus();
+ _input.blur(function(){
+ $(this).remove();
+ var ps = _input.val();
+ _span.text(ps).show();
+ var data = {name:name,id:id,ps:ps};
+ myPost('set_db_ps', data, function(data){
+ var rdata = $.parseJSON(data.data);
+ layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
+ });
+ });
+ _input.keyup(function(){
+ if(event.keyCode == 13){
+ _input.trigger('blur');
+ }
+ });
+}
+
+function openPhpmyadmin(name,username,password){
+
+ data = syncPost('/plugins/check',{'name':'phpmyadmin'});
+
+
+ if (!data.status){
+ layer.msg(data.msg,{icon:2,shade: [0.3, '#000']});
+ return;
+ }
+
+ data = syncPost('/plugins/run',{'name':'phpmyadmin','func':'status'});
+ if (data.data != 'start'){
+ layer.msg('phpMyAdmin未启动',{icon:2,shade: [0.3, '#000']});
+ return;
+ }
+ // console.log(data);
+ data = syncPost('/plugins/run',{'name':'phpmyadmin','func':'get_home_page'});
+ var rdata = $.parseJSON(data.data);
+ if (!rdata.status){
+ layer.msg(rdata.msg,{icon:2,shade: [0.3, '#000']});
+ return;
+ }
+ $("#toPHPMyAdmin").attr('action',rdata.data);
+
+ if($("#toPHPMyAdmin").attr('action').indexOf('phpmyadmin') == -1){
+ layer.msg('请先安装phpMyAdmin',{icon:2,shade: [0.3, '#000']});
+ setTimeout(function(){ window.location.href = '/soft'; },3000);
+ return;
+ }
+
+ //检查版本
+ data = syncPost('/plugins/run',{'name':'phpmyadmin','func':'version'});
+ bigVer = data.data.split('.')[0]
+ if (bigVer>=4.5){
+
+ setTimeout(function(){
+ $("#toPHPMyAdmin").submit();
+ },3000);
+ layer.msg('phpMyAdmin['+data.data+']需要手动登录😭',{icon:16,shade: [0.3, '#000'],time:4000});
+
+ } else{
+ var murl = $("#toPHPMyAdmin").attr('action');
+ $("#pma_username").val(username);
+ $("#pma_password").val(password);
+ $("#db").val(name);
+
+ layer.msg('正在打开phpMyAdmin',{icon:16,shade: [0.3, '#000'],time:2000});
+
+ setTimeout(function(){
+ $("#toPHPMyAdmin").submit();
+ },3000);
+ }
+}
+
+function delBackup(filename,name){
+ myPost('delete_db_backup',{filename:filename},function(){
+ layer.msg('执行成功!');
+ setTimeout(function(){
+ $('.layui-layer-close2').click();
+ setBackup(name);
+ },2000);
+ });
+}
+
+function downloadBackup(file){
+ window.open('/files/download?filename='+encodeURIComponent(file));
+}
+
+function importBackup(file,name){
+ myPost('import_db_backup',{file:file,name:name}, function(data){
+ // console.log(data);
+ layer.msg('执行成功!');
+ });
+}
+
+function setBackup(db_name,obj){
+ myPost('get_db_backup_list', {name:db_name}, function(data){
+
+ var rdata = $.parseJSON(data.data);
+ var tbody = '';
+ for (var i = 0; i < rdata.data.length; i++) {
+ tbody += '\
+ ' + rdata.data[i]['name'] + ' | \
+ ' + rdata.data[i]['size'] + ' | \
+ ' + rdata.data[i]['time'] + ' | \
+ \
+ 导入 | \
+ 下载 | \
+ 删除\
+ | \
+
';
+ }
+
+ var s = layer.open({
+ type: 1,
+ title: "数据库备份详情",
+ area: ['600px', '280px'],
+ closeBtn: 2,
+ shadeClose: false,
+ content: '\
+
\
+ \
+
\
+
\
+
\
+
\
+ \
+ \
+ 文件名称 | \
+ 文件大小 | \
+ 备份时间 | \
+ 操作 | \
+
\
+ \
+ ' + tbody + '\
+
\
+
\
+
\
+
'
+ });
+
+ $('#btn_backup').click(function(){
+ myPost('set_db_backup',{name:db_name}, function(data){
+ layer.msg('执行成功!');
+
+ setTimeout(function(){
+ layer.close(s);
+ setBackup(db_name,obj);
+ },2000);
+ });
+ });
+ });
+}
+
+
+function dbList(page, search){
+ var _data = {};
+ if (typeof(page) =='undefined'){
+ var page = 1;
+ }
+
+ _data['page'] = page;
+ _data['page_size'] = 10;
+ if(typeof(search) != 'undefined'){
+ _data['search'] = search;
+ }
+ myPost('get_db_list', _data, function(data){
+ var rdata = $.parseJSON(data.data);
+ var list = '';
+ for(i in rdata.data){
+ list += '';
+ list +=' | ';
+ list += '' + rdata.data[i]['name'] +' | ';
+ list += '' + rdata.data[i]['username'] +' | ';
+ list += '' +
+ '***' +
+ ''+
+ ''+
+ ' | ';
+
+
+ list += ''+rdata.data[i]['ps']+' | ';
+ list += '';
+
+ list += ''+(rdata.data[i]['is_backup']?'备份':'未备份') +' | ';
+
+ var rw = '';
+ var rw_change = 'all';
+ if (typeof(rdata.data[i]['rw'])!='undefined'){
+ var rw_val = '读写';
+ if (rdata.data[i]['rw'] == 'all'){
+ rw_val = "所有";
+ rw_change = 'rw';
+ } else if (rdata.data[i]['rw'] == 'rw'){
+ rw_val = "读写";
+ rw_change = 'r';
+ } else if (rdata.data[i]['rw'] == 'r'){
+ rw_val = "只读";
+ rw_change = 'all';
+ }
+ rw = ''+rw_val+' | ';
+ }
+
+
+ list += '管理 | ' +
+ '工具 | ' +
+ '权限 | ' +
+ rw +
+ '改密 | ' +
+ '删除' +
+ ' | ';
+ list += '
';
+ }
+
+ //
+ var con = '\
+
\
+
\
+
\
+
\
+
\
+ \
+ \
+
\
+
\
+
\
+
\
+ 同步选中\
+ 同步所有\
+ 从服务器获取\
+
\
+
\
+
';
+
+ con += '';
+
+ $(".soft-man-con").html(con);
+ $('#databasePage').html(rdata.page);
+
+ readerTableChecked();
+ });
+}
+
+
+function myLogs(){
+
+ myPost('bin_log', {status:1}, function(data){
+ var rdata = $.parseJSON(data.data);
+
+ var line_status = ""
+ if (rdata.status){
+ line_status = '\
+ ';
+ } else {
+ line_status = '';
+ }
+
+ var limitCon = '\
+ 二进制日志 ' + toSize(rdata.msg) + '\
+ '+line_status+'\
+
错误日志
\
+ \
+
';
+ $(".soft-man-con").html(limitCon);
+
+ //设置二进制日志
+ $(".btn-bin").click(function () {
+ myPost('bin_log', 'close=change', function(data){
+ var rdata = $.parseJSON(data.data);
+ layer.msg(rdata.msg, { icon: rdata.status ? 1 : 5 });
+ setTimeout(function(){myLogs();}, 2000);
+ });
+ });
+
+ $(".clean-btn-bin").click(function () {
+ myPost('clean_bin_log', '', function(data){
+ var rdata = $.parseJSON(data.data);
+ layer.msg(rdata.msg, { icon: rdata.status ? 1 : 5 });
+ setTimeout(function(){myLogs();}, 2000);
+ });
+ });
+
+ //清空日志
+ $(".btn-clear").click(function () {
+ myPost('error_log', 'close=1', function(data){
+ var rdata = $.parseJSON(data.data);
+ layer.msg(rdata.msg, { icon: rdata.status ? 1 : 5 });
+ setTimeout(function(){myLogs();}, 2000);
+ });
+ })
+
+ myPost('error_log', 'p=1', function(data){
+ var rdata = $.parseJSON(data.data);
+ var error_body = '';
+ if (rdata.status){
+ error_body = rdata.data;
+ } else {
+ error_body = rdata.msg;
+ }
+ $("#error_log").html(error_body);
+ var ob = document.getElementById('error_log');
+ ob.scrollTop = ob.scrollHeight;
+ });
+ });
+}
+
+
+function repCheckeds(tables) {
+ var dbs = []
+ if (tables) {
+ dbs.push(tables)
+ } else {
+ var db_tools = $("input[value^='dbtools_']");
+ for (var i = 0; i < db_tools.length; i++) {
+ if (db_tools[i].checked) dbs.push(db_tools[i].value.replace('dbtools_', ''));
+ }
+ }
+
+ if (dbs.length < 1) {
+ layer.msg('请至少选择一张表!', { icon: 2 });
+ return false;
+ }
+ return dbs;
+}
+
+function repDatabase(db_name, tables) {
+ dbs = repCheckeds(tables);
+
+ myPost('repair_table', { db_name: db_name, tables: JSON.stringify(dbs) }, function(data){
+ var rdata = $.parseJSON(data.data);
+ layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
+ repTools(db_name, true);
+ },'已送修复指令,请稍候...');
+}
+
+
+function optDatabase(db_name, tables) {
+ dbs = repCheckeds(tables);
+
+ myPost('opt_table', { db_name: db_name, tables: JSON.stringify(dbs) }, function(data){
+ var rdata = $.parseJSON(data.data);
+ layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
+ repTools(db_name, true);
+ },'已送优化指令,请稍候...');
+}
+
+function toDatabaseType(db_name, tables, type){
+ dbs = repCheckeds(tables);
+ myPost('alter_table', { db_name: db_name, tables: JSON.stringify(dbs),table_type: type }, function(data){
+ var rdata = $.parseJSON(data.data);
+ layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
+ repTools(db_name, true);
+ }, '已送引擎转换指令,请稍候...');
+}
+
+
+function selectedTools(my_obj, db_name) {
+ var is_checked = false
+
+ if (my_obj) is_checked = my_obj.checked;
+ var db_tools = $("input[value^='dbtools_']");
+ var n = 0;
+ for (var i = 0; i < db_tools.length; i++) {
+ if (my_obj) db_tools[i].checked = is_checked;
+ if (db_tools[i].checked) n++;
+ }
+ if (n > 0) {
+ var my_btns = '\
+ \
+ \
+ '
+ $("#db_tools").html(my_btns);
+ } else {
+ $("#db_tools").html('');
+ }
+}
+
+function repTools(db_name, res){
+ myPost('get_db_info', {name:db_name}, function(data){
+ var rdata = $.parseJSON(data.data);
+ var types = { InnoDB: "MyISAM", MyISAM: "InnoDB" };
+ var tbody = '';
+ for (var i = 0; i < rdata.tables.length; i++) {
+ if (!types[rdata.tables[i].type]) continue;
+ tbody += '\
+ | \
+ ' + rdata.tables[i].table_name + ' | \
+ ' + rdata.tables[i].type + ' | \
+ ' + rdata.tables[i].collation + ' | \
+ ' + rdata.tables[i].rows_count + ' | \
+ ' + rdata.tables[i].data_size + ' | \
+ \
+ 修复 |\
+ 优化 |\
+ 转为' + types[rdata.tables[i].type] + '\
+ | \
+
'
+ }
+
+ if (res) {
+ $(".gztr").html(tbody);
+ $("#db_tools").html('');
+ $("input[type='checkbox']").attr("checked", false);
+ $(".tools_size").html('大小:' + rdata.data_size);
+ return;
+ }
+
+ layer.open({
+ type: 1,
+ title: "MySQL工具箱【" + db_name + "】",
+ area: ['780px', '580px'],
+ closeBtn: 2,
+ shadeClose: false,
+ content: '\
+
\
+
\
+
\
+ - 【修复】尝试使用REPAIR命令修复损坏的表,仅能做简单修复,若修复不成功请考虑使用myisamchk工具
\
+ - 【优化】执行OPTIMIZE命令,可回收未释放的磁盘空间,建议每月执行一次
\
+ - 【转为InnoDB/MyISAM】转换数据表引擎,建议将所有表转为InnoDB
\
+
'
+ });
+ tableFixed('database_fix');
+ });
+}
+
+
+function setDbMaster(name){
+ myPost('set_db_master', {name:name}, function(data){
+ var rdata = $.parseJSON(data.data);
+ layer.msg(rdata.msg, { icon: rdata.status ? 1 : 5 });
+ setTimeout(function(){
+ masterOrSlaveConf();
+ }, 2000);
+ });
+}
+
+
+function setDbSlave(name){
+ myPost('set_db_slave', {name:name}, function(data){
+ var rdata = $.parseJSON(data.data);
+ layer.msg(rdata.msg, { icon: rdata.status ? 1 : 5 });
+ setTimeout(function(){
+ masterOrSlaveConf();
+ }, 2000);
+ });
+}
+
+
+function addMasterRepSlaveUser(){
+ layer.open({
+ type: 1,
+ area: '500px',
+ title: '添加同步账户',
+ closeBtn: 1,
+ shift: 5,
+ shadeClose: true,
+ btn:["提交","取消"],
+ content: "",
+ success:function(){
+ $("input[name='name']").keyup(function(){
+ var v = $(this).val();
+ $("input[name='db_user']").val(v);
+ $("input[name='ps']").val(v);
+ });
+
+ $('select[name="dataAccess"]').change(function(){
+ var v = $(this).val();
+ if (v == 'ip'){
+ $(this).after("");
+ } else {
+ $('#dataAccess_subid').remove();
+ }
+ });
+ },
+ yes:function(index){
+ var data = $("#add_master").serialize();
+ data = decodeURIComponent(data);
+ var dataObj = str2Obj(data);
+ if(!dataObj['address']){
+ dataObj['address'] = dataObj['dataAccess'];
+ }
+
+ myPost('add_master_rep_slave_user', dataObj, function(data){
+ var rdata = $.parseJSON(data.data);
+ showMsg(rdata.msg,function(){
+ layer.close(index);
+ if (rdata.status){
+ getMasterRepSlaveList();
+ }
+ },{icon: rdata.status ? 1 : 2},600);
+ });
+ }
+ });
+}
+
+
+
+function updateMasterRepSlaveUser(username){
+
+ var index = layer.open({
+ type: 1,
+ area: '500px',
+ title: '更新账户',
+ closeBtn: 1,
+ shift: 5,
+ shadeClose: true,
+ content: "",
+ });
+
+ $('#submit_update_master').click(function(){
+ var data = $("#update_master").serialize();
+ data = decodeURIComponent(data);
+ var dataObj = str2Obj(data);
+ myPost('update_master_rep_slave_user', data, function(data){
+ var rdata = $.parseJSON(data.data);
+ showMsg(rdata.msg,function(){
+ if (rdata.status){
+ getMasterRepSlaveList();
+ }
+ $('.layui-layer-close1').click();
+ },{icon: rdata.status ? 1 : 2},600);
+ });
+ });
+}
+
+function getMasterRepSlaveUserCmd(username, db=''){
+ myPost('get_master_rep_slave_user_cmd', {username:username,db:db}, function(data){
+ var rdata = $.parseJSON(data.data);
+
+ if (!rdata['status']){
+ layer.msg(rdata['msg']);
+ return;
+ }
+
+ var cmd = rdata.data['cmd'];
+
+ var loadOpen = layer.open({
+ type: 1,
+ title: '同步命令',
+ area: '500px',
+ content:"",
+ });
+
+
+ copyPass(cmd);
+ $('.class-copy-cmd').click(function(){
+ copyPass(cmd);
+ });
+ });
+}
+
+function delMasterRepSlaveUser(username){
+ myPost('del_master_rep_slave_user', {username:username}, function(data){
+ var rdata = $.parseJSON(data.data);
+ layer.msg(rdata.msg);
+
+ $('.layui-layer-close1').click();
+
+ setTimeout(function(){
+ getMasterRepSlaveList();
+ },1000);
+ });
+}
+
+
+function setDbMasterAccess(username){
+ myPost('get_db_access','username='+username, function(data){
+ var rdata = $.parseJSON(data.data);
+ if (!rdata.status){
+ layer.msg(rdata.msg,{icon:2,shade: [0.3, '#000']});
+ return;
+ }
+
+ var index = layer.open({
+ type: 1,
+ area: '500px',
+ title: '设置数据库权限',
+ closeBtn: 1,
+ shift: 5,
+ btn:["提交","取消"],
+ shadeClose: true,
+ content: "",
+ success:function(){
+ if (rdata.msg == '127.0.0.1'){
+ $('select[name="dataAccess"]').find("option[value='127.0.0.1']").attr("selected",true);
+ } else if (rdata.msg == '%'){
+ $('select[name="dataAccess"]').find('option[value="%"]').attr("selected",true);
+ } else if ( rdata.msg == 'ip' ){
+ $('select[name="dataAccess"]').find('option[value="ip"]').attr("selected",true);
+ $('select[name="dataAccess"]').after("");
+ } else {
+ $('select[name="dataAccess"]').find('option[value="ip"]').attr("selected",true);
+ $('select[name="dataAccess"]').after("");
+ }
+
+ $('select[name="dataAccess"]').change(function(){
+ var v = $(this).val();
+ if (v == 'ip'){
+ $(this).after("");
+ } else {
+ $('#dataAccess_subid').remove();
+ }
+ });
+ },
+ yes:function(index){
+ var data = $("#set_db_access").serialize();
+ data = decodeURIComponent(data);
+ var dataObj = str2Obj(data);
+ if(!dataObj['access']){
+ dataObj['access'] = dataObj['dataAccess'];
+ if ( dataObj['dataAccess'] == 'ip'){
+ if (dataObj['address']==''){
+ layer.msg('IP地址不能空!',{icon:2,shade: [0.3, '#000']});
+ return;
+ }
+ dataObj['access'] = dataObj['address'];
+ }
+ }
+ dataObj['username'] = username;
+ myPost('set_dbmaster_access', dataObj, function(data){
+ var rdata = $.parseJSON(data.data);
+ showMsg(rdata.msg,function(){
+ layer.close(index);
+ },{icon: rdata.status ? 1 : 2});
+ });
+ }
+ });
+
+ });
+}
+
+function getMasterRepSlaveList(){
+ var _data = {};
+ if (typeof(page) =='undefined'){
+ var page = 1;
+ }
+
+ _data['page'] = page;
+ _data['page_size'] = 10;
+ myPost('get_master_rep_slave_list', _data, function(data){
+ // console.log(data);
+ var rdata = [];
+ try {
+ rdata = $.parseJSON(data.data);
+ } catch(e){
+ console.log(e);
+ }
+ var list = '';
+ // console.log(rdata['data']);
+ var user_list = rdata['data'];
+ for (i in user_list) {
+ // console.log(i);
+ var name = user_list[i]['username'];
+ list += ''+name+' | \
+ '+user_list[i]['password']+' | \
+ \
+ 修改 | \
+ 删除 | \
+ 权限 | \
+ 从库同步命令\
+ | \
+
';
+ }
+
+ $('#get_master_rep_slave_list_page tbody').html(list);
+ $('.dataTables_paginate_4').html(rdata['page']);
+ });
+}
+
+function getMasterRepSlaveListPage(){
+ var page = '';
+ page += '添加同步账户
';
+
+ var loadOpen = layer.open({
+ type: 1,
+ title: '同步账户列表',
+ area: '500px',
+ content:"",
+ success:function(){
+ getMasterRepSlaveList();
+ }
+ });
+}
+
+
+function deleteSlave(){
+ myPost('delete_slave', {}, function(data){
+ var rdata = $.parseJSON(data.data);
+ showMsg(rdata['msg'], function(){
+ masterOrSlaveConf();
+ },{},3000);
+ });
+}
+
+
+function getFullSyncStatus(db){
+ var timeId = null;
+
+ var btn = '开始
';
+ var loadOpen = layer.open({
+ type: 1,
+ title: '全量同步['+db+']',
+ area: '500px',
+ content:"",
+ cancel: function(){
+ clearInterval(timeId);
+ }
+ });
+
+ function fullSync(db,begin){
+
+ myPostN('full_sync', {db:db,begin:begin}, function(data){
+ var rdata = $.parseJSON(data.data);
+ $('#full_msg').text(rdata['msg']);
+ $('.progress-bar').css('width',rdata['progress']+'%');
+ $('.progress-bar').text(rdata['progress']+'%');
+
+ if (rdata['code']==6 ||rdata['code']<0){
+ layer.msg(rdata['msg']);
+ clearInterval(timeId);
+ $("#begin_full_sync").attr('data-status','init');
+ }
+ });
+ }
+
+ $('#begin_full_sync').click(function(){
+ var val = $(this).attr('data-status');
+ if (val == 'init'){
+ fullSync(db,1);
+ timeId = setInterval(function(){
+ fullSync(db,0);
+ }, 1000);
+ $(this).attr('data-status','starting');
+ } else {
+ layer.msg("正在同步中..");
+ }
+ });
+}
+
+function addSlaveSSH(ip=''){
+
+ myPost('get_slave_ssh_by_ip', {ip:ip}, function(rdata){
+
+ var rdata = $.parseJSON(rdata.data);
+
+ var ip = '127.0.0.1';
+ var port = "22";
+ var id_rsa = '';
+ var db_user ='';
+
+ if (rdata.data.length>0){
+ ip = rdata.data[0]['ip'];
+ port = rdata.data[0]['port'];
+ id_rsa = rdata.data[0]['id_rsa'];
+ db_user = rdata.data[0]['db_user'];
+ }
+
+ var index = layer.open({
+ type: 1,
+ area: ['500px','480px'],
+ title: '添加SSH',
+ closeBtn: 1,
+ shift: 5,
+ shadeClose: true,
+ btn:["确认","取消"],
+ content: "",
+ success:function(){
+ $('textarea[name="id_rsa"]').html(id_rsa);
+ },
+ yes:function(index){
+ var ip = $('input[name="ip"]').val();
+ var port = $('input[name="port"]').val();
+ var db_user = $('input[name="db_user"]').val();
+ var id_rsa = $('textarea[name="id_rsa"]').val();
+
+ var data = {ip:ip,port:port,id_rsa:id_rsa,db_user:db_user};
+ myPost('add_slave_ssh', data, function(data){
+ layer.close(index);
+ var rdata = $.parseJSON(data.data);
+ showMsg(rdata.msg,function(){
+ if (rdata.status){
+ getSlaveSSHPage();
+ }
+ },{icon: rdata.status ? 1 : 2},600);
+ });
+ }
+ });
+ });
+}
+
+
+function delSlaveSSH(ip){
+ myPost('del_slave_ssh', {ip:ip}, function(rdata){
+ var rdata = $.parseJSON(rdata.data);
+ layer.msg(rdata.msg, {icon: rdata.status ? 1 : 2});
+ getSlaveSSHPage();
+ });
+}
+
+function getSlaveSSHPage(page=1){
+ var _data = {};
+ _data['page'] = page;
+ _data['page_size'] = 5;
+ _data['tojs'] ='getSlaveSSHPage';
+ myPost('get_slave_ssh_list', _data, function(data){
+ var layerId = null;
+ var rdata = [];
+ try {
+ rdata = $.parseJSON(data.data);
+ } catch(e) {
+ console.log(e);
+ }
+ var list = '';
+ var ssh_list = rdata['data'];
+ for (i in ssh_list) {
+ var ip = ssh_list[i]['ip'];
+ var port = ssh_list[i]['port'];
+
+ var id_rsa = '未设置';
+ if ( ssh_list[i]['port'] != ''){
+ id_rsa = '已设置';
+ }
+
+ var db_user = '未设置';
+ if ( ssh_list[i]['db_user'] != ''){
+ db_user = ssh_list[i]['db_user'];
+ }
+
+ list += ''+ip+' | \
+ '+port+' | \
+ '+db_user+' | \
+ '+id_rsa+' | \
+ \
+ 修改 | \
+ 删除\
+ | \
+
';
+ }
+
+ $('.get-slave-ssh-list tbody').html(list);
+ $('.dataTables_paginate_4').html(rdata['page']);
+ });
+}
+
+
+function getSlaveSSHList(page=1){
+
+ var page = '';
+ page += '添加SSH
';
+
+ layerId = layer.open({
+ type: 1,
+ title: 'SSH列表',
+ area: '500px',
+ content:"",
+ success:function(){
+ getSlaveSSHPage(1);
+ }
+ });
+}
+
+function handlerRun(){
+ myPostN('get_slave_sync_cmd', {}, function(data){
+ var rdata = $.parseJSON(data.data);
+ var cmd = rdata['data'];
+ var loadOpen = layer.open({
+ type: 1,
+ title: '手动执行',
+ area: '500px',
+ content:"",
+ });
+ copyPass(cmd);
+ $('.class-copy-cmd').click(function(){
+ copyPass(cmd);
+ });
+ });
+}
+
+function initSlaveStatus(){
+ myPost('init_slave_status', '', function(data){
+ var rdata = $.parseJSON(data.data);
+ showMsg(rdata.msg,function(){
+ if (rdata.status){
+ masterOrSlaveConf();
+ }
+ },{icon:rdata.status?1:2},2000);
+ });
+}
+
+function masterOrSlaveConf(version=''){
+
+ function getMasterDbList(){
+ var _data = {};
+ if (typeof(page) =='undefined'){
+ var page = 1;
+ }
+
+ _data['page'] = page;
+ _data['page_size'] = 10;
+
+ myPost('get_masterdb_list', _data, function(data){
+ var rdata = $.parseJSON(data.data);
+ var list = '';
+ for(i in rdata.data){
+ list += '';
+ list += '' + rdata.data[i]['name'] +' | ';
+ list += '' + (rdata.data[i]['master']?'是':'否') +' | ';
+ list += '' +
+ ''+(rdata.data[i]['master']?'退出':'加入')+' | ' +
+ '同步命令' +
+ ' | ';
+ list += '
';
+ }
+
+ var con = '\
+
\
+
\
+
\
+ 同步账户列表\
+
\
+
';
+
+ $(".table_master_list").html(con);
+ $('#databasePage').html(rdata.page);
+ });
+ }
+
+ function getAsyncMasterDbList(){
+ var _data = {};
+ if (typeof(page) =='undefined'){
+ var page = 1;
+ }
+
+ _data['page'] = page;
+ _data['page_size'] = 10;
+
+ myPost('get_slave_list', _data, function(data){
+ var rdata = $.parseJSON(data.data);
+ var list = '';
+ for(i in rdata.data){
+
+ var v = rdata.data[i];
+ var status = "异常";
+ if (v['Slave_SQL_Running'] == 'Yes' && v['Slave_IO_Running'] == 'Yes'){
+ status = "正常";
+ }
+
+ list += '';
+ list += '' + rdata.data[i]['Master_Host'] +' | ';
+ list += '' + rdata.data[i]['Master_Port'] +' | ';
+ list += '' + rdata.data[i]['Master_User'] +' | ';
+ list += '' + rdata.data[i]['Master_Log_File'] +' | ';
+ list += '' + rdata.data[i]['Slave_IO_Running'] +' | ';
+ list += '' + rdata.data[i]['Slave_SQL_Running'] +' | ';
+ list += '' + status +' | ';
+ list += '' +
+ '删除' +
+ ' | ';
+ list += '
';
+ }
+
+ var con = '';
+
+ // \
+ // \
+ // 添加\
+ //
+ $(".table_slave_status_list").html(con);
+ });
+ }
+
+ function getAsyncDataList(){
+ var _data = {};
+ if (typeof(page) =='undefined'){
+ var page = 1;
+ }
+
+ _data['page'] = page;
+ _data['page_size'] = 10;
+ myPost('get_masterdb_list', _data, function(data){
+ var rdata = $.parseJSON(data.data);
+ var list = '';
+ for(i in rdata.data){
+ list += '';
+ list += '' + rdata.data[i]['name'] +' | ';
+ list += '' +
+ ''+(rdata.data[i]['slave']?'退出':'加入')+' | ' +
+ '同步' +
+ ' | ';
+ list += '
';
+ }
+
+ var con = '\
+
\
+
\
+
\
+ 手动命令\
+ 全量同步\
+
\
+
';
+
+ $(".table_slave_list").html(con);
+ $('#databasePage').html(rdata.page);
+ });
+ }
+
+
+
+ function getMasterStatus(){
+ myPost('get_master_status', '', function(data){
+ var rdata = $.parseJSON(data.data);
+ // console.log('mode:',rdata.data);
+ var rdata = rdata.data;
+ var limitCon = '\
+ \
+ 主从同步模式\
+ \
+ \
+
\
+
\
+ \
+ Master[主]配置\
+ \
+
\
+
\
+ \
+ \
+
\
+ \
+ \
+ Slave[从]配置\
+ \
+ \
+ \
+
\
+
\
+ \
+ \
+ \
+ \
+ ';
+ $(".soft-man-con").html(limitCon);
+
+ //设置主服务器配置
+ $(".btn-master").click(function () {
+ myPost('set_master_status', 'close=change', function(data){
+ var rdata = $.parseJSON(data.data);
+ layer.msg(rdata.msg, { icon: rdata.status ? 1 : 5 });
+ setTimeout(function(){
+ getMasterStatus();
+ }, 3000);
+ });
+ });
+
+ $(".btn-slave").click(function () {
+ myPost('set_slave_status', 'close=change', function(data){
+ var rdata = $.parseJSON(data.data);
+ layer.msg(rdata.msg, { icon: rdata.status ? 1 : 5 });
+ setTimeout(function(){
+ getMasterStatus();
+ }, 3000);
+ });
+ });
+
+ $('.db-mode').click(function(){
+ if ($(this).hasClass('btn-success')){
+ //no action
+ return;
+ }
+
+ var mode = 'classic';
+ if ($(this).hasClass('btn-gtid')){
+ mode = 'gtid';
+ }
+
+ layer.open({
+ type:1,
+ title:"MySQL主从模式切换",
+ shadeClose:false,
+ btnAlign: 'c',
+ btn: ['切换并重启', '切换不重启'],
+ yes: function(index, layero){
+ this.change(index,mode,"yes");
+
+ },
+ btn2: function(index, layero){
+ this.change(index,mode,"no");
+ return false;
+ },
+ change:function(index,mode,reload){
+ console.log(index,mode,reload);
+ myPost('set_dbrun_mode',{'mode':mode,'reload':reload},function(data){
+ layer.close(index);
+ var rdata = $.parseJSON(data.data);
+ showMsg(rdata.msg ,function(){
+ getMasterStatus();
+ },{ icon: rdata.status ? 1 : 5 });
+ });
+ }
+ });
+ });
+
+ if (rdata.status){
+ getMasterDbList();
+ }
+
+ if (rdata.slave_status){
+ getAsyncMasterDbList();
+ getAsyncDataList()
+ }
+ });
+ }
+ getMasterStatus();
+}
diff --git a/scripts/init.d/mw.tpl b/scripts/init.d/mw.tpl
index 1dfbc7984..7d660dc77 100755
--- a/scripts/init.d/mw.tpl
+++ b/scripts/init.d/mw.tpl
@@ -3,7 +3,7 @@
# description: MW Cloud Service
### BEGIN INIT INFO
-# Provides: bt
+# Provides: Midoks
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5