C# mysqlcheck 检查数据库异常+修复数据库

断电等不可预期的错误导致数据库表不能使用。。。所以在网上找了一下有什么可以修复户数据库的。

1.SQL语句。

2.MYSQL自带的mysqlcheck工具。

虽然有了介绍但是 并不知道如何使用。

大家都是直接贴代码,但是对于没有经验的人来说都不知道是从哪里执行这几行代码。。。为此我也是飞了好多时间。

下面来介绍如何使用这个语句

至于解释 随便搜一下 满地都是 关键词 mysqlcheck


1.sql语句修复

数据库还能执行sql语句时可以尝试

check table my_table;
repair table mytable;

check tables my_table1,my_table2;
这个是可以看到返回的

但是只支持MyISAM格式的数据库表

可以这样更换一下类型 或者所以下其他方式

alter table `cashier_goods` engine  = MyISAM; 




2.第二种 就是调用 mysql 中bin目录下的mysqlcheck来

我这里给出C#代码  我的数据库名为supercashier 可以根据自己的需要来改

大致步骤是

1.确定mysql的bin位置

2.调用cmd执行命令并输出日志

代码也可自己根据需要调整(给出的例子是 检测数据库是否异常 异常则尝试修复一次,没有异常直接退出)

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

namespace FixMySQL
{
    class Program
    {
        static void Main(string[] args)
        {
            bool checkresult = MethodC();//数据库检测
            Console.WriteLine(checkresult ? "数据库正常" : "数据库损坏");
            if (checkresult)
            {
                return;
            }
            Console.WriteLine("\r\n 是否需要进行尝试修复!");
            Console.WriteLine("尝试修复请输入 y 并点击回车");
            string isneedrepair = Console.ReadLine();
            if (isneedrepair.ToUpper() == "Y")
            {
                MethodA();//修复并输出日志
            }
            Console.WriteLine("尝试修复后仍不能正常使用,请毫不犹豫联系我们!\r\n");
            Console.WriteLine("按任意键退出!");
            Console.ReadLine();
        }

        private static bool MethodC()
        {
            //数据库路径
            var mySQLPath = Process.GetProcessesByName("mysqld");
            try
            {
                string sqlpath = mySQLPath[0].MainModule.FileName;
                //Console.WriteLine(mySQLPath[0].MainModule.FileName);
            }
            catch (Exception)
            {
                Console.WriteLine("未检测到数据库,或数据库没有开启!");
                Console.WriteLine("按任意键退出! \r\n");
                Console.ReadLine();
                return false;
            }
            string path = System.IO.Path.GetDirectoryName(mySQLPath[0].MainModule.FileName);
            //桌面路径
            string DeskTopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
            DeskTopPath += @"\超级支付数据库自动修复" + DateTime.Now.ToString("yyyyMMddhhmmss");
            if (!System.IO.Directory.Exists(DeskTopPath))
            {
                System.IO.Directory.CreateDirectory(DeskTopPath);
            }
            string B = "mysqlcheck -c --databases supercashier -uroot";//检查库或表
            Directory.SetCurrentDirectory(path);
            string result = ExecuteCommand(B);
            //string[] anaylize = System.Text.RegularExpressions.Regex.Split(result, "\r\n");
            string[] anaylize = result.Replace("\r\n", "|").TrimEnd('|').Split('|');

            foreach (var item in anaylize)
            {
                if (!string.IsNullOrEmpty(item) && !item.Contains("OK"))
                {
                    return false;
                }
            }
            return true;
        }
        private static void MethodA()
        {
            //数据库路径
            var mySQLPath = Process.GetProcessesByName("mysqld");
            try
            {
                string sqlpath = mySQLPath[0].MainModule.FileName;
                //Console.WriteLine(mySQLPath[0].MainModule.FileName);
            }
            catch (Exception)
            {
                Console.WriteLine("未检测到数据库,或数据库没有开启!");
                Console.WriteLine("按任意键退出! \r\n");
                Console.ReadLine();
                return;
            }
            string path = System.IO.Path.GetDirectoryName(mySQLPath[0].MainModule.FileName);
            //桌面路径
            string DeskTopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
            DeskTopPath += @"\超级支付数据库自动修复" + DateTime.Now.ToString("yyyyMMddhhmmss");
            if (!System.IO.Directory.Exists(DeskTopPath))
            {
                System.IO.Directory.CreateDirectory(DeskTopPath);
            }
            Console.WriteLine("输出路径" + DeskTopPath);
            Console.WriteLine("请在桌面输出路径中查看修复日志文件");
            //创建bat 使得修复代码可视化
            StringBuilder batstr = new StringBuilder();
            batstr.Append("数据库分析日志说明:\r\n");
            batstr.Append("OK\r\n");
            batstr.Append("表示数据库表正常\r\n");
            batstr.Append("Table is already up to date\r\n");
            batstr.Append("表示数据库表已经是最新的 \r\n\r\n");

            batstr.Append("数据库检查日志说明:\r\n");
            batstr.Append("OK\r\n");
            batstr.Append("表示数据库表正常\r\n");
            batstr.Append("broken\r\n");
            batstr.Append("表示数据库表损坏\r\n\r\n");

            batstr.Append("数据库修复日志说明:\r\n");
            batstr.Append("OK \r\n");
            batstr.Append("表示数据库表修复成功\r\n");
            batstr.Append("The storage engine for the table doesn't support repair\r\n");
            batstr.Append("表示数据库表类型不支持修复\r\n\r\n");

            batstr.Append("数据库优化日志说明:\r\n");
            batstr.Append("OK\r\n");
            batstr.Append("表示数据库表优化成功\r\n");
            batstr.Append("Table does not support optimize, doing recreate + analyze instead \r\n");
            batstr.Append("表不支持优化,而是重新创建+分析\r\n");
            batstr.Append("尝试修复后仍不能正常使用,请毫不犹豫联系我们!\r\n");
            System.IO.File.WriteAllText(DeskTopPath + @"\日志阅读说明.txt", batstr.ToString());

            string A = "mysqlcheck -a --databases supercashier -uroot>" + DeskTopPath + @"\数据库分析日志.txt" + " \r\n";//分析指定的表 所有数据库
            string B = "mysqlcheck -c --databases supercashier -uroot>" + DeskTopPath + @"\数据库表检查日志.txt" + " \r\n";//检查库或表
            string C = "mysqlcheck -r --databases supercashier -uroot>" + DeskTopPath + @"\数据库表修复日志.txt" + " \r\n";//修复库或表
            string D = "mysqlcheck -o --databases supercashier -uroot>" + DeskTopPath + @"\数据库表优化日志.txt" + " \r\n";//优化指定的表
            //string E = "mysqlcheck --auto-repair  --databases supercashier -uroot>" + DeskTopPath + @"\ssss.txt" + " \r\n";
            //string E = "mysqlcheck --auto-repair  --databases supercashier -uroot>" + DeskTopPath + @"\ssss.txt" + " \r\n";
            // --repair--quick 尝试快速修复
            //--repair 正常修复(除非快速修复失败)
            //--repair--force 强行修复
            Directory.SetCurrentDirectory(path);
            Console.WriteLine("1.正在进行全局分析...");
            ExecuteCommand(A);
            Console.WriteLine("全局分析完成! \r\n");
            Console.WriteLine("2.正在进行检查...");
            ExecuteCommand(B);
            Console.WriteLine("检查完成! \r\n");
            Console.WriteLine("3.正在进行修复...");
            ExecuteCommand(C);
            Console.WriteLine("修复完成! \r\n");
            Console.WriteLine("4.正在进行优化...");
            Console.WriteLine("优化过程所需时间较长请耐心等待! \r\n");
            ExecuteCommand(D);
            Console.WriteLine("优化完成! \r\n");
            Console.WriteLine("按任意键退出! \r\n");
            Console.ReadLine();
        }

        private static void MethodB()
        {
            //数据库路径
            var mySQLPath = Process.GetProcessesByName("mysqld");
            try
            {
                Console.WriteLine(mySQLPath[0].MainModule.FileName);
            }
            catch (Exception)
            {
                Console.WriteLine("没有数据库!");
                return;
            }
            string path = System.IO.Path.GetDirectoryName(mySQLPath[0].MainModule.FileName);
            //桌面路径
            string DeskTopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
            DeskTopPath += @"\mysql_Fix";
            if (!System.IO.Directory.Exists(DeskTopPath))
            {
                System.IO.Directory.CreateDirectory(DeskTopPath);
            }
            Console.WriteLine("请在桌面输出路径中查看修复日志文件");


            //创建bat 使得修复代码可视化
            StringBuilder batstr = new StringBuilder();
            //batstr.Append(" @echo off" + "\r\n");
            batstr.Append("cd " + path + "\r\n");
            batstr.Append("mysqlcheck -a --databases supercashier -uroot>" + DeskTopPath + @"\A_Analysis.txt" + " \r\n");//分析指定的表 所有数据库
            batstr.Append("mysqlcheck -c --databases supercashier -uroot>" + DeskTopPath + @"\B_check.txt" + " \r\n");//检查库或表
            batstr.Append("mysqlcheck -r --databases supercashier -uroot>" + DeskTopPath + @"\C_repair.txt" + " \r\n");//修复库或表
            batstr.Append("mysqlcheck -o --databases supercashier -uroot>" + DeskTopPath + @"\D_optimization.txt" + " \r\n");//优化指定的表
            batstr.Append("mysqlcheck --auto-repair  --databases supercashier -uroot>" + DeskTopPath + @"\ssss.txt" + " \r\n");
            System.IO.File.WriteAllText(DeskTopPath + @"\fixmysql.bat", batstr.ToString());
            //执行一次语句
            Process.Start(DeskTopPath + @"\fixmysql.bat");

            System.IO.File.WriteAllText(DeskTopPath + @"\fixmysql.txt", ExecuteCommand(batstr.ToString()));
            //Console.WriteLine();
            Console.ReadLine();

        }

        /// <summary>
        /// 使用命令行执行命令并返回结果
        /// </summary>
        /// <param name="command">The command.</param>
        /// <returns></returns>
        private static string ExecuteCommand(string command)
        {
            try
            {
                // create the ProcessStartInfo using "cmd" as the program to be run,
                // and "/c " as the parameters.
                // Incidentally, /c tells cmd that we want it to execute the command that follows,
                // and then exit.
                var procStartInfo =
                    new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);

                // The following commands are needed to redirect the standard output.
                // This means that it will be redirected to the Process.StandardOutput StreamReader.
                procStartInfo.RedirectStandardOutput = true;
                procStartInfo.UseShellExecute = false;
                // Do not create the black window.
                procStartInfo.CreateNoWindow = true;
                // Now we create a process, assign its ProcessStartInfo and start it
                var proc = new Process();
                proc.StartInfo = procStartInfo;
                proc.Start();
                // Get the output into a string
                return proc.StandardOutput.ReadToEnd();
                // Display the command output.
                //Console.WriteLine(result);
            }
            catch (Exception objException)
            {
                // Log the exception
                //MessageBox.Show(objException.Message);
                Console.WriteLine(objException.Message);
                return null;
            }
        }
    }

}

代码中

A方法 是整套的检查修复流程

B方法是利用bat执行cmd命令 这样代码量少 但是会暴漏语句 可以执行完再删除

C方法是只检查数据库表是否正常

里面有个蛋疼的是字符串输出的时候会把路径加上很多字符 cmd识别不出来

所以利用下面的语句来切换工作目录

            Directory.SetCurrentDirectory(path);

不过也可以看到 方法B中是通过cd 目录来实现这个效果的

反正听起来蛮简单的,做起来好多小细节需要自己把握

希望对大家有用


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值