2017-08-03 12 views
1

Azure StorageにSQLデータベース(Azureまたは互換性のあるオンデマンド)をプログラムでバックアップ/エクスポートして別のSQLデータベースに復元する必要があります。ビルドサーバーまたは本番サーバーのいずれかにAzure SDKがインストールされているとは保証できないため、コードの依存関係にNuGetパッケージのみを使用したいと考えています。私は、共通の行動と思われるものについて、コード例を見つけることはできません。SQLデータベースをプログラムで直接BLOBストレージにエクスポートする方法

https://blog.hompus.nl/2013/03/13/backup-your-azure-sql-database-to-blob-storage-using-code/

しかし、(RoleEnvironment、SDKのみのオブジェクトを必要とする)ローカルBACPACファイルにこのコードの輸出:私が見つけた最も近いが、このでした。中間ファイルを使わずにBlob Storageに直接エクスポートする方法があるはずです。ストリームを作成して実行することが考えられました。

services.ExportBacpac(stream, "dbnameToBackup") 

ストリームをストレージに書き込みます。メモリストリームは機能しません。これは大規模なデータベース(100〜200 GB)になる可能性があります。

これを行うにはどうすればよいでしょうか?ここで

+1

それをローカルファイルに書き出し、Azure Storage Data Movement Libraryを介してBlobストレージにアップロードしますか? https://www.nuget.org/packages/Microsoft.Azure.Storage.DataMovement –

答えて

1

はアイデアです:

.ExportBacPac方法にストリームを渡していますが、定期的に空に別のスレッドで、それへの参照を保持し、何のメモリオーバーフローがありませんようにストリームをリセットします。ここでは、Dacにはストリームがいっぱいになっているときにアクセスする手段がないと仮定しています。

スレッドセーフであるにもかかわらず、自分で気を取らなければならないこと - MemoryStreamsはデフォルトでスレッドセーフではありません。だから、.Position.CopyToの周りに独自のロック機構を書く必要があります。私はこれをテストしていないが、あなたが正しくロックを処理する場合、私は.ExportBacPacメソッドは、他のスレッドがストリームにアクセスしている間にエラーをスローしないと思います。私のテストに基づいて

ThreadSafeStream stream = new ThreadSafeStream(); 

Task task = new Task(async (exitToken) => { 
    MemoryStream partialStream = new MemoryStream(); 

    // Check if backup completed 
    if (...) 
    { 
     exitToken.Trigger(); 
    } 

    stream.CopyToThreadSafe(partialStream); 
    stream.PositionThreadSafe = 0; 

    AzureService.UploadToStorage(partialStream); 

    await Task.Delay(500); // Play around with this - it shouldn't take too long to copy the stream 
}); 

services.ExportBacpac(stream, "dbnameToBackup"); 

await TimerService.RunTaskPeriodicallyAsync(task, 500); 
+0

私はロックを導入することに興奮していません。以前の経験では、ロックは痛みの大きな原因でした。また、アプリケーションコードがさまざまな並列タスクを実行するために何百ものスレッドを作成してアップロードスレッドを枯渇させることができるため、インフラストラクチャコード(私が書いているもの)に新しいスレッドを作成することは問題があります。最終的にはタイムアウトにつながる。 (これも前に起こったことです) – afeygin

4

は、sql Microsoft Azure SQL Management Library 0.51.0-prereleaseサポートが直接AzureストレージにSQLデータベース.bacpacファイルをエクスポート:

は、ここに私の考えをまとめた擬似コードのような非常に単純な例です。

sqlManagementClient.ImportExport.Export(resourceGroup, azureSqlServer, azureSqlDatabase,exportRequestParameters)を使用してをエクスポートできます。 bacpacファイル紺碧の記憶

しかし、Microsoft Azure SQL管理ライブラリSDKの最新バージョンでは、ImportExportが見つかりませんでした。したがって、Microsoft SQL Azure SQL管理ライブラリSQL 5.01.0-prerelease SDKしか使用できませんでした。

SQL Azure SQL管理ライブラリを使用してSQLバックアップを空白のBLOBストレージにエクスポートする方法の詳細は、以下の手順とコードを参照してください。

前提条件:

レジストリのAzure AD内のAppとそのためのサービスの原則を作成します。レジストリアプリケーションとアクセストークンの取得方法の詳細な手順は、documentを参照してください。

詳細コード:

注意:ご登録の紺碧のAD情報とのclientId、tenantId、秘密鍵、subscriptionIdを交換してください。azureSqlDatabase、resourceGroup、azureSqlServer、adminLogin、adminPassword、storageKey、storageAccountを独自のSQLデータベースとストレージに置き換えます。このような

static void Main(string[] args) 
{ 

    var subscriptionId = "xxxxxxxx"; 
    var clientId = "xxxxxxxxx"; 
    var tenantId = "xxxxxxxx"; 
    var secretKey = "xxxxx"; 
    var azureSqlDatabase = "data base name"; 
    var resourceGroup = "Resource Group name"; 
    var azureSqlServer = "xxxxxxx"; //testsqlserver 
    var adminLogin = "user"; 
    var adminPassword = "password"; 
    var storageKey = "storage key"; 
    var storageAccount = "storage account"; 
    var baseStorageUri = $"https://{storageAccount}.blob.core.windows.net/brandotest/";//with container name endwith "/" 
    var backName = azureSqlDatabase + "-" + $"{DateTime.UtcNow:yyyyMMddHHmm}" + ".bacpac"; //back up sql file name 
    var backupUrl = baseStorageUri + backName; 
    ImportExportOperationStatusResponse exportStatus = new ImportExportOperationStatusResponse(); 
    try 
    { 
     ExportRequestParameters exportRequestParameters = new ExportRequestParameters 
     { 
      AdministratorLogin = adminLogin, 
      AdministratorLoginPassword = adminPassword, 
      StorageKey = storageKey, 
      StorageKeyType = "StorageAccessKey", 
      StorageUri = new Uri(backupUrl) 
     }; 

     SqlManagementClient sqlManagementClient = new SqlManagementClient(new Microsoft.Azure.TokenCloudCredentials(subscriptionId, GetAccessToken(tenantId, clientId, secretKey))); 
     var export = sqlManagementClient.ImportExport.Export(resourceGroup, azureSqlServer, azureSqlDatabase, 
         exportRequestParameters); //do export operation 

     while (exportStatus.Status != Microsoft.Azure.OperationStatus.Succeeded) // until operation successed 
     { 
      Thread.Sleep(1000 * 60); 
      exportStatus = sqlManagementClient.ImportExport.GetImportExportOperationStatus(export.OperationStatusLink); 
     } 

     Console.WriteLine($"Export DataBase {azureSqlDatabase} to Storage {storageAccount} Succesfully"); 
    } 

    catch (Exception exception) 
    { 

     //todo 

    } 

} 

private static string GetAccessToken(string tenantId, string clientId, string secretKey) 
{ 
    var authenticationContext = new AuthenticationContext($"https://login.windows.net/{tenantId}"); 
    var credential = new ClientCredential(clientId, secretKey); 
    var result = authenticationContext.AcquireTokenAsync("https://management.core.windows.net/", 
     credential); 

    if (result == null) 
    { 
     throw new InvalidOperationException("Failed to obtain the JWT token"); 
    } 

    var token = result.Result.AccessToken; 
    return token; 
} 

結果:

1.Send要求がデータベースにエクスポート動作状態を監視するための要求を送信Azureブロブストレージ

enter image description here

2.ContinueにエクスポートするSQL Serverの開始を指示します。

enter image description here

3.Finish操作を輸出しました。

enter image description here

+0

これは有望ですが、プレリリースソフトウェアを使用することはできません。 – afeygin

+0

また、sqlデータベースのエクスポート[rest api](https://docs.microsoft.com/en-us/rest/api/sql/databases%20-%20import%20export#Databases_Export)を使用して、SQL Serverに通知することもできますデータベースをダウンロードして空白のブロブにエクスポートします。このように受け入れると、コード例をいくつか提供することもできます。 –

1

それはブランドの答えに似ですが、この1つは安定したパッケージ使用します:ブランドの答えで同じ変数を使用して

using Microsoft.WindowsAzure.Management.Sql; 

Nuget

を、コードは次のようになります:

var azureSqlServer = "xxxxxxx"+".database.windows.net"; 
var azureSqlServerName = "xxxxxxx"; 

     SqlManagementClient managementClient = new SqlManagementClient(new TokenCloudCredentials(subscriptionId, GetAccessToken(tenantId, clientId, secretKey))); 

     var exportParams = new DacExportParameters() 
     { 
      BlobCredentials = new DacExportParameters.BlobCredentialsParameter() 
      { 
       StorageAccessKey = storageKey, 
       Uri = new Uri(baseStorageUri) 
      }, 
      ConnectionInfo = new DacExportParameters.ConnectionInfoParameter() 
      { 
       ServerName = azureSqlServer, 
       DatabaseName = azureSqlDatabase, 
       UserName = adminLogin, 
       Password = adminPassword 
      } 
     }; 
     var exportResult = managementClient.Dac.Export(azureSqlServerName, exportParams); 
関連する問題