You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
235 lines
7.9 KiB
235 lines
7.9 KiB
//
|
|
// sqlsnap.h Define the interface to the nt/sql snapshot handler.
|
|
//
|
|
// The idea here is for a pure interface, making it easy to keep the
|
|
// abstraction maximized (can move to COM later, if we like).
|
|
//
|
|
// No C++ exceptions will be thrown across the interfaces.
|
|
//
|
|
// To use this interface, the calling process must invoke:
|
|
// InitSQLEnvironment - once to setup the environment, establishing
|
|
// the error and trace loggers.
|
|
// The trace logger is optional, but an error logger must be provided.
|
|
// The loggers are created by deriving from CLogFacility and implementing
|
|
// a "WriteImplementation" method.
|
|
//
|
|
// Thereafter, calls to "CreateSqlSnapshot" are used to create snapshot objects
|
|
// which encapsulate the operations needed to support storage snapshots.
|
|
//
|
|
// *****************************************
|
|
// LIMITATIONS
|
|
//
|
|
// - only SIMPLE databases can be snapshot (trunc on checkpoint = 'true')
|
|
// Exception: SQL2000 full recovery db's are allowed. But master can't be restored with them.
|
|
// - there is no serialization of services starting or adding/changing file lists during the snapshot
|
|
// - servers which are not started when the snapshot starts are skipped (non-torn databases will be
|
|
// backed up fine, torn databases won't be detected).
|
|
// - sql7.0 databases which are "un"-useable will prevent snapshots (the list of files can't be obtained).
|
|
//
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <windows.h>
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Standard foo for file name aliasing. This code block must be after
|
|
// all includes of VSS header files.
|
|
//
|
|
#ifdef VSS_FILE_ALIAS
|
|
#undef VSS_FILE_ALIAS
|
|
#endif
|
|
#define VSS_FILE_ALIAS "INCSQLSH"
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT InitSQLEnvironment();
|
|
|
|
// Caller must provide a path checker interface.
|
|
// Used to provide info about the snapshot
|
|
class CCheckPath
|
|
{
|
|
public:
|
|
|
|
// ComponentBased snapshots can deal with non-simple recovery.
|
|
// The backup app must handle VDI metadata if rollforward will be supported.
|
|
//
|
|
virtual
|
|
bool
|
|
IsComponentBased () throw() = 0;
|
|
|
|
// ComponentBased snapshots provide an explicit list of databases
|
|
//
|
|
virtual
|
|
PCWSTR
|
|
EnumerateSelectedDatabases (const WCHAR *instanceName, UINT* nextIndex) throw () = 0;
|
|
|
|
// return true if Path is part of the snapshot
|
|
// Only intended for non-component-based backups.
|
|
//
|
|
virtual
|
|
bool
|
|
IsPathInSnapshot (const WCHAR* path) throw () = 0;
|
|
};
|
|
|
|
//------------------------------------------------------------------
|
|
// Provide information Post-Freeze (or Thaw) about the databases
|
|
// which were frozen and which support VDI metadata.
|
|
//
|
|
struct FrozenDatabaseInfo
|
|
{
|
|
const WCHAR* serverName;
|
|
const WCHAR* databaseName;
|
|
// BOOL isSimpleRecovery; THIS ISN'T CONVENIENTLY AVAILABLE....DO WE NEED IT?
|
|
UINT metaDataSize;
|
|
const BYTE* pMetaData;
|
|
};
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
// A handler for snapshots.
|
|
//
|
|
class CSqlSnapshot
|
|
{
|
|
public:
|
|
virtual ~CSqlSnapshot () throw () {};
|
|
|
|
virtual HRESULT Prepare (
|
|
CCheckPath* checker) throw () = 0;
|
|
|
|
virtual HRESULT Freeze () throw () = 0;
|
|
|
|
virtual HRESULT Thaw () throw () = 0;
|
|
|
|
// Call this at "Post-snapshot" time, after all databases are frozen and MD is complete.
|
|
//
|
|
// Iterate over the databases which were frozen.
|
|
// Valid to call this after Freeze, Thaw until destruction or Prepare().
|
|
//
|
|
virtual HRESULT GetFirstDatabase (FrozenDatabaseInfo* fInfo) throw () = 0;
|
|
virtual HRESULT GetNextDatabase (FrozenDatabaseInfo* fInfo) throw () = 0;
|
|
};
|
|
|
|
extern "C" CSqlSnapshot* CreateSqlSnapshot () throw ();
|
|
|
|
//-------------------------------------------------------------
|
|
// Handle the restore operations for "composite restore" situations.
|
|
//
|
|
// An object is used to cache the connection to a single instance.
|
|
// Thus the caller should perform operations grouped by instance.
|
|
//
|
|
class CSqlRestore
|
|
{
|
|
public:
|
|
// Inform SQLServer that data laydown is desired on the full database.
|
|
// Performs a DETACH, freeing the files.
|
|
//
|
|
virtual HRESULT PrepareToRestore (
|
|
const WCHAR* pInstance,
|
|
const WCHAR* pDatabase)
|
|
throw () = 0;
|
|
|
|
// After data is laid down, this performs RESTORE WITH SNAPSHOT[,NORECOVERY]
|
|
//
|
|
virtual HRESULT FinalizeRestore (
|
|
const WCHAR* pInstance,
|
|
const WCHAR* pDatabase,
|
|
bool compositeRestore, // true if WITH NORECOVERY desired
|
|
const BYTE* pMetadata, // metadata obtained from BACKUP
|
|
unsigned int dataLen) // size of metadata (in bytes)
|
|
throw () = 0;
|
|
};
|
|
|
|
extern "C" CSqlRestore* CreateSqlRestore () throw ();
|
|
|
|
//-------------------------------------------------------------
|
|
// An enumerator for SQL objects.
|
|
//
|
|
// An object of this class can have only one active query at
|
|
// a time. Requesting a new enumeration will close any previous
|
|
// partially fetched result.
|
|
//
|
|
#define MAX_SERVERNAME 128
|
|
#define MAX_DBNAME 128
|
|
struct ServerInfo
|
|
{
|
|
bool isOnline; // true if the server is ready for connections
|
|
|
|
// bool supportsCompositeRestore; // true if >=SQL2000 (RESTORE WITH NORECOVERY,SNAPSHOT)
|
|
// not readily available. Ask Brian if we really need it....
|
|
// this is easy to obtain when the databases are being enumerated.
|
|
//
|
|
|
|
WCHAR name [MAX_SERVERNAME]; // null terminated name of server
|
|
};
|
|
struct DatabaseInfo
|
|
{
|
|
bool isSimpleRecovery; // true if the recovery model is "SIMPLE"
|
|
bool supportsFreeze; // true if this database can freeze (via dbcc or backup)
|
|
UINT32 status; // status bits
|
|
WCHAR name [MAX_DBNAME]; // null terminated name of database
|
|
};
|
|
struct DatabaseFileInfo
|
|
{
|
|
bool isLogFile; // true if this is a log file
|
|
WCHAR name [MAX_PATH];
|
|
};
|
|
|
|
|
|
// A heirarchical enumerator
|
|
// server(instance) (1:N) databases (1:N) files
|
|
// ...add doc...
|
|
//
|
|
class CSqlEnumerator
|
|
{
|
|
public:
|
|
virtual ~CSqlEnumerator () throw () {};
|
|
|
|
virtual HRESULT FirstServer (
|
|
ServerInfo* pServer) throw () = 0;
|
|
|
|
virtual HRESULT NextServer (
|
|
ServerInfo* pServer) throw () = 0;
|
|
|
|
virtual HRESULT FirstDatabase (
|
|
const WCHAR* pServerName,
|
|
DatabaseInfo* pDbInfo) throw () = 0;
|
|
|
|
virtual HRESULT NextDatabase (
|
|
DatabaseInfo* pDbInfo) throw () = 0;
|
|
|
|
virtual HRESULT FirstFile (
|
|
const WCHAR* pServerName,
|
|
const WCHAR* pDbName,
|
|
DatabaseFileInfo* pFileInfo) throw () = 0;
|
|
|
|
virtual HRESULT NextFile (
|
|
DatabaseFileInfo* pFileInfo) throw () = 0;
|
|
};
|
|
|
|
extern "C" CSqlEnumerator* CreateSqlEnumerator () throw ();
|
|
|
|
|
|
//------------------------------------------------------
|
|
// HRESULTS returned by the interface.
|
|
//
|
|
// WARNING: I used facility = x78 arbitrarily!
|
|
//
|
|
#define SQLLIB_ERROR(code) MAKE_HRESULT(SEVERITY_ERROR, 0x78, code)
|
|
#define SQLLIB_STATUS(code) MAKE_HRESULT(SEVERITY_SUCCESS, 0x78, code)
|
|
|
|
// Status codes
|
|
//
|
|
#define S_SQLLIB_NOSERVERS SQLLIB_STATUS(1) // no SQLServers of interest (from Prepare)
|
|
|
|
// Error codes
|
|
//
|
|
#define E_SQLLIB_GENERIC SQLLIB_ERROR(1) // something bad, check the errorlog
|
|
|
|
#define E_SQLLIB_TORN_DB SQLLIB_ERROR(2) // database would be torn by the snapshot
|
|
|
|
#define E_SQLLIB_NO_SUPPORT SQLLIB_ERROR(3) // 6.5 doesn't support snapshots
|
|
|
|
#define E_SQLLIB_PROTO SQLLIB_ERROR(4) // protocol error (ex: freeze before prepare)
|
|
|
|
#define E_SQLLIB_NONSIMPLE SQLLIB_ERROR(5) // only simple databases are supported
|
|
|
|
|