数据库调整

pull/109/head
midoks 6 years ago
parent 836acf6987
commit a9c458c607
  1. 4
      plugins/mysql/class/mysql.py
  2. 3
      plugins/mysql/index.html
  3. 112
      plugins/mysql/index.py
  4. 80
      plugins/mysql/js/database.html
  5. 141
      plugins/mysql/js/mysql.js

@ -33,6 +33,7 @@ class mysql:
self.__DB_PORT = int(re.search(rep, myconf).groups()[0]) self.__DB_PORT = int(re.search(rep, myconf).groups()[0])
except: except:
self.__DB_PORT = 3306 self.__DB_PORT = 3306
# print self.__DB_PASS
#self.__DB_PASS = public.M('config').where('id=?', (1,)).getField('mysql_root') #self.__DB_PASS = public.M('config').where('id=?', (1,)).getField('mysql_root')
try: try:
self.__DB_CONN = MySQLdb.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS, self.__DB_CONN = MySQLdb.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
@ -47,6 +48,9 @@ class mysql:
self.__DB_ERR = e self.__DB_ERR = e
return False return False
def setPwd(self, pwd):
self.__DB_PASS = pwd
def execute(self, sql): def execute(self, sql):
# 执行SQL语句返回受影响行 # 执行SQL语句返回受影响行
if not self.__Conn(): if not self.__Conn():

@ -4,6 +4,9 @@
<p class="bgw" onclick="pluginService('mysql');">服务</p> <p class="bgw" onclick="pluginService('mysql');">服务</p>
<p onclick="pluginInitD('mysql');">自启动</p> <p onclick="pluginInitD('mysql');">自启动</p>
<p onclick="pluginConfig('mysql');">配置文件</p> <p onclick="pluginConfig('mysql');">配置文件</p>
<p onclick="myPort();">端口</p>
<p onclick="runInfo();">当前状态</p>
<p onclick="pluginLogs('mysql','','show_log');">慢日志</p>
</div> </div>
<div class="bt-w-con pd15"> <div class="bt-w-con pd15">
<div class="soft-man-con"> <div class="soft-man-con">

@ -72,22 +72,26 @@ def contentReplace(content):
return content return content
def pSqliteDb(): def pSqliteDb(dbname='databases'):
file = getServerDir() + '/mysql.db' file = getServerDir() + '/mysql.db'
name = 'mysql' name = 'mysql'
if not os.path.exists(file): if not os.path.exists(file):
conn = public.M(name).dbPos(getServerDir(), name) conn = public.M(dbname).dbPos(getServerDir(), name)
csql = public.readFile(getPluginDir() + '/conf/mysql.sql') csql = public.readFile(getPluginDir() + '/conf/mysql.sql')
csql_list = csql.split(';') csql_list = csql.split(';')
for index in range(len(csql_list)): for index in range(len(csql_list)):
conn.execute(csql_list[index], ()) conn.execute(csql_list[index], ())
else: else:
conn = public.M(name).dbPos(getServerDir(), name) conn = public.M(dbname).dbPos(getServerDir(), name)
return conn return conn
def pMysqlDb(): def pMysqlDb():
return '' db = mysql.mysql()
db.__DB_CNF = getConf()
db.setPwd(pSqliteDb('config').where(
'id=?', (1,)).getField('mysql_root'))
return db
def initDreplace(): def initDreplace():
@ -127,7 +131,6 @@ def status():
def getDataDir(): def getDataDir():
file = getConf() file = getConf()
content = public.readFile(file) content = public.readFile(file)
rep = 'datadir\s*=\s*(.*)' rep = 'datadir\s*=\s*(.*)'
@ -135,33 +138,50 @@ def getDataDir():
return tmp.groups()[0].strip() return tmp.groups()[0].strip()
def getShowLogFile():
file = getConf()
content = public.readFile(file)
rep = 'slow-query-log-file\s*=\s*(.*)'
tmp = re.search(rep, content)
return tmp.groups()[0].strip()
def initMysqlData(): def initMysqlData():
datadir = getDataDir() datadir = getDataDir()
serverdir = getServerDir()
if not os.path.exists(datadir + '/mysql'): if not os.path.exists(datadir + '/mysql'):
serverdir = getServerDir()
cmd = 'cd ' + serverdir + ' && ./scripts/mysql_install_db --user=midoks --basedir=' + \ cmd = 'cd ' + serverdir + ' && ./scripts/mysql_install_db --user=midoks --basedir=' + \
serverdir + ' --ldata=' + datadir serverdir + ' --ldata=' + datadir
public.execShell(cmd) public.execShell(cmd)
return 0
return 1
def initMysqlPwd():
time.sleep(3)
pwd = public.getRandomString(16) serverdir = getServerDir()
cmd_pass = serverdir + '/bin/mysqladmin -uroot -p12345'
print cmd_pass pwd = public.getRandomString(16)
cmd_pass = serverdir + '/bin/mysqladmin -uroot password ' + pwd
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (pwd,))
public.execShell(cmd_pass)
return True return True
def myOp(method): def myOp(method):
import commands
init_file = initDreplace() init_file = initDreplace()
cmd = init_file + ' ' + method cmd = init_file + ' ' + method
if method == 'start': try:
initMysqlData() initData = initMysqlData()
subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True,
bufsize=4096, stderr=subprocess.PIPE) bufsize=4096, stderr=subprocess.PIPE)
if (initData == 0):
initMysqlPwd()
return 'ok' return 'ok'
else: except Exception as e:
data = public.execShell(cmd) return str(e)
if data[1] == '':
return 'ok'
return data[1]
def start(): def start():
@ -213,16 +233,54 @@ def initdUinstall():
return 'ok' return 'ok'
def runInfo(): def getMyPort():
db = mysql.mysql() file = getConf()
db.__DB_CNF = getConf() content = public.readFile(file)
data = db.query('show global status') rep = 'port\s*=\s*(.*)'
print data tmp = re.search(rep, content)
return 'ok' return tmp.groups()[0].strip()
def getShowLog(): def setMyPort():
return 'ok' args = getArgs()
if not 'port' in args:
return 'port missing'
port = args['port']
file = getConf()
content = public.readFile(file)
rep = "port\s*=\s*([0-9]+)\s*\n"
content = re.sub(rep, 'port = ' + port + '\n', content)
public.writeFile(file, content)
restart()
return public.returnJson(True, '编辑成功!')
def runInfo():
db = pMysqlDb()
data = db.query('show global status')
gets = ['Max_used_connections', 'Com_commit', 'Com_rollback', 'Questions', 'Innodb_buffer_pool_reads', 'Innodb_buffer_pool_read_requests', 'Key_reads', 'Key_read_requests', 'Key_writes', 'Key_write_requests', 'Qcache_hits', 'Qcache_inserts', 'Bytes_received', 'Bytes_sent', 'Aborted_clients', 'Aborted_connects',
'Created_tmp_disk_tables', 'Created_tmp_tables', 'Innodb_buffer_pool_pages_dirty', 'Opened_files', 'Open_tables', 'Opened_tables', 'Select_full_join', 'Select_range_check', 'Sort_merge_passes', 'Table_locks_waited', 'Threads_cached', 'Threads_connected', 'Threads_created', 'Threads_running', 'Connections', 'Uptime']
try:
if data[0] == 1045:
return public.returnJson(False, 'MySQL密码错误!')
except:
pass
result = {}
for d in data:
for g in gets:
if d[0] == g:
result[g] = d[1]
result['Run'] = int(time.time()) - int(result['Uptime'])
tmp = db.query('show master status')
try:
result['File'] = tmp[0][0]
result['Position'] = tmp[0][1]
except:
result['File'] = 'OFF'
result['Position'] = 'OFF'
return public.getJson(result)
if __name__ == "__main__": if __name__ == "__main__":
func = sys.argv[1] func = sys.argv[1]
@ -247,6 +305,10 @@ if __name__ == "__main__":
elif func == 'conf': elif func == 'conf':
print getConf() print getConf()
elif func == 'show_log': elif func == 'show_log':
print getShowLog() print getShowLogFile()
elif func == 'my_port':
print getMyPort()
elif func == 'set_my_port':
print setMyPort()
else: else:
print 'error' print 'error'

@ -1,80 +0,0 @@
{% extends "default/layout.html" %}
{% block content %}
<div class="main-content pb55">
<div class="container-fluid">
<div class="pos-box bgw mtb15">
<div class="position f14 c9 pull-left">
<a class="plr10 c4" href="/">首页</a>/<span class="plr10 c4">数据库管理</span>
</div>
<div class="search pull-right">
<form target="hid" onsubmit='getData(1,$$("#SearchValue").prop("value"))'>
<input type="text" id="SearchValue" class="ser-text pull-left" placeholder="搜索数据库" />
<button type="button" class="ser-sub pull-left" onclick='getData(1,$$("#SearchValue").prop("value"))'></button>
</form>
<iframe name='hid' id="hid" style="display:none"></iframe>
</div>
</div>
<div class="safe bgw mtb15 pd15">
<button onclick="DataAdd(0)" title="添加数据库" class="btn btn-success btn-sm" type="button" style="margin-right: 5px;">添加数据库</button>
<button onclick="DataSetuppwd(0)" title="$tData['lan']['BTNT2']" class="btn btn-default btn-sm" type="button" style="margin-right: 5px;">root密码</button>
<button onclick="AdminDatabase('','root','$tData['mysql_root']')" title="$tData['lan']['BTNT3']" class="btn btn-default btn-sm" type="button" style="margin-right: 5px;">phpMyAdmin</button>
<span style="float:right">
<button id="allDelete" style="float: right;display: none;margin-left:10px;" onclick="allDeleteDatabase();" title="$tData['lan']['BTNT4']" class="btn btn-default btn-sm">$tData['lan']['BTN4']</button>
<button onclick="Recycle_bin('open');" id="dataRecycle" title="$tData['lan']['BTNT4']" class="btn btn-default btn-sm" style="margin-left: 5px;"><span class="glyphicon glyphicon-trash" style="margin-right: 5px;"></span>回收站</button>
</span>
<div class="divtable mtb10">
<div class="tablescroll">
<table class="table table-hover" style="min-width: 900px;border: 0 none;">
<thead>
<tr>
<th width='30px'><input onclick="checkSelect();" type="checkbox" id="setBox"></th>
<th onclick="listOrder('name','database',this)" style="cursor: pointer;">数据库名<span class="glyphicon glyphicon-triangle-top" style="margin-left:5px;color:#bbb"></span></th>
<th onclick="listOrder('name','database',this)" style="cursor: pointer;">用户名<span class="glyphicon glyphicon-triangle-top" style="margin-left:5px;color:#bbb"></span></th>
<th>密码</th>
<th width="140">备份</th>
<th>备注</th>
<th width="260" class="text-right">操作</th>
</tr>
</thead>
<tbody id="DataBody"></tbody>
</table>
</div>
<div class="dataTables_paginate paging_bootstrap pagination">
<span class="sync btn btn-default btn-sm" style="margin-right:5px" onclick="SyncToDatabases(1)" title="$tData['lan']['TP1']">同步选中</span>
<span class="sync btn btn-default btn-sm" style="margin-right:5px" onclick="SyncToDatabases(0)" title="$tData['lan']['TP2']">同步所有</span>
<span class="sync btn btn-default btn-sm" onclick="SyncGetDatabases()" title="$tData['lan']['TP3']">从服务器获取</span>
<ul id="DataPage" class="page pull-right"></ul>
</div>
</div>
</div>
<form id="toPHPMyAdmin" action="$web.ctx.session.phpmyadminDir/index.php" method="post" style="display: none;" target="_blank">
<input type="text" name="pma_username" id="pma_username" value="" />
<input type="password" name="pma_password" id="pma_password" value="" />
<input type="text" name="server" value="1" />
<input type="text" name="target" value="index.php" />
<input type="text" name="db" id="db" value="" />
</form>
</div>
</div>
</div>
<script type="text/javascript" src="/static/app/data.js?v={{config.version}}"></script>
<script type="text/javascript" src="/static/app/files.js?v={{config.version}}></script>
<script type="text/javascript">
// $if not tData['isSetup']:
// layer.msg('$tData["lan"]["JS1"]<a href="/soft#i" style="color:#20a53a;float: right;">$tData["lan"]["JS2"]</a>',{icon:7,shade: [0.3, '#000'],time:0});
// $(".layui-layer-shade").css("margin-left","180px");
setTimeout(function(){
getData(1);
},300);
$("#dataRecycle").click(function(){
setTimeout(function(){
Recycle_bin(6);
},1000);
// });
</script>
<script src="/static/app/upload.js?v={{config.version}}"></script>
{% endblock %}

@ -1,3 +1,96 @@
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){
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 });
$.post('/plugins/run', {name:'mysql', 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 runInfo(){
myPost('run_info','',function(data){
var rdata = $.parseJSON(data.data);
// console.log(rdata);
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 = '<div class="divtable"><table class="table table-hover table-bordered" style="width: 490px;margin-bottom:10px;background-color:#fafafa">\
<tbody>\
<tr><th>启动时间</th><td>' + getLocalTime(rdata.Run) + '</td><th></th><td>' + parseInt(rdata.Questions / rdata.Uptime) + '</td></tr>\
<tr><th>总连接次数</th><td>' + rdata.Connections + '</td><th></th><td>' + parseInt((parseInt(rdata.Com_commit) + parseInt(rdata.Com_rollback)) / rdata.Uptime) + '</td></tr>\
<tr><th>发送</th><td>' + toSize(rdata.Bytes_sent) + '</td><th>File</th><td>' + rdata.File + '</td></tr>\
<tr><th>接收</th><td>' + toSize(rdata.Bytes_received) + '</td><th>Position</th><td>' + rdata.Position + '</td></tr>\
</tbody>\
</table>\
<table class="table table-hover table-bordered" style="width: 490px;">\
<thead style="display:none;"><th></th><th></th><th></th><th></th></thead>\
<tbody>\
<tr><th>活动/峰值连接数</th><td>' + rdata.Threads_running + '/' + rdata.Max_used_connections + '</td><td colspan="2">,max_connections</td></tr>\
<tr><th>线程缓存命中率</th><td>' + ((1 - rdata.Threads_created / rdata.Connections) * 100).toFixed(2) + '%</td><td colspan="2">,thread_cache_size</td></tr>\
<tr><th>索引命中率</th><td>' + ((1 - rdata.Key_reads / rdata.Key_read_requests) * 100).toFixed(2) + '%</td><td colspan="2">,key_buffer_size</td></tr>\
<tr><th>Innodb索引命中率</th><td>' + ((1 - rdata.Innodb_buffer_pool_reads / rdata.Innodb_buffer_pool_read_requests) * 100).toFixed(2) + '%</td><td colspan="2">,innodb_buffer_pool_size</td></tr>\
<tr><th>查询缓存命中率</th><td>' + cache_size + '</td><td colspan="2">' + lan.soft.mysql_status_ps5 + '</td></tr>\
<tr><th>创建临时表到磁盘</th><td>' + ((rdata.Created_tmp_disk_tables / rdata.Created_tmp_tables) * 100).toFixed(2) + '%</td><td colspan="2">,tmp_table_size</td></tr>\
<tr><th>已打开的表</th><td>' + rdata.Open_tables + '</td><td colspan="2">,table_cache_size</td></tr>\
<tr><th>没有使用索引的量</th><td>' + rdata.Select_full_join + '</td><td colspan="2">0,</td></tr>\
<tr><th>没有索引的JOIN量</th><td>' + rdata.Select_range_check + '</td><td colspan="2">0,</td></tr>\
<tr><th>排序后的合并次数</th><td>' + rdata.Sort_merge_passes + '</td><td colspan="2">,sort_buffer_size</td></tr>\
<tr><th>锁表次数</th><td>' + rdata.Table_locks_waited + '</td><td colspan="2">,</td></tr>\
<tbody>\
</table></div>'
$(".soft-man-con").html(Con);
});
}
function myPort(){
myPost('my_port','',function(data){
var con = '<div class="line ">\
<div class="info-r ml0">\
<input name="port" class="bt-input-text mr5 port" type="text" style="width:100px" value="'+data.data+'">\
<button id="btn_change_port" name="btn_change_port" class="btn btn-success btn-sm mr5 ml5 btn_change_port">修改</button>\
</div></div>';
$(".soft-man-con").html(con);
$('#btn_change_port').click(function(){
var port = $("input[name='port']").val();
// console.log(port);
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 selectChange() { function selectChange() {
$("#SelectVersion,#selectVer").change(function() { $("#SelectVersion,#selectVer").change(function() {
var info = $(this).val(); var info = $(this).val();
@ -297,21 +390,7 @@ function changeMySQLDataPath(act) {
}); });
} }
//MySQL-Slow日志
function mysqlSlowLog() {
var loadT = layer.msg(lan.public.the, { icon: 16, time: 0, shade: [0.3, '#000'] });
$.post('/database?action=GetSlowLogs', {}, function(logs) {
layer.close(loadT);
if (logs.status !== true) {
logs.msg = '';
}
if (logs.msg == '') logs.msg = '当前没有慢日志.';
var phpCon = '<textarea readonly="" style="margin: 0px;width: 500px;height: 520px;background-color: #333;color:#fff; padding:0 5px" id="error_log">' + logs.msg + '</textarea>';
$(".soft-man-con").html(phpCon);
var ob = document.getElementById('error_log');
ob.scrollTop = ob.scrollHeight;
});
}
//数据库日志 //数据库日志
function mysqlLog(act) { function mysqlLog(act) {
@ -340,38 +419,6 @@ function mysqlLog(act) {
}); });
} }
//取数据库运行状态
function mysqlRunStatus() {
$.post('/database?action=GetRunStatus', "", function(rdata) {
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 = '<div class="divtable"><table class="table table-hover table-bordered" style="width: 490px;margin-bottom:10px;background-color:#fafafa">\
<tbody>\
<tr><th>' + lan.soft.mysql_status_title1 + '</th><td>' + getLocalTime(rdata.Run) + '</td><th>' + lan.soft.mysql_status_title5 + '</th><td>' + parseInt(rdata.Questions / rdata.Uptime) + '</td></tr>\
<tr><th>' + lan.soft.mysql_status_title2 + '</th><td>' + rdata.Connections + '</td><th>' + lan.soft.mysql_status_title6 + '</th><td>' + parseInt((parseInt(rdata.Com_commit) + parseInt(rdata.Com_rollback)) / rdata.Uptime) + '</td></tr>\
<tr><th>' + lan.soft.mysql_status_title3 + '</th><td>' + ToSize(rdata.Bytes_sent) + '</td><th>' + lan.soft.mysql_status_title7 + '</th><td>' + rdata.File + '</td></tr>\
<tr><th>' + lan.soft.mysql_status_title4 + '</th><td>' + ToSize(rdata.Bytes_received) + '</td><th>' + lan.soft.mysql_status_title8 + '</th><td>' + rdata.Position + '</td></tr>\
</tbody>\
</table>\
<table class="table table-hover table-bordered" style="width: 490px;">\
<thead style="display:none;"><th></th><th></th><th></th><th></th></thead>\
<tbody>\
<tr><th>' + lan.soft.mysql_status_title9 + '</th><td>' + rdata.Threads_running + '/' + rdata.Max_used_connections + '</td><td colspan="2">' + lan.soft.mysql_status_ps1 + '</td></tr>\
<tr><th>' + lan.soft.mysql_status_title10 + '</th><td>' + ((1 - rdata.Threads_created / rdata.Connections) * 100).toFixed(2) + '%</td><td colspan="2">' + lan.soft.mysql_status_ps2 + '</td></tr>\
<tr><th>' + lan.soft.mysql_status_title11 + '</th><td>' + ((1 - rdata.Key_reads / rdata.Key_read_requests) * 100).toFixed(2) + '%</td><td colspan="2">' + lan.soft.mysql_status_ps3 + '</td></tr>\
<tr><th>' + lan.soft.mysql_status_title12 + '</th><td>' + ((1 - rdata.Innodb_buffer_pool_reads / rdata.Innodb_buffer_pool_read_requests) * 100).toFixed(2) + '%</td><td colspan="2">' + lan.soft.mysql_status_ps4 + '</td></tr>\
<tr><th>' + lan.soft.mysql_status_title13 + '</th><td>' + cache_size + '</td><td colspan="2">' + lan.soft.mysql_status_ps5 + '</td></tr>\
<tr><th>' + lan.soft.mysql_status_title14 + '</th><td>' + ((rdata.Created_tmp_disk_tables / rdata.Created_tmp_tables) * 100).toFixed(2) + '%</td><td colspan="2">' + lan.soft.mysql_status_ps6 + '</td></tr>\
<tr><th>' + lan.soft.mysql_status_title15 + '</th><td>' + rdata.Open_tables + '</td><td colspan="2">' + lan.soft.mysql_status_ps7 + '</td></tr>\
<tr><th>' + lan.soft.mysql_status_title16 + '</th><td>' + rdata.Select_full_join + '</td><td colspan="2">' + lan.soft.mysql_status_ps8 + '</td></tr>\
<tr><th>' + lan.soft.mysql_status_title17 + '</th><td>' + rdata.Select_range_check + '</td><td colspan="2">' + lan.soft.mysql_status_ps9 + '</td></tr>\
<tr><th>' + lan.soft.mysql_status_title18 + '</th><td>' + rdata.Sort_merge_passes + '</td><td colspan="2">' + lan.soft.mysql_status_ps10 + '</td></tr>\
<tr><th>' + lan.soft.mysql_status_title19 + '</th><td>' + rdata.Table_locks_waited + '</td><td colspan="2">' + lan.soft.mysql_status_ps11 + '</td></tr>\
<tbody>\
</table></div>'
$(".soft-man-con").html(Con);
});
}
//数据库配置状态 //数据库配置状态
function mysqlStatus() { function mysqlStatus() {

Loading…
Cancel
Save