Sintomas
Depois de instalar o Microsoft SQL Server 2017 no RHEL 7,4, o programa termina e gera um dump principal quando você tenta executar a ferramenta MSSQL-conf. Além disso, a seguinte entrada é registrada nos logs do systemctl para o serviço MSSQL-Server (journalctl-u MSSQL-Server. Service):
Este programa encontrou um erro fatal e não pode continuar em execução. As seguintes informações de diagnóstico estão disponíveis: Motivo: 0x00000003 Mensagem: resultado StackTrace: 00005577212bcd92 0000557721266767 Processo: 590-sqlservr Thread: 594 (thread do aplicativo 0x1000) ID da instância: afe0f97b-fdbc-4a4d-910c-038e7ee2049b Identificação de falha: 544c4c67-0f49-4877-A959-92c14798d58e Carimbo de compilação: f7473acad6f0299cd161863aaa02e4284434ab6d915c7b467e2a14e907290249 Capturando o dump principal e as informações...
Causa
Esse problema ocorre porque o SQL Server 2017 no Linux não é compatível com os layouts VA do herdado. Devido às configurações habilitadas no RHEL 7,4, todos os processos são iniciados usando legacy_va_layout.
Durante a inicialização, o SQL Server no Linux verifica os intervalos de endereços. Quando ele encontra uma incompatibilidade devido a um layout de VA herdada, ele gera um Assert, termina o programa e gera um dump principal.
O RHEL 7,4 pode mudar para usar um layout de VA do herdado por qualquer um dos seguintes motivos:
-
O valor limite de pilha suave é definido como ilimitado (por exemplo, um script Limits. conf modificado ou uma configuração ulimit-s ).
-
Um layout de VA global herdada está habilitado (por exemplo, sysctl VM. legacy_va_layout ou Modificar/etc/sysctl.conf).
Resolução
-
No layout /etc/security/limits.conf , adicione uma nova linha e, em seguida, insira o código a seguir: mssql soft stack 8192 root soft stack 8192
-
No layout /etc/sysctl.conf , adicione uma nova linha e, em seguida, insira o código a seguir: vm.legacy_va_layout = 0
-
Reinicie o computador: reboot
-
Verifique se a configuração de pilha suave para os usuários, raiz e mssql, é 8192. Alterne para o contexto do usuário e execute o seguinte comando: ulimit -s
-
Certifique-se de que o layout de VA global herdado seja 0: Sysctl vm.legacy_va_layout
Informações adicionais
Verificando o limite de tamanho da pilha
Verificar o limite de tamanho da pilha e a configuração legacy_va_layout (valores padrão, tirados de uma instalação recente-7).
[root@localhost ~]# sysctl vm.legacy_va_layout vm.legacy_va_layout = 0 [root@localhost ~]# ulimit -s 8192
Quando essas configurações são feitas em um sistema x64, o layout de espaço de endereço é semelhante ao seguinte:
+----------------------+ TASK_SIZE ((1UL << 47)-PAGE_SIZE) | PILHA | +----------------------+ +----------------------+ MMAP_BASE (STACK_SIZE + RND_OFFSET) | MMAP () | | vvvvvvvvvvvvvvvvvvvv | | | | | | | | | | | | | | | | | | | | | | | |^^^^^^^^^^^^^^| | HEAP | +----------------------+ | SEGMENTOS ELF | +----------------------+ +----------------------+ 0
MMAP_BASE está perto da parte superior do espaço de endereço. Como os mapeamentos são adicionados, a alocação de espaço de endereço "é ampliada". Esta é a configuração padrão para RHEL, e isso é o que o SQL Server espera encontrar quando ele é iniciado.
Executar um programa simples
Executar um programa simples que mmaps uma página e retorna o endereço retornado pelo kernel (exemplo):
mmap code ========= #include <stdio.h> #include <sys/mman.h> int main() { void* result = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); printf("mmap %p\n", result); return 0; } [root@localhost ~]# ./mmap mmap 0x7fb6976d6000
No entanto, se um ou ambos os parâmetros forem alterados, o layout do VA poderá reverter para o seu layout herdado:
+----------------------+ TASK_SIZE ((1UL << 47)-PAGE_SIZE) | PILHA | | vvvvvvvvv ^ VVVVVVVVVV | | | | | | | | | | | | | | | | | | | |^^^^^^^^^^^^^^| | MMAP () | +----------------------+ TASK_UNMAPPED_BASE (PAGE_ALIGN (TASK_SIZE/3)) | | | | | | |^^^^^^^^^^^^^^| | HEAP | +----------------------+ | SEGMENTOS ELF | +----------------------+ +----------------------+ 0
Aqui, o MMAP_BASE é colocado em um terço do espaço de endereço. Como os mapeamentos são adicionados, a alocação de espaço de endereço "aumenta para cima" (expande). Como temos um espaço de endereço virtual de 47 bits, no Linux de 64 bits, MMAP_BASE é colocado em torno do "0x2A0000000000" 42nd TB virtual. Portanto, o MSSQL choque em endereços que já estão mapeados abaixo de 64TB quando ele tenta definir seus mapas fixos.
Ajustar o tamanho da pilha para aumentar o limite não associado, "ilimitado"
[root@localhost ~] # ulimit-s ilimitado [root@localhost ~] #./mmap mmap 0x2b6634464000
* ajustando a VM. legacy_va_layout
[root@localhost ~] # ulimit-s 8192 [root@localhost ~] # sysctl-w VM. legacy_va_layout = 1 VM. legacy_va_layout = 1 [root@localhost ~] #./mmap mmap 0x2b46f28f9000
Você pode obter o mesmo efeito que a configuração de VM. legacy_va_layout ajustando o tamanho da pilha para aumentar ilimitado. A diferença é que, depois que um administrador define VM. legacy_va_layout = 1, o sistema usará globalmente o layout de VA herdado para todos os processos. (A única maneira de substituir isso é redefinindo o botão sysctl para 0.) No entanto, se você tiver VM. legacy_va_layout = 0 (padrão), é possível ajustar essa característica ajustando o limite de tamanho da pilha por sessão de logon emitindo ulimit (ou Personalizando Limits. conf).