mars
2011
Les systèmes d’exploitation génériques comme MS Windows sont conçus pour faire fonctionner tant bien que mal LES applications. L’objectif de ces OS est de s’arranger pour faire tourner toutes sortes d’applications mêmes celles qui sont mal conçues (moins optimisées). Cet objectif a pour conséquence de tirer vers le bas les applications les plus exigeantes en temps de réponse. Cette généricité des OS comme Windows est donc un facteur limitant pour les SGBDR.
Il est donc indispensable pour un SGBDR digne de ce nom de disposer d’un algorithme, d’un mécanisme de planification des tâches (scheduling) et de gestion de mémoire différents de celui de l’OS générique comme Windows.
C’est ainsi que SQL SERVER 7.0 et SQL SERVER 2000 dispose d’une couche intermédiaire autonome de scheduling appellée « User Mode Scheduler » (UMS).
Arrive ensuite SQL SERVER 2005 où l’UMS a été remplacé par SQLOS (SQL Operating System).
SQLOS est d’une part une amélioration de l’UMS et d’autre part une centralisation de toutes les briques développées pour optimiser le moteur de stockage SQL SERVER. Les deux principales fonctions de SQLOS sont : la planification des tâches (scheduling) et la gestion de mémoire.
En plus de ces principales fonctions, SQLOS met à disposition les « Dynamics Managements Objects » qui sont généralement des vues, les fameuses DMVs qui permettent d’avoir plus de visibilité sur l’état d’une instance SQL Server, d’obtenir à un moment donné toutes les informations (mémoire,cpu, tâches en cours d’exécutions,…) sur le fonctionnement de l’instance.
Bref, si l’on considère SQLOS comme le chef d’orchestre de SQL Server, alors qui sont les musiciens de cet orchestre ? Quelles sont les partitions jouées par chaque musicien ?
Lorsqu’on écrit par exemple une requête SQL dans SQL management Studio (SSMS) et qu’on appuie sur la touche F5 (ou le bouton exécuter)
SQL Server perçoit cette action comme un message d’exécution d’une tâche (SQL Server Tasks).
SQL Server Tasks est le conteneur de la tâche à effectuer.
Après validation de l’instruction (l’objectif ici n’est pas de décrire les différentes étapes d’exécution d’une requête) SQL Server sollicite l’expertise de SQL Server Scheduler pour la définition du contexte d’exécution de la tâche (ressources, privilèges,..). C’est ce contexte d’exécution qu’on appelle processus (process en anglais). Après la définition du contexte (processus), SQL Server confie l’exécution proprement dite de la tâche à un exécutant (SQL Server Workers). Sous SQL Server il existe deux types de worker : les threads et les fibers.
Si EXEC sp_configure ‘lightweight pooling’ a pour valeur 0 alors le worker est un thread
Si EXEC sp_configure ‘lightweight pooling’ a pour valeur 1 alors le worker est un fiber
C’est rare de trouver des serveurs SQL configurés en mode fiber. Généralement le worker est un Thread. Signalons que SQLMAIL, SQLXML et les requêtes CLR ne supportent pas le mode fiber. On comprend donc pourquoi le fiber a moins de popularité que le thread. Notons que le thread est une unité d’exécution (c’est lui qui exécute le code) et il est rattaché à un contexte d’exécution (le processus). Sans un thread un processus ne peut rien faire et inversement sans un processus un thread ne peut rien faire. Les deux (thread et processus) sont intimement liés pour le meilleur et pour le pire jusqu’à la fin de leur vie… C’est ce qui fait qu’on confond souvent thread et processus.
SQL Server Scheduler – SQL Server Tasks – SQL Server Worker – Threads versus Fibers sont les principaux éléments de SQLOS. Connaître ce qu’il y a sous le capot de sa voiture évite de faire certaines bêtises comme mettre le liquide de nettoyage des vitres dans le compartiment du liquide de refroidissement du moteur
Passons en revue les DMVs relatives à SQL Server Scheduler – SQL Server Tasks – SQL Server Worker – Threads versus Fibers
–> sys.dm_os_schedulers : retourne une ligne par SQL Server scheduler (planificateur SQL Server). Chaque scheduler est associé à un processeur logique
❏ scheduler_id : ID du scheduler
❏ cpu_id : ID du processeur auquel le planificateur est associé.
❏ current_tasks_count : Nombre de tâches actuellement associées au scheduler = tâches en attente + tâches en cours d’exécution
❏ runnable_tasks_count : Nombre de tâches en attente sur le scheduler current_workers_count: Nombre de workers (thread ou fiber)associé au scheduler
❏ is_idle : 1 = Le planificateur est inactif. Pas de tâche en cours d’exécution
–> sys.dm_os_tasks : retourne une ligne pour chaque tâche active dans l’instance SQL Server.
❏ task_state : état de la tâche. Valeurs possibles
¤ PENDING : En attente d’un worker (thread ou fiber).
¤ RUNNABLE : Exécutable, mais en attente.
¤ RUNNING : En cours d’exécution.
¤ SUSPENDED : rattaché à un worker et en attente d’un événement.
¤ DONE : Terminé.
¤ SPINLOOP : Bloqué dans une boucle.
❏ scheduler_id : ID du planificateur parent
❏ session_id : ID de la session qui est associée à la tâche.
❏ exec_context_id : ID du contexte d’exécution qui est associé à la tâche.
❏ pending_io_count : Nombre d’E/S physiques qui sont effectuées par cette tâche
–> sys.dm_os_workers : retourne une ligne pour chaque worker.
❏ is_fiber : si 1 alors worker est un fiber. Si 0 alors worker est un thread
–> sys.dm_os_threads : retourne la liste des threads SQL Server
❏ creation_time : date/heure de création du thread
❏ affinity : le CPU sur lequel ce thread est censé s’exécuter. Il dépend de la configuration de l’option « Affinity mask »
décimal binaire Autorise les threads sur les processeurs
——– ———- ————————–
1 00000001 0
3 00000011 0 et 1
7 00000111 0,1 et 2
15 00001111 0,1,2 et 3
31 00011111 0,1,2,3 et 4
63 00111111 0,1,2,3,4 et 5
127 01111111 0,1,2,3,4,5 et 6
255 11111111 0,1,2,3,4,5,6 et 7
Une requête qui permet d’identifier :
¤ les tâches en cours ou en attente d’exécution
¤ les tâches exécuter en parallèle
¤ le processeur qui est affecté à la tâche
¤ la nature du worker (thread ou fiber)
¤ la date de création de la tâche par SQLOS
¤ la tâche (l’instruction) à exécuter
…
SELECT th.creation_time
,ta.request_id
,ta.session_id
,ta.scheduler_id
,s.cpu_id
,th.affinity
,w.is_fiber
,w.state w_state
,s.is_idle
,ta.task_state
,s.current_tasks_count
,s.runnable_tasks_count
,ta.pending_io_count
,sqltxt.text as tche_A_executer
FROM sys.dm_os_schedulers s
INNER JOIN sys.dm_os_tasks ta ON ta.scheduler_id = s.scheduler_id
INNER JOIN sys.dm_os_workers w ON ta.task_address = w.task_address
INNER JOIN sys.dm_os_threads th ON th.scheduler_address = s.scheduler_address AND th.worker_address = w.worker_address
INNER JOIN sys.dm_exec_requests r ON ta.task_address = r.task_address
CROSS APPLY sys.dm_exec_sql_text (r.plan_handle) sqltxt
WHERE ta.request_id is not null
AND ta.session_id is not null
AND r.plan_handle is not null
ORDER BY request_id,session_id
Que conclure ?
Je me demande pourquoi Microsoft a opté pour une couche intermédiare comme SQLOS intégrée dans le SGBD au lieu de concevoir un système d’exploitation orienté SGBD. Un système d’exploitation optimisé pour SGBD, débarassé de tous frameworks ou couches inutiles/nuisibles pour l’SGBD ?
Permettez-moi de faire une analogie avec ce que je vois dans le domaine des télécommunications où les éditeurs de solutions font généralement un packaging OS + Applications. L’OS est généralement une distribution Linux fait maison de façon à ce que chaque application dispose de son OS. La conséquence c’est qu’il faut à chaque fois une machine dédiée…
Les ouvrages que j’ai consulté :
—————————————————————————-
Titre : Microsoft SQL Server 2008 Internals
Auteurs : Kalen Delaney, Paul S. Randal, Kimberly L. Tripp, Conor Cunningham, Adam Machanic, Ben Nevarez
Titre : SQL Server 2008 Internals and Troubleshooting
Auteurs : Christian Bolton, Justin Langford, Brent Ozar, James Rowland-Jones, Steven Wort
———————————-
Etienne ZINZINDOHOUE
———————————-