Leaked source code of windows server 2003
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

//
// 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