2010-02-28 32 views
5

tôi cố gắng làm như sau:Đang cố gắng để tách đính kèm cơ sở dữ liệu - không thể acces db sau

  • Tháo cơ sở dữ liệu

  • Copy files vào một thư mục tạm thời

  • Gắn cơ sở dữ liệu một lần nữa

Điều này làm việc lần đầu tiên, nhưng khi tôi tr y để chạy phương pháp này lần thứ hai từ cùng một quá trình tôi nhận được một lỗi. Tôi luôn có thể truy cập vào dữ liệu được đính kèm một lần nữa từ các máy khách khác, nhưng không phải từ bên trong ứng dụng của tôi.

Lỗi này là:

"lỗi cấp Giao thông vận tải trong khi cố gắng để gửi yêu cầu đến máy chủ. (Nhà cung cấp: Shared Memory-Provider, lỗi:. 0 - không có quá trình ở đầu kia của ống)" , khi tôi cố gắng đọc dữ liệu từ sys.database_files của db mới được đính kèm.

Các lỗi được dịch từ tiếng Đức "Fehler auf Übertragungsebene beim Senden der Anforderung một den Server."

Nó xảy ra sau khi "cmdGetDBFileName.ExecuteReader". Tôi vẫn có thể mở kết nối nhưng truy vấn sys.database_files không thành công.

Nguồn khá dài, nhưng tôi đoán bạn có thể bỏ qua phần đầu tiên khi tôi lấy tên tệp của db để tách. Bạn có thấy lỗi của tôi hoặc có bất kỳ ý tưởng nào tôi có thể kiểm tra không?

public bool DetachB2CPrepare() 
     { 
      _log.Debug("DetachB2CPrepare"); 
      SqlConnection prepareDBConnection = null; 
      SqlConnection prepareMasterDBConnection = null; 
      SqlDataReader readerDbFiles = null; 

      bool result = true; 
      try 
      { 
       //rc_b2c_product_prepare.mdf  
       string prepareDBPysicalFileName = ""; 
       //rc_b2c_product_prepare  
       string prepareDBFileName = ""; 
       //D:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\rc_b2c_product_prepare.mdf 
       string prepareDBFileNameComplete = ""; 

       //rc_b2c_product_prepare_1.ldf 
       string prepareTransactionLogPhysicalFileName = ""; 
       //rc_b2c_product_prepare_log  
       string prepareTransactionLogFileName = ""; 
       //D:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\rc_b2c_product_prepare_1.ldf 
       string prepareTransactionLogFileNameComplete = ""; 
       _log.DebugFormat("Try to open B2CPrepare"); 
       prepareDBConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["B2CPrepare"].ConnectionString); 
       prepareDBConnection.Open(); 



       //Get the file names of DB 
       SqlCommand cmdGetDBFileName = new SqlCommand("select name , physical_name, type from sys.database_files where type= 0"); 
       cmdGetDBFileName.Connection = prepareDBConnection; 
       readerDbFiles = cmdGetDBFileName.ExecuteReader(); 
       if (readerDbFiles.Read()) 
       { 
        prepareDBFileName = (string)readerDbFiles["name"]; 
        prepareDBFileNameComplete = (string)readerDbFiles["physical_name"]; 
        int lastSlash = prepareDBFileNameComplete.LastIndexOf(@"\"); 
        prepareDBPysicalFileName = prepareDBFileNameComplete.Substring(lastSlash + 1, prepareDBFileNameComplete.Length - lastSlash - 1); 
        readerDbFiles.Close(); 
       } 
       else{ 
        return false; 
       } 

       cmdGetDBFileName.CommandText = "select name , physical_name, type from sys.database_files where type= 1"; 
       readerDbFiles = cmdGetDBFileName.ExecuteReader(); 
       if (readerDbFiles.Read()) 
       { 
        prepareTransactionLogFileName = (string)readerDbFiles["name"]; 
        prepareTransactionLogFileNameComplete = (string)readerDbFiles["physical_name"]; 
        int lastSlash = prepareTransactionLogFileNameComplete.LastIndexOf(@"\"); 
        prepareTransactionLogPhysicalFileName = prepareTransactionLogFileNameComplete.Substring(lastSlash + 1, prepareTransactionLogFileNameComplete.Length - lastSlash - 1); 
        readerDbFiles.Close(); 
       } 
       else 
       { 
        return false; 
       } 

       _log.DebugFormat("shrink transactionlog {0}", prepareTransactionLogFileName); 

       SqlCommand cmdShrinkPrepare = new SqlCommand(string.Format(@"DBCC Shrinkfile('{0}',100) ", prepareTransactionLogFileName)); 
       cmdShrinkPrepare.Connection = prepareDBConnection; 
       cmdShrinkPrepare.ExecuteNonQuery(); 

       //master auf MyProductName 
       prepareMasterDBConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyProductNameMaster"].ConnectionString); 
       prepareMasterDBConnection.Open(); 

       _log.Debug("cmdOffline"); 

       //Datenbank verbindunge löschen 
       SqlCommand cmdOffline = new SqlCommand(@"ALTER DATABASE rc_b2c_product_prepare SET SINGLE_USER WITH ROLLBACK IMMEDIATE"); 
       cmdOffline.Connection = prepareMasterDBConnection; 
       cmdOffline.ExecuteNonQuery(); 

       _log.Debug("cmdDetach: rc_b2c_product_prepare" ); 

       SqlCommand cmdDetach = new SqlCommand(@"dbo.sp_detach_db @dbname = N'rc_b2c_product_prepare',@keepfulltextindexfile = N'false'"); 
       cmdDetach.Connection = prepareMasterDBConnection; 
       cmdDetach.ExecuteNonQuery(); 

       string pathForCopies = MyProductName.Backend.settings.B2CPrepareDBBackupPath; 

       //copy files to temp folder 
       string tempFileDB = pathForCopies + "\\" + prepareDBPysicalFileName; 
       string tempFileLog = pathForCopies + "\\" + prepareTransactionLogPhysicalFileName; 

       _log.DebugFormat("Copy: {0} TO: {1}", prepareDBFileNameComplete, tempFileDB); 

       System.IO.File.Copy(prepareDBFileNameComplete, tempFileDB, true); 

       _log.DebugFormat("Copy: {0} TO: {1}", prepareTransactionLogFileNameComplete, tempFileLog); 

       System.IO.File.Copy(prepareTransactionLogFileNameComplete, tempFileLog, true); 

       _log.DebugFormat("cmdAttach: db {0} log {1}", prepareDBFileNameComplete, prepareTransactionLogFileNameComplete); 

       SqlCommand cmdAttach = new SqlCommand( 
         string.Format(@" 
         CREATE DATABASE rc_b2c_product_prepare ON 
         (FILENAME = N'{0}'), 
         (FILENAME = N'{1}') 
         FOR ATTACH", prepareDBFileNameComplete, prepareTransactionLogFileNameComplete)); 

       cmdAttach.Connection = prepareMasterDBConnection; 
       cmdAttach.ExecuteNonQuery(); 

       _log.Debug("ALTER DATABASE rc_b2c_product_prepare SET MULTI_USER "); 

       //set multi user 
       SqlCommand cmdOnline = new SqlCommand(@"ALTER DATABASE rc_b2c_product_prepare SET MULTI_USER WITH ROLLBACK IMMEDIATE"); 
       cmdOnline.Connection = prepareMasterDBConnection; 
       cmdOnline.ExecuteNonQuery(); 

       return result; 
      } 
      catch (Exception e) 
      { 
       _log.Error(e); 
       return false; 
      } 
      finally 
      { 
       if (prepareDBConnection != null) 
       { 
        prepareDBConnection.Close(); 
       } 
       if (prepareMasterDBConnection != null) 
       { 
        prepareMasterDBConnection.Close(); 
       } 
       if (readerDbFiles != null) 
       { 
        readerDbFiles.Close(); 
       } 
      } 
     } 

Trả lời

1

Có vẻ như nó có thể liên quan đến việc cố gắng sử dụng kết nối không còn hợp lệ do kết nối tổng hợp.

Bạn có thể thử tắt tính năng tổng hợp kết nối để xem đó có phải là sự cố hay không. Để làm điều này, thêm "Pooling = false" vào chuỗi kết nối SQL trong tệp cấu hình của bạn.

+0

vô hiệu hóa kết nối ppoiling đã làm các trick –

1

Có thể có vấn đề với hồ bơi kết nối, bạn đã thử đóng prepareDBConnection trước khi thực hiện tách/đính kèm?

Thứ hai, bạn đã xem các đối tượng quản lý SQL (SMO) - đây là một example for the detach/attach.

Thận trọng, bạn không phải tách cơ sở dữ liệu khi bạn chỉ muốn tạo bản sao lưu, bạn có thể đặt bản sao ngoại tuyến thay thế. Using SMO hoặc using SQL (sp_dboption doc).

0

Để Tách một cơ sở dữ liệu MSSQL

USE master; 
GO 
ALTER DATABASE [AdventureWorks2012] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; 
EXEC sp_detach_db @dbname = N'AdventureWorks2012'; 
GO 

Để đính kèm một cơ sở dữ liệu tách

USE master; 
GO 
CREATE DATABASE MyAdventureWorks 
ON (FILENAME = 'C:\MySQLServer\AdventureWorks2012_Data.mdf'), 
(FILENAME = 'C:\MySQLServer\AdventureWorks2012_Log.ldf') 
FOR ATTACH; 
GO 

Tôi đã thử mã này cho nhiều cơ sở dữ liệu, nó làm việc tốt.

Các vấn đề liên quan