断电等不可预期的错误导致数据库表不能使用。。。所以在网上找了一下有什么可以修复户数据库的。
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 目录来实现这个效果的
反正听起来蛮简单的,做起来好多小细节需要自己把握
希望对大家有用