Exemplo n.º 1
0
        /// <summary>
        /// 数据库主备同步
        /// </summary>
        /// <returns></returns>
        public void DBSync()
        {
            try
            {
                // 删除备数据库
                if (!DBDelete())
                {
                }

                int dbSize = 1;
                Open();
                foreach (Database db in svr.Databases)
                {
                    if (db.Name == dbName)
                    {
                        //得到数据库大小
                        dbSize = db.FileGroups.Item(1).DBFiles.Item(1).Size;
                        break;
                    }
                }
                #region [ 判断磁盘剩余空间是否可进行备份 ]

                // 获取磁盘剩余空间大小
                DriveInfo d        = new DriveInfo(dbPath.Substring(0, 1));
                int       diskSize = Convert.ToInt32(d.AvailableFreeSpace / 1024 / 1024);
                if (diskSize < dbSize)
                {
                    ErrorMessage(2024003, "", "[DataBaseManage:CheckDBState]", "备份数据库所需磁盘空间不够" + dbSize + "M\r\n磁盘[" + d.Name + "]存储空间过小,无法备份");
                    return;
                }
                #endregion

                #region [ 强制关闭主数据库的连接 ]
                // 获取所有的进程列表
                SQLDMO.QueryResults qr = svr.EnumProcesses(-1);

                // 查找 SPID 和 DBName 的位置
                int iColPIDNum = -1;        // 标记 SPID 的位置
                int iColDbName = -1;        // 标记 DBName 的位置

                for (int i = 1; i <= qr.Columns; i++)
                {
                    string strName = qr.get_ColumnName(i);

                    if (strName.ToUpper().Trim() == "SPID")
                    {
                        // 标记 SPID
                        iColPIDNum = i;
                    }
                    else if (strName.ToUpper().Trim() == "DBNAME")
                    {
                        // 标记 DBName
                        iColDbName = i;
                    }

                    // 如果找到 SPID 和 DBName, 则跳出循环
                    if (iColPIDNum != -1 && iColDbName != -1)
                    {
                        break;
                    }
                }

                // 发现正在操作指定恢复的数据库的进程,将其强制终止
                for (int i = 1; i <= qr.Rows; i++)
                {
                    // 获取该进程正在操作的数据库名称
                    int    lPID      = qr.GetColumnLong(i, iColPIDNum);
                    string strDBName = qr.GetColumnString(i, iColDbName);

                    // 比对被操作的数据库是否是我们要还原的数据库
                    if (strDBName.ToUpper() == dbName.ToUpper())
                    {
                        svr.KillProcess(lPID);
                    }
                }
                #endregion
                // 分离原数据库
                string s = svr.DetachDB(dbName, false);

                // 判断 文件夹不存在则创建 文件存在则删除
                if (!Directory.Exists(backPath))
                {
                    Directory.CreateDirectory(backPath);
                }

                try
                {
                    // 删除备数据库
                    svr.KillDatabase(dbBackUpName);
                }
                catch { }

                // 备数据库主文件
                if (File.Exists(backPath + dbName + ".mdf"))
                {
                    // 分离原数据库
                    try
                    {
                        svr.DetachDB(dbBackUpName, false);
                    }
                    catch { }
                    File.Delete(backPath + dbName + ".mdf");
                }
                // 备数据库日志文件
                if (File.Exists(backPath + dbBackUpName + "_log.ldf"))
                {
                    File.Delete(backPath + dbBackUpName + "_log.ldf");
                }

                #region copy文件

                fc = new FileCopy(dbPath + dbName + ".mdf", backPath + dbName + ".mdf");
                fc.CopyComplete += new FileCopy.CopyCompleteEventHandler(fc_CopyComplete);
                fc.GuageEvent   += new FileCopy.GuageEventHandler(fc_GuageEvent);
                // 开始copy
                fc.Copy();

                #endregion
            }
            catch (System.Runtime.InteropServices.COMException ce)
            {
                if (ce.ErrorCode == -2147217803)//("因为它当前正在使用") != -1)
                {
                    // 分离错误 正在使用无法删除
                    ErrorMessage(-2147217803, ce.StackTrace, "[DBManage:DBSync]", ce.Message);
                }
            }
            //finally
            //{
            //    LinkNull(svr);
            //}
        }