关于sql数据库同步

本文介绍了一个用于自动实时同步数据库表的工具,通过tablediff比较源数据库和目标数据库之间的差异,并生成批处理文件来同步数据。文章详细展示了核心代码实现过程,包括创建批处理文件、执行批处理文件等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天电脑刚好出了点问题,正在郁闷中。。。这样也就有时间总结一下这两个月来我做的主要工作:

刚到公司经理就交给我一个以前老同事做过的一个项目让我重做一遍,做一个数据库同步软件。

首先看了一下同事做的软件源码。发现他实现数据库同步的核心在于读取数据库中的所有表,然后用tablediff对表进行比较,具体做法是用tablediff的方式,对每个表产生一个带tablediff函数的批处理文件,对于有内容不同的表产生一个sql日志,然后同步数据库执行sql日志中的内容。

 

写博客截图太麻烦了。。。。

不截图了

这就是相关的截图了,对数据库了解的朋友知道用tablediff的方式比较数据表将占用大量的CPU资源,当同步间隔时间设为1秒时cpu该程序占用cpu大概在10%左右。

相关的核心代码:

BatHelper.cs:生成批处理文件

using System;

using System.Diagnostics;

using System.IO;

using System.Text;

using System.Threading;

 

namespace Synchro

{

    /// <summary>

    /// .bat Helper

    /// </summary>

    class BatHelper

    {

        #region private constant

        // debug folder

        private static readonly string WorkPath      = System.Windows.Forms.Application.StartupPath;

        // TableDiff folder

        private static readonly string TableDiffPath = WorkPath + "//COM";

        // bat folder

        private static readonly string BatFilePath   = WorkPath + "//bat";

        #endregion

 

        // check bat/cfg/sql/log folders

        public static bool WorkFolderExist()

        {

            bool bret       = true;

            bool bConfig    = false;

            bool bbat       = false;

            bool bsql       = false;

            bool blog       = false;

 

            // bat/cfg/sql exists or not

            DirectoryInfo[] directories = new DirectoryInfo(WorkPath).GetDirectories();

            foreach (DirectoryInfo info in directories)

            {

                if (info.Name == "bat")

                {

                    bbat = true;

                    bret = false;

                }

                else if (info.Name == "cfg")

                {

                    bConfig = true;

                    bret = false;

                }

                else if(info.Name == "sql")

                {

                    bsql = true;

                    bret = false;

                }

                else if(info.Name == "log")

                {

                    blog = true;

                    bret = false;

                }

            }

 

            // bat/cfg/sql/lgo not exists ,create()

            DirectoryInfo directoryInfo;

            if(!bbat)

            {

                directoryInfo = new DirectoryInfo(WorkPath + "//bat");

                directoryInfo.Create();

            }

            if (!bConfig)

            {

                directoryInfo = new DirectoryInfo(WorkPath + "//cfg");

                directoryInfo.Create();

            }

            if (!bsql)

            {

                directoryInfo = new DirectoryInfo(WorkPath + "//sql");

                directoryInfo.Create();

            }

            if(!blog)

            {

                directoryInfo = new DirectoryInfo(WorkPath + "//log");

                directoryInfo.Create();

            }

 

            return bret;

        }

 

        // 根据表名创建对应的批处理文件

        public static void CreateTableDiffBat(string tableName)

        {

            if(tableName == null ||tableName.Trim() == "")

                return;

            string serverSrc    = "";

            string uidSrc       = "";

            string pwdSrc       = "";

            string databaseSrc  = "";

            string serverDes    = "";

            string uidDes       = "";

            string pwdDes       = "";

            string databaseDes  = "";

 

            // select ServerCfg.xml cfgfile

            bool ret = XmlHelper.SelectServerSetConfig(ref serverSrc, ref uidSrc, ref pwdSrc, ref databaseSrc, ref serverDes, ref uidDes, ref pwdDes, ref databaseDes);

            if (!ret)

            {

                throw new Exception(@"加载配置文件/cfg/ServerCfg.xml失败");

            }

 

            // 拼接字符串创建 "tableName.bat"形式文件

            System.IO.StreamWriter sw = new StreamWriter(BatFilePath + "//" + tableName + ".bat", false, Encoding.Default);

            sw.WriteLine("cd "+TableDiffPath);

            StringBuilder content = new StringBuilder();

            content.Append("tablediff -sourceserver ");

            content.Append("/"");

            content.Append(serverSrc);

            content.Append("/"");

            content.Append(" -sourcedatabase ");

            content.Append("/"");

            content.Append(databaseSrc);

            content.Append("/"");

            content.Append(" -sourcetable ");

            content.Append("/"");

            content.Append(tableName);

            content.Append("/"");

            content.Append(" -sourceschema /"dbo/"");

            content.Append(" -sourcepassword ");

            content.Append("/"");

            content.Append(pwdSrc);

            content.Append("/"");

            content.Append(" -sourceuser ");

            content.Append("/"");

            content.Append(uidSrc);

            content.Append("/"");

            content.Append(" -destinationserver ");

            content.Append("/"");

            content.Append(serverDes);

            content.Append("/"");

            content.Append(" -destinationdatabase ");

            content.Append("/"");

            content.Append(databaseDes);

            content.Append("/"");

            content.Append(" -destinationtable ");

            content.Append("/"");

            content.Append(tableName);

            content.Append("/"");

            content.Append(" -destinationschema /"dbo/" ");

            content.Append("-destinationpassword ");

            content.Append("/"");

            content.Append(pwdDes);

            content.Append("/"");

            content.Append(" -destinationuser ");

            content.Append("/"");

            content.Append(uidDes);

            content.Append("/"");

            content.Append(" -bf  /"50000/" ");

            content.Append(" -f ");

            content.Append("/"");

            content.Append(DbHelper.SqlFilePath + "//" + tableName);

            content.Append("/"");

            sw.WriteLine(content.ToString());

            sw.Close();

        }

 

        // exec "tableName.bat"

        public static bool ExecTableDiffBat(string tableName)

        {

            try

            {

                DbHelper.FileDelete(tableName);

                ProcessStartInfo p = new ProcessStartInfo("cmd.exe");

                p.UseShellExecute = false;

                p.RedirectStandardError = true;

                p.CreateNoWindow = true;

                p.Arguments = "/c " + BatFilePath + "//" + tableName.Trim() + ".bat";

                //p.WorkingDirectory = "c://";

                Process process = Process.Start(p);

                do

                {

                    Thread.Sleep(500);

 

                } while (!process.HasExited);

                process.Close();

                return true;

            }

            catch(Exception e)

            {

                //string Synchrolog = LogHelper.LogFilePath + "//Synchro_" + DateTime.Now.ToString("yyyy-MM-dd").Trim() + ".log";

                //LogHelper.AppendLog(Synchrolog,"执行["+tableName+".bat]文件出错。 "+e.Message);

                return false;

            }

        }

 

        // exists *.bat file

        public static bool FileExist(string fileName)

        {

            return File.Exists(BatFilePath + "//" + fileName + ".bat");

        }

 

        // delete all *.bat files

        public static bool RemoveAll()

        {

            FileInfo[] fileInfos = new DirectoryInfo(BatFilePath).GetFiles();

            foreach (FileInfo info in fileInfos)

            {

                info.Delete();

            }

            return true;

        }

 

        public static void RemoveSqlFile(string tableName)

        {

            int i = 0;

            while (true)

            {

                string sqlFileN = DbHelper.SqlFilePath + "//" + tableName + "." + i.ToString() + ".sql";

                if (File.Exists(sqlFileN))

                {

                    DbHelper.ExecDataDiffSqlFile(sqlFileN);

                }

                i++;

                if(i==21)

                    break;

            }

        }

    }

}

 

 

比较数据表,与同步数据表主函数:

// preview compare .

        private bool PreviewCompare(string tableName)

        {

 

            DataTable dtSrt = DbHelper.GetSpaceUsedSrc(tableName);

            if (dtSrt != null && dtSrt.Rows.Count > 0)

            {

                txtTabNmSrc.Text = dtSrt.Rows[0]["name"].ToString().Trim();

                txtRowSrc.Text = dtSrt.Rows[0]["rows"].ToString().Trim();

                txtDataSrc.Text = dtSrt.Rows[0]["data"].ToString().Trim();

            }

 

            DataTable dtDes = DbHelper.GetSpaceUsedDes(tableName);

            if (dtDes != null && dtDes.Rows.Count > 0)

            {

                txtTabNmDes.Text = dtDes.Rows[0]["name"].ToString().Trim();

                txtRowDes.Text = dtDes.Rows[0]["rows"].ToString().Trim();

                txtDataDes.Text = dtDes.Rows[0]["data"].ToString().Trim();

            }

            int srcCount = DbHelper.GetTableCountSrc(tableName);

            int desCount = DbHelper.GetTableCountDes(tableName);

            if (srcCount != -1 && desCount != -1)

            {

                txtRowSrc.Text = srcCount.ToString();

                txtRowDes.Text = desCount.ToString();

 

                if (srcCount == desCount)

                {

                    return true;

                }

                else

                {

                    return false;

                }

            }

            if(txtRowSrc.Text!=txtRowDes.Text)

            {

                return false;

            }

            //if(txtDataSrc.Text!= txtDataDes.Text)

            //{

            //    return false;

            //}

            return true;

        }

 

功能说明:

自动实时同步设置的实时同步表。

自动在设置时刻数据库数据整体同步。

一天内可以设置多个数据库整体同步的时刻。

提供相同表数据差异对比工具,并可以进行数据同步数据。

 

配置说明:

1.配置同步数据库信息。

2.配置需要实时同步的表及时间间隔。

3.配置数据库整体同步的时间。

4.完成以上配置,运行。

 

 

注意:

    同步时间间隔设置过小,可能导致CPU占用率过高。

         工作目录下,请勿修改“COM”文件夹名,也不要删除该文件。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值