fix: 解决 mysql 8.0 性能调整失败的问题
This commit is contained in:
@@ -201,6 +201,16 @@ func (b *BaseApi) LoadBaseinfo(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, data)
|
helper.SuccessWithData(c, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *BaseApi) LoadRemoteAccess(c *gin.Context) {
|
||||||
|
isRemote, err := mysqlService.LoadRemoteAccess()
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
helper.SuccessWithData(c, isRemote)
|
||||||
|
}
|
||||||
|
|
||||||
func (b *BaseApi) LoadStatus(c *gin.Context) {
|
func (b *BaseApi) LoadStatus(c *gin.Context) {
|
||||||
data, err := mysqlService.LoadStatus()
|
data, err := mysqlService.LoadStatus()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -101,8 +101,6 @@ type DBBaseInfo struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
ContainerName string `json:"containerName"`
|
ContainerName string `json:"containerName"`
|
||||||
Port int64 `json:"port"`
|
Port int64 `json:"port"`
|
||||||
Password string `json:"password"`
|
|
||||||
RemoteConn bool `json:"remoteConn"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type SearchDBWithPage struct {
|
type SearchDBWithPage struct {
|
||||||
|
@@ -46,6 +46,7 @@ type IMysqlService interface {
|
|||||||
LoadStatus() (*dto.MysqlStatus, error)
|
LoadStatus() (*dto.MysqlStatus, error)
|
||||||
LoadVariables() (*dto.MysqlVariables, error)
|
LoadVariables() (*dto.MysqlVariables, error)
|
||||||
LoadBaseInfo() (*dto.DBBaseInfo, error)
|
LoadBaseInfo() (*dto.DBBaseInfo, error)
|
||||||
|
LoadRemoteAccess() (bool, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIMysqlService() IMysqlService {
|
func NewIMysqlService() IMysqlService {
|
||||||
@@ -266,6 +267,22 @@ func (u *MysqlService) Delete(id uint) error {
|
|||||||
if err := excuteSql(app.ContainerName, app.Password, fmt.Sprintf("drop database if exists %s", db.Name)); err != nil {
|
if err := excuteSql(app.ContainerName, app.Password, fmt.Sprintf("drop database if exists %s", db.Name)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uploadDir := fmt.Sprintf("%s/uploads/%s/mysql/%s", constant.DefaultDataDir, app.Name, db.Name)
|
||||||
|
if _, err := os.Stat(uploadDir); err == nil {
|
||||||
|
_ = os.RemoveAll(uploadDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
localDir, err := loadLocalDir()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
backupDir := fmt.Sprintf("%s/database/mysql/%s/%s", localDir, db.MysqlName, db.Name)
|
||||||
|
if _, err := os.Stat(backupDir); err == nil {
|
||||||
|
_ = os.RemoveAll(backupDir)
|
||||||
|
}
|
||||||
|
_ = backupRepo.DeleteRecord(commonRepo.WithByType("database-mysql"), commonRepo.WithByName(app.Name), backupRepo.WithByDetailName(db.Name))
|
||||||
|
|
||||||
_ = mysqlRepo.Delete(context.Background(), commonRepo.WithByID(db.ID))
|
_ = mysqlRepo.Delete(context.Background(), commonRepo.WithByID(db.ID))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -406,7 +423,13 @@ func (u *MysqlService) UpdateVariables(updatas []dto.MysqlVariablesUpdate) error
|
|||||||
}
|
}
|
||||||
group := "[mysqld]"
|
group := "[mysqld]"
|
||||||
for _, info := range updatas {
|
for _, info := range updatas {
|
||||||
files = updateMyCnf(files, group, info.Param, info.Value)
|
if app.Version != "5.7.39" {
|
||||||
|
if info.Param == "query_cache_size" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
files = updateMyCnf(files, group, info.Param, loadSizeUnit(info.Value))
|
||||||
}
|
}
|
||||||
file, err := os.OpenFile(path, os.O_WRONLY, 0666)
|
file, err := os.OpenFile(path, os.O_WRONLY, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -434,19 +457,26 @@ func (u *MysqlService) LoadBaseInfo() (*dto.DBBaseInfo, error) {
|
|||||||
data.ContainerName = app.ContainerName
|
data.ContainerName = app.ContainerName
|
||||||
data.Name = app.Name
|
data.Name = app.Name
|
||||||
data.Port = int64(app.Port)
|
data.Port = int64(app.Port)
|
||||||
data.Password = app.Password
|
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *MysqlService) LoadRemoteAccess() (bool, error) {
|
||||||
|
app, err := appInstallRepo.LoadBaseInfoByKey("mysql")
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
hosts, err := excuteSqlForRows(app.ContainerName, app.Password, "select host from mysql.user where user='root';")
|
hosts, err := excuteSqlForRows(app.ContainerName, app.Password, "select host from mysql.user where user='root';")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return false, err
|
||||||
}
|
}
|
||||||
for _, host := range hosts {
|
for _, host := range hosts {
|
||||||
if host == "%" {
|
if host == "%" {
|
||||||
data.RemoteConn = true
|
return true, nil
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &data, nil
|
|
||||||
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *MysqlService) LoadVariables() (*dto.MysqlVariables, error) {
|
func (u *MysqlService) LoadVariables() (*dto.MysqlVariables, error) {
|
||||||
@@ -633,3 +663,13 @@ func updateMyCnf(oldFiles []string, group string, param string, value interface{
|
|||||||
}
|
}
|
||||||
return newFiles
|
return newFiles
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadSizeUnit(value int64) string {
|
||||||
|
if value > 1048576 {
|
||||||
|
return fmt.Sprintf("%dM", value/1048576)
|
||||||
|
}
|
||||||
|
if value > 1024 {
|
||||||
|
return fmt.Sprintf("%dK", value/1024)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%d", value)
|
||||||
|
}
|
||||||
|
@@ -35,6 +35,7 @@ func (s *DatabaseRouter) InitDatabaseRouter(Router *gin.RouterGroup) {
|
|||||||
cmdRouter.GET("/variables", baseApi.LoadVariables)
|
cmdRouter.GET("/variables", baseApi.LoadVariables)
|
||||||
cmdRouter.GET("/status", baseApi.LoadStatus)
|
cmdRouter.GET("/status", baseApi.LoadStatus)
|
||||||
cmdRouter.GET("/baseinfo", baseApi.LoadBaseinfo)
|
cmdRouter.GET("/baseinfo", baseApi.LoadBaseinfo)
|
||||||
|
cmdRouter.GET("/remote", baseApi.LoadRemoteAccess)
|
||||||
cmdRouter.GET("/options", baseApi.ListDBName)
|
cmdRouter.GET("/options", baseApi.ListDBName)
|
||||||
|
|
||||||
cmdRouter.GET("/redis/persistence/conf", baseApi.LoadPersistenceConf)
|
cmdRouter.GET("/redis/persistence/conf", baseApi.LoadPersistenceConf)
|
||||||
|
@@ -47,6 +47,9 @@ export const loadMysqlVariables = () => {
|
|||||||
export const loadMysqlStatus = () => {
|
export const loadMysqlStatus = () => {
|
||||||
return http.get<Database.MysqlStatus>(`/databases/status`);
|
return http.get<Database.MysqlStatus>(`/databases/status`);
|
||||||
};
|
};
|
||||||
|
export const loadRemoteAccess = () => {
|
||||||
|
return http.get<boolean>(`/databases/remote`);
|
||||||
|
};
|
||||||
export const loadDBNames = () => {
|
export const loadDBNames = () => {
|
||||||
return http.get<Array<string>>(`/databases/options`);
|
return http.get<Array<string>>(`/databases/options`);
|
||||||
};
|
};
|
||||||
|
@@ -138,6 +138,7 @@ export default {
|
|||||||
error: '失败',
|
error: '失败',
|
||||||
created: '已创建',
|
created: '已创建',
|
||||||
restarting: '重启中',
|
restarting: '重启中',
|
||||||
|
unhealthy: '异常',
|
||||||
removing: '迁移中',
|
removing: '迁移中',
|
||||||
paused: '暂停',
|
paused: '暂停',
|
||||||
exited: '停止',
|
exited: '停止',
|
||||||
@@ -220,6 +221,8 @@ export default {
|
|||||||
database: {
|
database: {
|
||||||
create: '创建数据库',
|
create: '创建数据库',
|
||||||
noMysql: '当前未检测到 {0} 数据库,请进入应用商店点击安装!',
|
noMysql: '当前未检测到 {0} 数据库,请进入应用商店点击安装!',
|
||||||
|
mysqlBadStatus: '当前 mysql 应用状态异常,请在',
|
||||||
|
adjust: '中查看原因或修改配置',
|
||||||
goInstall: '去安装',
|
goInstall: '去安装',
|
||||||
source: '来源',
|
source: '来源',
|
||||||
backup: '备份',
|
backup: '备份',
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-loading="loading">
|
<div v-loading="loading">
|
||||||
<LayoutContent :header="'Compose-' + composeName" back-name="Compose" :reload="true">
|
<LayoutContent :header="composeName" back-name="Compose" :reload="true">
|
||||||
<div v-if="createdBy === 'local'">
|
<div v-if="createdBy === 'local'">
|
||||||
<el-button icon="VideoPlay" @click="onComposeOperate('start')">{{ $t('container.start') }}</el-button>
|
<el-button icon="VideoPlay" @click="onComposeOperate('start')">{{ $t('container.start') }}</el-button>
|
||||||
<el-button icon="VideoPause" @click="onComposeOperate('stop')">{{ $t('container.stop') }}</el-button>
|
<el-button icon="VideoPause" @click="onComposeOperate('stop')">{{ $t('container.stop') }}</el-button>
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
<el-card style="margin-top: 20px">
|
<el-card style="margin-top: 20px">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<span>Containers</span>
|
<span>{{ $t('container.container') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<ComplexTable
|
<ComplexTable
|
||||||
|
@@ -2,9 +2,16 @@
|
|||||||
<div>
|
<div>
|
||||||
<Submenu activeName="mysql" />
|
<Submenu activeName="mysql" />
|
||||||
<AppStatus :app-key="'mysql'" style="margin-top: 20px" @setting="onSetting" @is-exist="checkExist" />
|
<AppStatus :app-key="'mysql'" style="margin-top: 20px" @setting="onSetting" @is-exist="checkExist" />
|
||||||
<div v-if="mysqlIsExist">
|
<Setting ref="settingRef" style="margin-top: 20px" />
|
||||||
<Setting ref="settingRef" style="margin-top: 20px" />
|
|
||||||
|
|
||||||
|
<el-card width="30%" v-if="mysqlStatus != 'Running' && !isOnSetting" class="mask-prompt">
|
||||||
|
<span style="font-size: 14px">{{ $t('database.mysqlBadStatus') }}</span>
|
||||||
|
<el-button type="primary" link style="font-size: 14px; margin-bottom: 5px" @click="onSetting">
|
||||||
|
【 {{ $t('database.setting') }} 】
|
||||||
|
</el-button>
|
||||||
|
<span style="font-size: 14px">{{ $t('database.adjust') }}</span>
|
||||||
|
</el-card>
|
||||||
|
<div v-if="mysqlIsExist" :class="{ mask: mysqlStatus != 'Running' }">
|
||||||
<el-card v-if="!isOnSetting" style="margin-top: 20px">
|
<el-card v-if="!isOnSetting" style="margin-top: 20px">
|
||||||
<ComplexTable
|
<ComplexTable
|
||||||
:pagination-config="paginationConfig"
|
:pagination-config="paginationConfig"
|
||||||
@@ -172,7 +179,7 @@ import { reactive, ref } from 'vue';
|
|||||||
import {
|
import {
|
||||||
deleteCheckMysqlDB,
|
deleteCheckMysqlDB,
|
||||||
deleteMysqlDB,
|
deleteMysqlDB,
|
||||||
loadMysqlBaseInfo,
|
loadRemoteAccess,
|
||||||
searchMysqlDBs,
|
searchMysqlDBs,
|
||||||
updateMysqlAccess,
|
updateMysqlAccess,
|
||||||
updateMysqlPassword,
|
updateMysqlPassword,
|
||||||
@@ -203,6 +210,8 @@ const paginationConfig = reactive({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const mysqlIsExist = ref(false);
|
const mysqlIsExist = ref(false);
|
||||||
|
const mysqlContainer = ref();
|
||||||
|
const mysqlStatus = ref();
|
||||||
|
|
||||||
const dialogRef = ref();
|
const dialogRef = ref();
|
||||||
const onOpenDialog = async () => {
|
const onOpenDialog = async () => {
|
||||||
@@ -230,9 +239,9 @@ const onChangeRootPassword = async () => {
|
|||||||
|
|
||||||
const remoteAccessRef = ref();
|
const remoteAccessRef = ref();
|
||||||
const onChangeAccess = async () => {
|
const onChangeAccess = async () => {
|
||||||
const res = await loadMysqlBaseInfo();
|
const res = await loadRemoteAccess();
|
||||||
let param = {
|
let param = {
|
||||||
privilege: res.data.remoteConn,
|
privilege: res.data,
|
||||||
};
|
};
|
||||||
remoteAccessRef.value!.acceptParams(param);
|
remoteAccessRef.value!.acceptParams(param);
|
||||||
};
|
};
|
||||||
@@ -241,6 +250,7 @@ const settingRef = ref();
|
|||||||
const onSetting = async () => {
|
const onSetting = async () => {
|
||||||
isOnSetting.value = true;
|
isOnSetting.value = true;
|
||||||
let params = {
|
let params = {
|
||||||
|
status: mysqlStatus.value,
|
||||||
mysqlName: mysqlName.value,
|
mysqlName: mysqlName.value,
|
||||||
};
|
};
|
||||||
settingRef.value!.acceptParams(params);
|
settingRef.value!.acceptParams(params);
|
||||||
@@ -316,6 +326,8 @@ const loadDashboardPort = async () => {
|
|||||||
const checkExist = (data: App.CheckInstalled) => {
|
const checkExist = (data: App.CheckInstalled) => {
|
||||||
mysqlIsExist.value = data.isExist;
|
mysqlIsExist.value = data.isExist;
|
||||||
mysqlName.value = data.name;
|
mysqlName.value = data.name;
|
||||||
|
mysqlStatus.value = data.status;
|
||||||
|
mysqlContainer.value = data.containerName;
|
||||||
if (mysqlIsExist.value) {
|
if (mysqlIsExist.value) {
|
||||||
search();
|
search();
|
||||||
loadDashboardPort();
|
loadDashboardPort();
|
||||||
|
@@ -37,7 +37,7 @@ const loading = ref(false);
|
|||||||
|
|
||||||
const dialogVisiable = ref(false);
|
const dialogVisiable = ref(false);
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
privilege: '',
|
privilege: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const confirmDialogRef = ref();
|
const confirmDialogRef = ref();
|
||||||
@@ -46,7 +46,7 @@ type FormInstance = InstanceType<typeof ElForm>;
|
|||||||
const formRef = ref<FormInstance>();
|
const formRef = ref<FormInstance>();
|
||||||
|
|
||||||
interface DialogProps {
|
interface DialogProps {
|
||||||
privilege: string;
|
privilege: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const acceptParams = (prop: DialogProps): void => {
|
const acceptParams = (prop: DialogProps): void => {
|
||||||
|
@@ -101,19 +101,24 @@ const slowLogRef = ref();
|
|||||||
|
|
||||||
const onSetting = ref<boolean>(false);
|
const onSetting = ref<boolean>(false);
|
||||||
const mysqlName = ref();
|
const mysqlName = ref();
|
||||||
|
const mysqlStatus = ref();
|
||||||
const variables = ref();
|
const variables = ref();
|
||||||
|
|
||||||
interface DialogProps {
|
interface DialogProps {
|
||||||
mysqlName: string;
|
mysqlName: string;
|
||||||
|
status: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dialogContainerLogRef = ref();
|
const dialogContainerLogRef = ref();
|
||||||
const acceptParams = (params: DialogProps): void => {
|
const acceptParams = (props: DialogProps): void => {
|
||||||
onSetting.value = true;
|
onSetting.value = true;
|
||||||
|
mysqlStatus.value = props.status;
|
||||||
loadBaseInfo();
|
loadBaseInfo();
|
||||||
loadVariables();
|
if (mysqlStatus.value === 'Running') {
|
||||||
loadSlowLogs();
|
loadVariables();
|
||||||
statusRef.value!.acceptParams({ mysqlName: params.mysqlName });
|
loadSlowLogs();
|
||||||
|
statusRef.value!.acceptParams({ mysqlName: props.mysqlName });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
const onClose = (): void => {
|
const onClose = (): void => {
|
||||||
onSetting.value = false;
|
onSetting.value = false;
|
||||||
@@ -191,12 +196,9 @@ const loadContainerLog = async (containerID: string) => {
|
|||||||
const loadBaseInfo = async () => {
|
const loadBaseInfo = async () => {
|
||||||
const res = await loadMysqlBaseInfo();
|
const res = await loadMysqlBaseInfo();
|
||||||
mysqlName.value = res.data?.name;
|
mysqlName.value = res.data?.name;
|
||||||
baseInfo.name = res.data?.name;
|
|
||||||
baseInfo.port = res.data?.port;
|
baseInfo.port = res.data?.port;
|
||||||
baseInfo.password = res.data?.password;
|
|
||||||
baseInfo.remoteConn = res.data?.remoteConn;
|
|
||||||
baseInfo.containerID = res.data?.containerName;
|
baseInfo.containerID = res.data?.containerName;
|
||||||
loadMysqlConf(`/opt/1Panel/data/apps/mysql/${baseInfo.name}/conf/my.cnf`);
|
loadMysqlConf(`/opt/1Panel/data/apps/mysql/${mysqlName.value}/conf/my.cnf`);
|
||||||
loadContainerLog(baseInfo.containerID);
|
loadContainerLog(baseInfo.containerID);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user