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

来源:互联网 发布:淘宝第三方资金平台 编辑:程序博客网 时间:2024/04/25 15:21

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

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
原创粉丝点击