Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Se aplica a:SQL Server - Linux
En este artículo se describen las interfaces proporcionadas por el SDK de cliente de la interfaz de dispositivo virtual (VDI) de SQL Server en Linux.
Nota:
Para SQL Server 2022 (16.x) en Linux, puede crear una copia de seguridad de instantáneas de Transact-SQL en su lugar.
Los fabricantes de software independientes (ISV) pueden usar la interfaz de programación de aplicaciones (API) del dispositivo de copia de seguridad virtual para integrar SQL Server en sus productos. En general, VDI en Linux se comporta de forma similar a VDI en Windows, con los cambios siguientes:
- La memoria compartida de Windows se convierte en la memoria compartida de POSIX.
- Los semáforos de Windows se convierten en semáforos de POSIX.
- Los tipos de Windows como
HRESULT
yDWORD
se cambian a números enteros equivalentes. - Las interfaces COM se quitan y se reemplazan por un par de clases de C++.
- SQL Server en Linux no admite instancias con nombre, por lo que se han quitado las referencias al nombre de instancia.
- La biblioteca compartida se implementa en
libsqlvdi.so
, instalada en/opt/mssql/lib/libsqlvdi.so
.
Este artículo es una referencia de anexo a la interfaz de dispositivo virtual (VDI) que detalla las especificaciones VDI de SQL Server en Windows.
Revise también la solución de copia de seguridad de VDI en el repositorio de GitHub de ejemplos de SQL Server.
Configuración de permisos de usuario
En Linux, los primitivos de POSIX son propiedad del usuario que los crea y su grupo predeterminado. Para los objetos creados por SQL Server, estos son propiedad del usuario mssql
y del grupo mssql
predeterminado. Para permitir el uso compartido entre SQL Server y el cliente VDI, se recomienda uno de los dos métodos siguientes:
Ejecute el cliente VDI como usuario
mssql
.Ejecute el siguiente comando para cambiar al usuario de
mssql
:sudo su mssql
Agregue el usuario
mssql
al grupovdiuser
y el usuariovdiuser
al grupomssql
.Ejecute los siguientes comandos:
sudo useradd vdiuser sudo usermod -a -G mssql vdiuser sudo usermod -a -G vdiuser mssql
Reinicie el servidor para seleccionar nuevos grupos de SQL Server y
vdiuser
.
Funciones de cliente
Esta sección contiene descripciones de cada una de las funciones de cliente. Las descripciones incluyen la información siguiente:
- Propósito de la función
- Sintaxis de la función
- Lista de parámetros
- Valores devueltos
- Observaciones
ClientVirtualDeviceSet::Create
Fin
Esta función crea el conjunto de dispositivos virtuales.
Sintaxis
int ClientVirtualDeviceSet::Create (
char * name, // name for the set
VDConfig * cfg // configuration for the set
);
Parámetros | Argumento | Explicación |
---|---|---|
name | Identifica el conjunto de dispositivos virtuales. Deben seguirse las reglas para los nombres usados por CreateFileMapping() . Se puede utilizar cualquier carácter excepto la barra diagonal inversa (\ ). Esta es una cadena de caracteres. Se recomienda agregar un prefijo a la cadena con nombre del producto o la compañía del usuario y el nombre de la base de datos. |
|
cfg | Esta es la configuración del conjunto de dispositivos virtuales. |
Valores devueltos | Argumento | Explicación |
---|---|---|
NOERROR | La función se ha realizado correctamente. | |
VD_E_NOTSUPPORTED | Uno o varios de los campos de la configuración no eran válidos o no se admiten. | |
VD_E_PROTOCOL | El conjunto de dispositivos virtuales ya existe. |
Observaciones
El método Create
solo debe llamarse una vez por operación BACKUP
o RESTORE
. Después de invocar el método Close
, el cliente puede volver a usar la interfaz para crear otro conjunto de dispositivos virtuales.
ClientVirtualDeviceSet::GetConfiguration
Fin
Esta función se usa para esperar a que el servidor configure el conjunto de dispositivos virtuales.
Sintaxis
int ClientVirtualDeviceSet::GetConfiguration (
time_t timeout, // in milliseconds
VDConfig * cfg // selected configuration
);
Parámetros | Argumento | Explicación |
---|---|---|
timeout | Se trata del tiempo de espera, en milisegundos. Use INFINITE o cualquier entero negativo para evitar el tiempo de espera. |
|
cfg | Tras la ejecución correcta, contiene la configuración seleccionada por el servidor. |
Valores devueltos | Argumento | Explicación |
---|---|---|
NOERROR | Se devolvió la configuración. | |
VD_E_ABORT | Se invoca a SignalAbort . |
|
VD_E_TIMEOUT | Se agotó el tiempo de espera de la función. |
Observaciones
Esta función se bloquea en un estado Alertable
. Después de la invocación correcta, se pueden abrir los dispositivos del conjunto de dispositivos virtuales.
ClientVirtualDeviceSet::OpenDevice
Fin
Esta función abre uno de los dispositivos del conjunto de dispositivos virtuales.
Sintaxis
int ClientVirtualDeviceSet::OpenDevice (
char * name, // name for the set
ClientVirtualDevice ** ppVirtualDevice // returns interface to device
);
Parámetros | Argumento | Explicación |
---|---|---|
name | Identifica el conjunto de dispositivos virtuales. | |
ppVirtualDevice | Cuando la función se ejecuta correctamente, se devuelve un puntero al dispositivo virtual. Este dispositivo se usa para GetCommand y CompleteCommand . |
Valores devueltos | Argumento | Explicación |
---|---|---|
NOERROR | La función se ha realizado correctamente. | |
VD_E_ABORT | Se solicitó Abort. | |
VD_E_OPEN | Todos los dispositivos están abiertos. | |
VD_E_PROTOCOL | El conjunto no está en el estado de inicialización o este dispositivo en concreto ya está abierto. | |
VD_E_INVALID | El nombre del dispositivo no es válido. No es uno de los nombres que se sabe que forman el conjunto. |
Observaciones
VD_E_OPEN
podría devolverse sin problema. El cliente puede llamar a OpenDevice
por medio de un bucle hasta que se devuelva este código.
Si se configura más de un dispositivo, por ejemplo n dispositivos, el conjunto de dispositivos virtuales devuelve n interfaces de dispositivo únicas.
Se puede usar la función GetConfiguration
para esperar hasta que se puedan abrir los dispositivos.
Si esta función no se realiza correctamente, se devuelve un valor NULL a través de ppVirtualDevice
.
ClientVirtualDevice::GetCommand
Fin
Esta función se usa para obtener el siguiente comando en cola en un dispositivo. Cuando se solicita, esta función espera el siguiente comando.
Sintaxis
int ClientVirtualDevice::GetCommand (
time_t timeout, // time-out in milliseconds
VDC_Command** ppCmd // returns the next command
);
Parámetros | Argumento | Explicación |
---|---|---|
timeout | Se trata del tiempo de espera, en milisegundos. Use INFINITE para esperar indefinidamente. Use 0 para sondear un comando. Se devuelve VD_E_TIMEOUT si no hay ningún comando disponible actualmente. Si se agota el tiempo de espera, el cliente decide la siguiente acción. |
|
Tiempo de espera | Se trata del tiempo de espera, en milisegundos. Use INFINITE o un valor negativo para esperar indefinidamente. Use 0 para sondear un comando. Se devuelve VD_E_TIMEOUT si no hay ningún comando disponible antes de que el tiempo de expiración se agote. Si se agota el tiempo de expiración, el cliente decide la siguiente acción. |
|
ppCmd | Cuando un comando se devuelve correctamente, el parámetro devuelve la dirección de un comando que se va a ejecutar. La memoria devuelta es de solo lectura. Cuando se completa el comando, este puntero se pasa a la rutina CompleteCommand . |
Valores devueltos | Argumento | Explicación |
---|---|---|
NOERROR | Se ha capturado un comando. | |
VD_E_CLOSE | El servidor ha cerrado el dispositivo. | |
VD_E_TIMEOUT | No había ningún comando disponible y se agotó el tiempo de espera. | |
VD_E_ABORT | El cliente o el servidor han usado el elemento SignalAbort para forzar un apagado. |
Observaciones
Cuando se devuelve VD_E_CLOSE
, SQL Server ha cerrado el dispositivo. Esto forma parte del apagado normal. Una vez cerrados todos los dispositivos, el cliente invoca ClientVirtualDeviceSet::Close
para cerrar el conjunto de dispositivos virtuales.
Cuando esta rutina debe bloquearse para esperar un comando, el subproceso se deja en una condición de Alertable
.
ClientVirtualDevice::CompleteCommand
Fin
Esta función se usa para notificar a SQL Server que un comando ha finalizado. Se debe devolver la información de finalización adecuada para el comando.
Sintaxis
int ClientVirtualDevice::CompleteCommand (
VDC_Command pCmd, // the command
int completionCode, // completion code
unsigned long bytesTransferred, // bytes transferred
int64_t position // current position
);
Parámetros | Argumento | Explicación |
---|---|---|
pCmd | Se trata de la dirección de un comando devuelto anteriormente desde ClientVirtualDevice::GetCommand . |
|
completionCode | Se trata de un código de estado que indica el estado de finalización. Este parámetro debe devolverse para todos los comandos. El código devuelto debe ser adecuado para el comando que se va a realizar. ERROR_SUCCESS se usa en todos los casos para indicar un comando ejecutado correctamente. Para obtener una lista completa de los posibles códigos, consulte el archivo vdierror.h . |
|
bytesTransferred | Se trata del número de bytes transferidos correctamente. Solo se devuelve para los comandos de transferencia de datos de Read y Write . |
|
position | Esta es solo una respuesta al comando GetPosition . |
Valores devueltos | Argumento | Explicación |
---|---|---|
NOERROR | La finalización se anotó correctamente. | |
VD_E_INVALID | pCmd no era un comando activo. |
|
VD_E_ABORT | Abort se señalizó. |
|
VD_E_PROTOCOL | El dispositivo no está abierto. |
Observaciones
Ninguno
ClientVirtualDeviceSet::SignalAbort
Fin
Esta función se usa para indicar que debe producirse una finalización anómala.
Sintaxis
int ClientVirtualDeviceSet::SignalAbort ();
Parámetros | Argumento | Explicación |
---|---|---|
Ninguno | No aplicable |
Valores devueltos | Argumento | Explicación |
---|---|---|
NOERROR | La notificación de Abort se envió correctamente. |
Observaciones
En cualquier momento, el cliente puede optar por anular la operación BACKUP
o RESTORE
. Esta rutina indica que todas las operaciones deben cesar. El estado del conjunto de dispositivos virtuales completo entra en el estado Abnormally Terminated
. No se devuelven más comandos en ningún dispositivo. Todos los comandos incompletos se completan automáticamente y devuelven ERROR_OPERATION_ABORTED
como código de finalización. El cliente debe llamar a ClientVirtualDeviceSet::Close
una vez que haya finalizado de forma segura cualquier uso pendiente de los búferes proporcionados al cliente.
ClientVirtualDeviceSet::Close
Fin
Esta función cierra el conjunto de dispositivos virtuales creado por ClientVirtualDeviceSet::Create
. Como resultado, se liberan todos los recursos asociados al conjunto de dispositivos virtuales.
Sintaxis
int ClientVirtualDeviceSet::Close ();
Parámetros | Argumento | Explicación |
---|---|---|
Ninguno | No aplicable |
Valores devueltos | Argumento | Explicación |
---|---|---|
NOERROR | Se devuelve cuando el conjunto de dispositivos virtuales se ha cerrado correctamente. | |
VD_E_PROTOCOL | No se realizó ninguna acción porque el conjunto de dispositivos virtuales no estaba abierto. | |
VD_E_OPEN | Los dispositivos aún estaban abiertos. |
Observaciones
La invocación de Close
es una declaración del cliente de que se deben liberar todos los recursos usados por el conjunto de dispositivos virtuales. El cliente debe asegurarse de que toda actividad que implique búferes de datos y dispositivos virtuales haya finalizado antes de invocar Close
. Todas las interfaces de dispositivo virtual devueltas por OpenDevice
se invalidan con Close
.
El cliente puede emitir una llamada a Create
en la interfaz del conjunto de dispositivos virtuales después de que se devuelva la llamada a Close
. Esta llamada crearía un nuevo conjunto de dispositivos virtuales para una operación BACKUP
o RESTORE
posterior.
Si se llama a Close
cuando uno o más dispositivos virtuales están todavía abiertos, se devuelve VD_E_OPEN
. En este caso, SignalAbort
se desencadena internamente para garantizar un apagado adecuado si es posible. Se publican los recursos de VDI. El cliente debe esperar una indicación VD_E_CLOSE
en cada dispositivo antes de invocar ClientVirtualDeviceSet::Close
. Si el cliente sabe que el conjunto de dispositivos virtuales ya está en un estado Abnormally Terminated
, no debería esperar una indicación VD_E_CLOSE
de GetCommand
y puede invocar ClientVirtualDeviceSet::Close
tan pronto como se termine la actividad en los búferes compartidos.
ClientVirtualDeviceSet::OpenInSecondary
Fin
Esta función abre el conjunto de dispositivos virtuales en un cliente secundario. El cliente principal ya debe haber usado Create
y GetConfiguration
para configurar el conjunto de dispositivos virtuales.
Sintaxis
int ClientVirtualDeviceSet::OpenInSecondary (
char * setName // name of the set
);
Parámetros | Argumento | Explicación |
---|---|---|
setName | Identifica el conjunto. Este nombre distingue entre mayúsculas y minúsculas y debe coincidir con el nombre usado por el cliente principal cuando invocó ClientVirtualDeviceSet::Create . |
Valores devueltos | Argumento | Explicación |
---|---|---|
NOERROR | La función se ha realizado correctamente. | |
VD_E_PROTOCOL | No se ha creado el conjunto de dispositivos virtuales, ya se ha abierto en este cliente o el conjunto de dispositivos virtuales no está listo para aceptar solicitudes abiertas de clientes secundarios. | |
VD_E_ABORT | La operación se va a anular. |
Notas Cuando se usa un modelo de varios procesos, el cliente principal es responsable de detectar la finalización normal y anómala de clientes secundarios.
ClientVirtualDeviceSet::GetBufferHandle
Fin
Algunas aplicaciones pueden requerir más de un proceso para operar sobre los búferes devueltos por ClientVirtualDevice::GetCommand
. En tales casos, el proceso que recibe el comando puede usar GetBufferHandle
para obtener un identificador independiente del proceso que identifica el búfer. Este identificador se puede comunicar a cualquier otro proceso que también tenga abierto el mismo conjunto de dispositivos virtuales. Ese proceso usaría ClientVirtualDeviceSet::MapBufferHandle
entonces para obtener la dirección del búfer. Es probable que la dirección que obtenga sea distinta a la de su asociado, ya que cada proceso puede asignar búferes en direcciones diferentes.
Sintaxis
int ClientVirtualDeviceSet::GetBufferHandle (
uint8_t* pBuffer, // in: buffer address
unsigned int* pBufferHandle // out: buffer handle
);
Parámetros | Argumento | Explicación |
---|---|---|
pBuffer | Se trata de la dirección de un búfer que se obtiene de un comando de Read o Write . |
|
BufferHandle | Devuelve un identificador único para el búfer. |
Valores devueltos | Argumento | Explicación |
---|---|---|
NOERROR | La función se ha realizado correctamente. | |
VD_E_PROTOCOL | El conjunto de dispositivos virtuales no está abierto actualmente. | |
VD_E_INVALID | pBuffer no es una dirección válida. |
Observaciones
El proceso que invoca la función GetBufferHandle
es responsable de invocar ClientVirtualDevice::CompleteCommand
cuando se complete la transferencia de datos.
ClientVirtualDeviceSet::MapBufferHandle
Fin
Esta función se usa para obtener una dirección de búfer válida de un identificador de búfer obtenido de algún otro proceso.
Sintaxis
int ClientVirtualDeviceSet::MapBufferHandle (
int dwBuffer, // in: buffer handle
uint8_t** ppBuffer // out: buffer address
);
Parámetros | Argumento | Explicación |
---|---|---|
dwBuffer | Este es el identificador devuelto por ClientVirtualDeviceSet::GetBufferHandle . |
|
ppBuffer | Dirección del búfer que es válido en el proceso actual. |
Valores devueltos | Argumento | Explicación |
---|---|---|
NOERROR | La función se ha realizado correctamente. | |
VD_E_PROTOCOL | El conjunto de dispositivos virtuales no está abierto actualmente. | |
VD_E_INVALID | ppBuffer es un identificador no válido. |
Observaciones
Tenga cuidado en comunicar correctamente los identificadores. Los identificadores son locales para un único conjunto de dispositivos virtuales. Los procesos de asociados que comparten un identificador deben asegurarse de que los identificadores de búfer solo se usan dentro del ámbito del conjunto de dispositivos virtuales del que se obtuvo originalmente el búfer.