적용 대상:SQL Server on Linux
이 문서에서는 Linux의 SQL Server 가상 디바이스 인터페이스(VDI) 클라이언트 SDK에서 제공하는 인터페이스에 대해 설명합니다.
참고 항목
Linux의 SQL Server 2022(16.x)의 경우 Transact-SQL 스냅샷 백업을 대신 만들 수 있습니다.
독립 소프트웨 공급업체 (ISV)는 가상 백업 디바이스 API(애플리케이션 프로그래밍 인터페이스)를 사용하여 SQL Server를 해당 제품에 통합합니다. 일반적으로 Linux의 VDI는 다음과 같이 변경된 Windows의 VDI와 유사하게 작동합니다.
- Windows 공유 메모리는 POSIX 공유 메모리가 됩니다.
- Windows 세마포는 POSIX 세마포가 됩니다.
- Windows 형식
HRESULT과DWORD은 같은 정수 형식으로 변경됩니다. - COM 인터페이스가 제거되고 C++ 클래스 쌍으로 대체됩니다.
- SQL Server on Linux는 명명된 인스턴스를 지원하지 않으므로 인스턴스 이름에 대한 참조가 제거되었습니다.
- 공유 라이브러리는
libsqlvdi.so에 구현되고/opt/mssql/lib/libsqlvdi.so에 설치됩니다.
이 문서는 Windows의 SQL Server VDI 사양을 자세히 설명한 VDI(가상 디바이스 인터페이스) 참조 에 대한 부록입니다.
또한 SQL Server 샘플 GitHub 리포지토리에서 샘플 VDI 백업 솔루션을 검토합니다.
사용자 권한 설정
Linux에서 POSIX 기본 형식은 기본 형식을 만드는 사용자 및 해당 기본 그룹이 소유합니다. SQL Server에서 만든 개체의 경우 기본적으로 mssql사용자와 mssql 그룹이 소유합니다. SQL Server와 VDI 클라이언트 간에 공유를 허용하려면 다음 두 가지 방법 중 하나를 사용하는 것이 좋습니다.
mssql사용자로 VDI 클라이언트 실행합니다.다음 명령을 실행하여
mssql사용자로 전환합니다.sudo su mssqlmssql사용자를vdiuser그룹에 추가하고vdiuser사용자를mssql그룹에 추가합니다.다음 명령을 실행합니다.
sudo useradd vdiuser sudo usermod -a -G mssql vdiuser sudo usermod -a -G vdiuser mssql서버를 다시 시작하여 SQL Server 및
vdiuser에 대한 새 그룹을 선택합니다.
클라이언트 함수
이 섹션에는 각 클라이언트 함수에 대한 설명이 포함되어 있습니다. 설명에는 다음 정보가 포함됩니다.
- 함수 용도
- 함수 구문
- 매개 변수 목록
- 반환 값
- 설명
ClientVirtualDeviceSet::Create
목적
이 함수는 가상 디바이스 세트를 만듭니다.
구문
int ClientVirtualDeviceSet::Create (
char * name, // name for the set
VDConfig * cfg // configuration for the set
);
| 매개 변수 | 인수 | 설명 |
|---|---|---|
| 이름 | 가상 디바이스 세트를 식별합니다.
CreateFileMapping()에서 사용되는 이름에 대한 규칙을 따라야 합니다. 백슬래시(\)를 제외한 모든 문자를 사용할 수 있습니다. 문자열입니다. 문자열에 사용자의 제품 또는 회사 이름 및 데이터베이스 이름을 접두사로 지정하는 것이 좋습니다. |
|
| cfg | 가상 디바이스 세트의 구성입니다. |
| 반환 값 | 인수 | 설명 |
|---|---|---|
| NOERROR | 함수가 성공했습니다. | |
| VD_E_NOTSUPPORTED | 구성에서 하나 이상의 필드가 잘못되었거나 지원되지 않습니다. | |
| VD_E_PROTOCOL | 가상 디바이스 세트가 이미 있습니다. |
설명
Create 메서드는 BACKUP 또는 RESTORE 작업당 한 번만 호출해야 합니다.
Close 메서드를 호출한 후 클라이언트는 인터페이스를 다시 사용하여 다른 가상 디바이스 세트를 만들 수 있습니다.
ClientVirtualDeviceSet::GetConfiguration
목적
이 함수는 서버가 가상 디바이스 세트를 구성할 때까지 기다리는 데 사용됩니다.
구문
int ClientVirtualDeviceSet::GetConfiguration (
time_t timeout, // in milliseconds
VDConfig * cfg // selected configuration
);
| 매개 변수 | 인수 | 설명 |
|---|---|---|
| timeout | 밀리초 단위의 시간 초과입니다. 시간 초과를 방지하려면 INFINITE 또는 음의 정수를 사용합니다. |
|
| cfg | 성공적으로 실행되면 서버에서 선택한 구성이 포함됩니다. |
| 반환 값 | 인수 | 설명 |
|---|---|---|
| NOERROR | 구성이 반환되었습니다. | |
| VD_E_ABORT |
SignalAbort가 호출되었습니다. |
|
| VD_E_TIMEOUT | 함수 시간이 초과되었습니다. |
설명
이 함수는 Alertable 상태에서 차단합니다. 호출에 성공하면 가상 디바이스 세트의 디바이스가 열릴 수 있습니다.
ClientVirtualDeviceSet::OpenDevice
목적
이 함수는 가상 디바이스 세트의 디바이스 중 하나를 엽니다.
구문
int ClientVirtualDeviceSet::OpenDevice (
char * name, // name for the set
ClientVirtualDevice ** ppVirtualDevice // returns interface to device
);
| 매개 변수 | 인수 | 설명 |
|---|---|---|
| 이름 | 가상 디바이스 세트를 식별합니다. | |
| ppVirtualDevice | 함수가 성공하면 가상 디바이스에 대한 포인터가 반환됩니다. 이 장치는 GetCommand과 CompleteCommand에 사용됩니다. |
| 반환 값 | 인수 | 설명 |
|---|---|---|
| NOERROR | 함수가 성공했습니다. | |
| VD_E_ABORT | 중단이 요청되었습니다. | |
| VD_E_OPEN | 모든 디바이스가 열려 있습니다. | |
| VD_E_PROTOCOL | 세트가 초기화 상태가 아니거나 이 특정 디바이스가 이미 열려 있습니다. | |
| VD_E_INVALID | 디바이스 이름이 잘못되었습니다. 세트를 구성하는 것으로 알려진 이름 중 하나가 아닙니다. |
설명
VD_E_OPEN는 문제 없이 반환될 수 있습니다. 클라이언트는 이 코드가 반환될 때까지 루프를 통해 OpenDevice를 호출 할 수 있습니다.
두 개 이상의 디바이스(예: n개 디바이스)가 구성된 경우 가상 디바이스 세트는 n개의 고유한 디바이스 인터페이스를 반환합니다.
GetConfiguration 함수는 디바이스를 열 수 있을 때까지 대기하는 데 사용할 수 있습니다.
이 함수가 성공하지 못하면 null 값이 ppVirtualDevice를 통해 반환됩니다.
ClientVirtualDevice::GetCommand
목적
이 함수는 디바이스의 큐에 대기 중인 다음 명령을 가져오는 데 사용됩니다. 요청되면 이 함수는 다음 명령을 기다립니다.
구문
int ClientVirtualDevice::GetCommand (
time_t timeout, // time-out in milliseconds
VDC_Command** ppCmd // returns the next command
);
| 매개 변수 | 인수 | 설명 |
|---|---|---|
| timeout | 대기할 시간(밀리초)입니다. 무한정 기다리려면 INFINITE을 사용합니다. 명령을 폴링하는 데 0를 사용합니다.
VD_E_TIMEOUT은 현재 사용할 수 있는 명령이 없는 경우 반환됩니다. 시간 초과가 발생하면 클라이언트는 다음 작업을 결정합니다. |
|
| 시간 제한 | 대기할 시간(밀리초)입니다. 무기한 대기하려면 INFINITE 또는 음수 값을 사용합니다. 명령을 폴링하려면 0을 사용합니다.
VD_E_TIMEOUT는 제한 시간이 만료되기 전에 사용할 수 있는 명령이 없으면 반환됩니다. 시간 초과가 발생하면 클라이언트는 다음 작업을 결정합니다. |
|
| ppCmd | 명령이 성공적으로 반환되면 매개 변수는 실행할 명령의 주소를 반환합니다. 반환된 메모리는 읽기 전용입니다. 명령이 완료되면 이 포인터가 CompleteCommand 루틴으로 전달됩니다. |
| 반환 값 | 인수 | 설명 |
|---|---|---|
| NOERROR | 명령을 가져왔습니다. | |
| VD_E_CLOSE | 서버에서 디바이스를 닫았습니다. | |
| VD_E_TIMEOUT | 사용할 수 있는 명령이 없고 제한 시간이 만료되었습니다. | |
| VD_E_ABORT | 클라이언트 또는 서버에서 SignalAbort를 사용하여 강제 종료했습니다. |
설명
VD_E_CLOSE가 반환될 때 SQL Server가 디바이스를 닫았습니다. 정상적인 종료의 일부입니다. 모든 디바이스가 닫힌 후 클라이언트는 가상 디바이스 세트를 닫기 위해 ClientVirtualDeviceSet::Close를 호출합니다.
이 루틴이 명령 대기를 차단해야 하는 경우 스레드는 Alertable 상태로 남습니다.
ClientVirtualDevice::CompleteCommand
목적
이 함수는 명령이 완료되었음을 SQL Server에 알리는 데 사용됩니다. 명령에 적합한 완료 정보를 반환해야 합니다.
구문
int ClientVirtualDevice::CompleteCommand (
VDC_Command pCmd, // the command
int completionCode, // completion code
unsigned long bytesTransferred, // bytes transferred
int64_t position // current position
);
| 매개 변수 | 인수 | 설명 |
|---|---|---|
| pCmd | 이 주소는 이전에 ClientVirtualDevice::GetCommand에서 반환된 명령의 주소입니다. |
|
| completionCode | 완료 상태를 나타내는 상태 코드입니다. 이 매개 변수는 모든 명령에 대해 반환되어야 합니다. 반환된 코드는 실행 중인 명령에 적합해야 합니다.
ERROR_SUCCESS는 성공적으로 실행된 명령을 나타내기 위해 모든 경우에 사용됩니다. 가능한 코드의 전체 목록은 vdierror.h 파일을 참조하세요. |
|
| bytesTransferred | 성공적으로 전송된 바이트 수입니다. 이 값은 데이터 전송 명령 Read 및 Write에 대해서만 반환됩니다. |
|
| 위치 |
GetPosition 명령에만 해당하는 응답입니다. |
| 반환 값 | 인수 | 설명 |
|---|---|---|
| NOERROR | 완료가 올바르게 기록되었습니다. | |
| VD_E_INVALID |
pCmd는 활성 명령이 아닙니다. |
|
| VD_E_ABORT |
Abort 신호를 받았습니다. |
|
| VD_E_PROTOCOL | 디바이스가 열려 있지 않습니다. |
설명
None
ClientVirtualDeviceSet::SignalAbort
목적
이 함수는 비정상적인 종료가 발생해야 하다는 신호를 표시하는 데 사용됩니다.
구문
int ClientVirtualDeviceSet::SignalAbort ();
| 매개 변수 | 인수 | 설명 |
|---|---|---|
| None | 해당 없음 |
| 반환 값 | 인수 | 설명 |
|---|---|---|
| NOERROR |
Abort 알림이 성공적으로 게시되었습니다. |
설명
언제든지 클라이언트는 BACKUP 또는 RESTORE 작업을 중단하도록 선택할 수 있습니다. 이 루틴은 모든 작업이 중단되어야 한다는 신호를 표시합니다. 전체 가상 디바이스 세트의 상태가 Abnormally Terminated 상태로 전환됩니다. 모든 디바이스에서 추가 명령이 반환되지 않습니다. 완료되지 않은 모든 명령은 자동으로 완료되고 ERROR_OPERATION_ABORTED 완료 코드로 반환 됩니다. 클라이언트는 클라이언트에 제공된 버퍼의 처리되지 않은 사용을 안전하게 종료한 후 ClientVirtualDeviceSet::Close를 호출해야 합니다.
ClientVirtualDeviceSet::Close
목적
이 함수는 ClientVirtualDeviceSet::Create에 의해 생성된 가상 디바이스 세트를 닫습니다. 그러면 가상 디바이스 세트와 연결된 모든 리소스가 릴리스됩니다.
구문
int ClientVirtualDeviceSet::Close ();
| 매개 변수 | 인수 | 설명 |
|---|---|---|
| None | 해당 없음 |
| 반환 값 | 인수 | 설명 |
|---|---|---|
| NOERROR | 가상 디바이스 세트가 성공적으로 닫혔을 때 반환됩니다. | |
| VD_E_PROTOCOL | 가상 디바이스 세트가 열려 있지 않아서 아무 작업도 수행되지 않았습니다. | |
| VD_E_OPEN | 장치가 여전히 열려 있었습니다. |
설명
Close의 호출은 가상 디바이스 세트에서 사용하는 모든 리소스를 해제해야 한다는 클라이언트 선언입니다. 클라이언트는 Close를 호출하기 전에 데이터 버퍼 및 가상 디바이스와 관련된 모든 작업이 종료되었는지 확인해야 합니다.
OpenDevice로 반환된 모든 가상 디바이스 인터페이스는 Close에 의해 무효화됩니다.
클라이언트는 Create 호출이 반환된 후에 가상 디바이스 세트 인터페이스에서 Close 호출을 실행할 수 있습니다. 이러한 호출은 후속 BACKUP 또는 RESTORE 작업에 대한 새 가상 디바이스 세트를 만듭니다.
하나 이상의 가상 디바이스가 여전히 열려 있을 때 Close가 호출되는 경우 VD_E_OPEN가 반환됩니다. 이 경우 가능하면 적절한 종료를 보장하기 위해 내부적으로 SignalAbort가 트리거됩니다. VDI 리소스가 해제됩니다. 클라이언트는 VD_E_CLOSE를 호출하기 전에 각 디바이스에서 ClientVirtualDeviceSet::Close 표시를 기다려야 합니다. 클라이언트가 가상 디바이스 세트가 이미 Abnormally Terminated 상태임을 알고 있는 경우 VD_E_CLOSE에서 GetCommand 표시를 기대하지 않아야 하며, 공유 버퍼에 대한 작업이 종료되는 즉시 ClientVirtualDeviceSet::Close를 호출할 수 있습니다.
ClientVirtualDeviceSet::OpenInSecondary
목적
이 함수는 보조 클라이언트에서 가상 디바이스 세트를 엽니다. 기본 클라이언트는 이미 Create 및 GetConfiguration을 사용하여 가상 디바이스 세트를 설정했어야 합니다.
구문
int ClientVirtualDeviceSet::OpenInSecondary (
char * setName // name of the set
);
| 매개 변수 | 인수 | 설명 |
|---|---|---|
| SetName | 세트를 식별합니다. 이 이름은 대/소문자를 구분하며 ClientVirtualDeviceSet::Create를 호출할 때 기본 클라이언트에서 사용하는 이름과 일치해야 합니다. |
| 반환 값 | 인수 | 설명 |
|---|---|---|
| NOERROR | 함수가 성공했습니다. | |
| VD_E_PROTOCOL | 가상 디바이스 세트가 만들어지지 않았거나, 이 클라이언트에서 이미 열려 있거나, 가상 디바이스 세트가 보조 클라이언트에서 열린 요청을 수락할 준비가 되지 않았습니다. | |
| VD_E_ABORT | 작업이 중단되고 있습니다. |
설명 다중 프로세스 모델을 사용하는 경우 기본 클라이언트는 보조 클라이언트의 정상적인 종료와 비정상적인 종료를 탐지해야 합니다.
ClientVirtualDeviceSet::GetBufferHandle
목적
일부 애플리케이션에서 ClientVirtualDevice::GetCommand가 반환된 버퍼에서 작동하려면 둘 이상의 프로세스가 필요할 수 있습니다. 이 경우 명령을 수신하는 프로세스는 GetBufferHandle을 사용하여 버퍼를 식별하는 프로세스 독립 핸들을 가져올 수 있습니다. 그런 다음, 이 핸들은 동일한 가상 디바이스 세트가 열려 있는 다른 프로세스에 전달될 수 있습니다. 그런 다음 해당 프로세스는 ClientVirtualDeviceSet::MapBufferHandle를 사용하여 버퍼의 주소를 가져옵니다. 각 프로세스는 서로 다른 주소에서 버퍼를 매핑할 수 있으므로 주소는 파트너와 다른 주소일 수 있습니다.
구문
int ClientVirtualDeviceSet::GetBufferHandle (
uint8_t* pBuffer, // in: buffer address
unsigned int* pBufferHandle // out: buffer handle
);
| 매개 변수 | 인수 | 설명 |
|---|---|---|
| pBuffer | 이 주소는 Read 또는 Write 명령에서 가져온 버퍼의 주소입니다. |
|
| BufferHandle | 버퍼의 고유 식별자가 반환됩니다. |
| 반환 값 | 인수 | 설명 |
|---|---|---|
| NOERROR | 함수가 성공했습니다. | |
| VD_E_PROTOCOL | 가상 디바이스 세트는 현재 열려 있지 않습니다. | |
| VD_E_INVALID |
pBuffer는 유효한 주소가 아닙니다. |
설명
GetBufferHandle함수를 호출하는 프로세스는 데이터 전송이 완료된 경우 ClientVirtualDevice::CompleteCommand 호출을 담당합니다.
ClientVirtualDeviceSet::MapBufferHandle
목적
이 함수는 일부 다른 프로세스에서 가져온 버퍼 핸들에서 유효한 버퍼 주소를 가져오는 데 사용됩니다.
구문
int ClientVirtualDeviceSet::MapBufferHandle (
int dwBuffer, // in: buffer handle
uint8_t** ppBuffer // out: buffer address
);
| 매개 변수 | 인수 | 설명 |
|---|---|---|
| dwBuffer | 이 핸들은 ClientVirtualDeviceSet::GetBufferHandle에서 반환하는 핸들입니다. |
|
| ppBuffer | 현재 프로세스에서 유효한 버퍼의 주소입니다. |
| 반환 값 | 인수 | 설명 |
|---|---|---|
| NOERROR | 함수가 성공했습니다. | |
| VD_E_PROTOCOL | 가상 디바이스 세트는 현재 열려 있지 않습니다. | |
| VD_E_INVALID |
ppBuffer는 잘못된 핸들입니다. |
설명
핸들을 올바르게 전달하도록 주의하세요. 핸들은 단일 가상 디바이스 세트에 로컬로 설정됩니다. 핸들을 공유하는 파트너 프로세스는 버퍼 핸들이 원래 버퍼를 가져온 가상 디바이스 세트의 범위 내에서만 사용되도록 해야 합니다.