FILESTREAM ডেটা বাদে ডাটাবেস পুনরুদ্ধার করুন


20

প্রসঙ্গ
আমরা নীচে একটি বৃহত-ইশ ডাটাবেস সহ একটি সিস্টেম বিকাশ করছি। এটি একটি এমএস এসকিউএল ডাটাবেস যা এসকিউএল সার্ভার ২০০৮ আর 2 এ চলছে। ডাটাবেসের মোট আকার প্রায় 12 জিবি।

এর মধ্যে প্রায় 8.5 জিবি একটি একক টেবিলে রয়েছে BinaryContent। নামটি যেমন বোঝায়, এটি একটি টেবিল যেখানে আমরা সরল ফাইলগুলি যে কোনও প্রকারের সরাসরি টেবিলটিতে একটি বিএলএলবি হিসাবে সংরক্ষণ করি। সম্প্রতি আমরা FILESTREAM ব্যবহার করে এই সমস্ত ফাইলটিকে ডাটাবেস থেকে সরিয়ে ফাইল সিস্টেমে স্থানান্তরিত করার সম্ভাবনাটি পরীক্ষা করে যাচ্ছি।

আমরা কোনও সমস্যা ছাড়াই আমাদের ডাটাবেসে প্রয়োজনীয় পরিবর্তন করেছি এবং মাইগ্রেশনের পরেও আমাদের সিস্টেম এখনও ভাল কাজ করছে। BinaryContentটেবিল ভালো মোটামুটিভাবে দেখায়:

CREATE TABLE [dbo].[BinaryContent](
    [BinaryContentID] [int] IDENTITY(1,1) NOT NULL,
    [FileName] [varchar](50) NOT NULL,
    [BinaryContentRowGUID] [uniqueidentifier] ROWGUIDCOL  NOT NULL
) ON [PRIMARY] FILESTREAM_ON [FileStreamContentFG]
ALTER TABLE [dbo].[BinaryContent] ADD [FileContentBinary] [varbinary](max) FILESTREAM  NULL
ALTER TABLE [dbo].[BinaryContent] ADD  CONSTRAINT [DFBinaryContentRowGUID]  DEFAULT (newsequentialid()) FOR [BinaryContentRowGUID]

সবকিছুতেই অবস্থিত সঙ্গে PRIMARYফাইল গ্রুপ, ক্ষেত্র ছাড়া FileBinaryContentযা একটি পৃথক ফাইলে গ্রুপ রয়েছে FileStreamContentFG

পরিস্থিতি
বিকাশকারীর দৃষ্টিকোণ থেকে, আমরা প্রায়শই আমাদের উত্পাদন পরিবেশ থেকে ডেটাবেজের একটি নতুন কপি চাই, যাতে সর্বশেষতম ডেটা কাজ করতে সক্ষম হয়। এই ক্ষেত্রে, আমরা খুব সহজেই বাইনারি কনটেন্টে সঞ্চিত ফাইলগুলিতে আগ্রহী (এখন FILESTREAM ব্যবহার করছি)।

আমাদের পছন্দ মতো এটি প্রায় কাজ করে যাচ্ছি। আমরা ফাইল স্ট্রিম ছাড়াই ডাটাবেস ব্যাক আপ করি:

BACKUP DATABASE FileStreamDB
FILEGROUP = 'PRIMARY' 
TO DISK = 'c:\backup\FileStreamDB_WithoutFS.bak' WITH INIT

এবং এটি পুনরুদ্ধার করুন:

RESTORE DATABASE FileStreamDB
FROM DISK = 'c:\backup\FileStreamDB_WithoutFS.bak'

এটি ঠিকঠাকভাবে কাজ করছে বলে মনে হচ্ছে এবং আমরা FileBinaryContentক্ষেত্রটি যে অংশগুলি ব্যবহার করি সেগুলি এড়াতে আমাদের সিস্টেম ততক্ষণ কাজ করে । আমরা উদাহরণস্বরূপ কোনও সমস্যা ছাড়াই নিম্নলিখিত কোয়েরিটি চালাতে পারি:

SELECT TOP 10 [BinaryContentID],[FileName],[BinaryContentRowGUID]
--,[FileContentBinary]
FROM [dbo].[BinaryContent]

স্বাভাবিকভাবেই, যদি আমি FileContentBinaryকোয়েরি সহ উপরের লাইনটি অন-মন্তব্য করি তবে আমি একটি ত্রুটি পেয়েছি:

"Dbo.BinaryContent" টেবিলের জন্য বৃহত্তর অবজেক্ট (LOB) ডেটা অফলাইন ফাইলগ্রুপ ("ফাইলস্ট্রিমসন্টেন্টজিজি") এ থাকে যা অ্যাক্সেস করা যায় না।

আমাদের সিস্টেম হ্যান্ডলগুলি ফাইল কোন সামগ্রীর সেট করা হয় null, তাই কি আমি চাই চাই না ভালো কিছু হল:

UPDATE [dbo].[BinaryContent]
SET [FileContentBinary] = null

তবে এটি অবশ্যই আমাকে উপরের মতো ত্রুটি দেয়। এই সময়ে আমি আটকে আছি।

প্রশ্ন ফাইল গ্রুপ
থেকে সবকিছু পুনরুদ্ধার না করেই আমি কি ডাটাবেস পুনরুদ্ধার করতে পারি FileStreamContentFG? হয় উপরে আপডেট করার সাথে সাথে মানগুলি নালিতে আপডেট করে, অথবা ফাইলটি অনুপস্থিত বা কিছু হারিয়ে যাওয়ার পরে ডিফল্ট হয়ে যায়?

বা আমি সম্ভবত ভুল উপায়ে সমস্যার দিকে এগিয়ে যাচ্ছি?

আমি প্রকৃতির দ্বারা বিকাশকারী এবং ডিবিএ হিসাবে বেশি জ্ঞান নেই, তাই যদি আমি এখানে কিছু তুচ্ছ জিনিস উপেক্ষা করছি তবে আমাকে ক্ষমা করবেন।


আপনি কি পুনরায় পুনরুদ্ধার করতে পারবেন যাতে আপনার কাছে [বাইনারি কনসেন্ট] ফাইলগ্রুপ থেকে কিছু ডেটা থাকে এবং তারপরে আপনি ডেট করতে চাইলে প্রাথমিক ফাইলগ্রুপটি পুনরুদ্ধার করতে পারেন?
jgardner04

@ jgardner04: এটি কার্যকর বলে মনে হচ্ছে না। আমি প্রথমে সম্পূর্ণ পুনরুদ্ধার করি এবং তারপরে কেবলমাত্র প্রাথমিক ফাইল গোষ্ঠী ব্যাকআপের পুনঃস্থাপনের পরে ডেটাবেসটি বেমানান অবস্থায় শেষ হয় (ত্রুটি বার্তা: "লগ পুনরুদ্ধার না হওয়ায় ডাটাবেসটি পুনরুদ্ধার করা যায় না (...) ডাটাবেস অনলাইনে আনা যায়নি কারণ এক বা একাধিক রেস্টোর স্টেপ দরকার " )।
জুলিয়ান

আপনারা কী ডাবো.বাইনারি কনসেন্টে সর্বদা সঞ্চিত পদ্ধতির মাধ্যমে অ্যাক্সেস পান? কয়জন জড়িত?
মার্ক স্টোরি-স্মিথ

@ মার্কস্টোরী-স্মিথ: এনএইচবারনেটের মাধ্যমে (একটি এএসপি.নেট ওয়েব অ্যাপ্লিকেশন এবং একটি উইন্ডোজ ফর্ম অ্যাপ্লিকেশন উভয় থেকে) মূলত নিয়মিত প্রশ্নগুলি ব্যবহার করে ডাটাবেসটি অ্যাক্সেস করা হয়। কীভাবে প্রাসঙ্গিক?
জুলিয়ান

2
আপনার অ্যাক্সেস যদি সঞ্চিত প্রক্রিয়াগুলির মাধ্যমে হয় তবে আমরা কোন ফাইলগ্রুপগুলি অনলাইনে রয়েছে তা পরীক্ষা করতে আংশিক উপলব্ধতা / টুকরোয়াল পুনরুদ্ধার থেকে একটি পদ্ধতির প্রয়োগ করতে পারি। সত্যি কথা বলতে, 12 জিবি তে এটি প্রায় কাজ করার মতো নয়, কেবল পুরো পুনরুদ্ধার করা।
মার্ক স্টোর-স্মিথ

উত্তর:


10

আপনি যা করার চেষ্টা করছেন তা ডাটাবেসটিকে একটি (লেনদেনিকরূপে) বেমানান অবস্থায় ফেলে দেবে, সুতরাং এটি সম্ভব নয়।

আংশিক ডাটাবেস প্রাপ্যতা whitepaper একটি দরকারী রেফারেন্স গাইড এবং কিভাবে একটি নির্দিষ্ট টেবিল বা ফাইল অনলাইনে আছে কিনা তা যাচাই করতে একটি উদাহরণ রয়েছে। আপনার ডেটা অ্যাক্সেস যদি সঞ্চিত প্রক্রিয়াগুলির মাধ্যমে হয় তবে আপনি তুলনামূলকভাবে সহজেই সেই চেকটি অন্তর্ভুক্ত করতে পারেন।

আপনার দৃশ্যে নজর দেওয়ার মতো একটি বিকল্প (তবে কিছুটা হ্যাকি) পদ্ধতিটি হ'ল টেবিলটি লুকিয়ে রাখা এবং এটি একটি দর্শন দিয়ে প্রতিস্থাপন করা।

-- NB: SQLCMD script
:ON ERROR EXIT
:setvar DatabaseName "TestRename"
:setvar FilePath "D:\MSSQL\I3\Data\"

SET STATISTICS TIME OFF;
SET STATISTICS IO OFF;
SET NOCOUNT ON;
GO

USE master;
GO

IF EXISTS (SELECT name FROM sys.databases WHERE name = N'$(DatabaseName)')
  DROP DATABASE $(DatabaseName)
GO

CREATE DATABASE $(DatabaseName) 
ON PRIMARY 
  (
  NAME = N' $(DatabaseName)'
  , FILENAME = N'$(FilePath)$(DatabaseName).mdf'
  , SIZE = 5MB
  , MAXSIZE = UNLIMITED
  , FILEGROWTH = 1MB
  ) 
, FILEGROUP [FG1] DEFAULT
  ( 
  NAME = N' $(DatabaseName)_FG1_File1'
  , FILENAME = N'$(FilePath)$(DatabaseName)_FG1_File1.ndf'
  , SIZE = 1MB
  , MAXSIZE = UNLIMITED
  , FILEGROWTH = 1MB 
  ) 
, FILEGROUP [FG2] CONTAINS FILESTREAM
  ( 
  NAME = N'$(DatabaseName)_FG2'
  , FILENAME = N'$(FilePath)Filestream'
  )
LOG ON 
  ( 
  NAME = N'$(DatabaseName)_log'
  , FILENAME = N'$(FilePath)$(DatabaseName)_log.ldf'
  , SIZE = 1MB
  , MAXSIZE = UNLIMITED
  , FILEGROWTH = 1MB
  )
GO

USE $(DatabaseName);
GO

CREATE TABLE [dbo].[BinaryContent](
    [BinaryContentID] [int] IDENTITY(1,1) NOT NULL
    , [FileName] [varchar](50) NOT NULL
    , [BinaryContentRowGUID] [uniqueidentifier] ROWGUIDCOL UNIQUE DEFAULT (NEWSEQUENTIALID()) NOT NULL
  , [FileContentBinary] VARBINARY(max) FILESTREAM  NULL
) ON [PRIMARY] FILESTREAM_ON [FG2]
GO 

-- Insert test rows
INSERT
  dbo.BinaryContent
  (
  [FileName]
  , [FileContentBinary]
  )
VALUES
  (
  CAST(NEWID() AS VARCHAR(36))
  , CAST(REPLICATE(NEWID(), 100) AS VARBINARY)
  );
GO 100

USE master;
GO

-- Take FILESTREAM filegroup offline
ALTER DATABASE $(DatabaseName)
MODIFY FILE (NAME = '$(DatabaseName)_FG2', OFFLINE)
GO

USE $(DatabaseName);
GO

-- Rename table to make way for view
EXEC sp_rename 'dbo.BinaryContent', 'BinaryContentTable', 'OBJECT';
GO

-- Create view to return content from table but with NULL FileContentBinary
CREATE VIEW dbo.BinaryContent
AS

SELECT
  [BinaryContentID]
    , [FileName] 
    , [BinaryContentRowGUID]
  , [FileContentBinary] = NULL
FROM
  [dbo].[BinaryContentTable];
GO

-- Check results as expected
SELECT TOP 10
  *
FROM
  dbo.BinaryContent;
GO

5

আপনি FILESTREAMপৃথক ডাটাবেসে একটি দিয়ে টেবিলটি বিচ্ছিন্ন করতে পারেন এবং PRODUCTIONএকটি ভিউ ব্যবহার করে এটি ডাটাবেসে একটি রেফারেন্স তৈরি করতে পারেন ।

এটি হ্যাকের অবলম্বন না করে আপনি যা চান তা করতে অনুমতি দেবে।


এটি আমার দৃষ্টিভঙ্গি হতে চলেছিল, তবে আমি তখন ডাটাবেসগুলির মধ্যে রেফারেন্সিয়াল অখণ্ডতা বজায় রাখার বিষয়গুলির বিরুদ্ধে উঠেছিলাম, কারণ ট্রিগাররা সাধারণত ফাইলধারার টেবিলগুলি সমর্থন করে না: dba.stackex بدل.com
জন জে স্মিথ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.