Inside SQL Server, Microsoft Press.
Traduction personnelle. But pédagogique.


Le Noyau SQL Server et l'Interaction avec le Système d'Exploitation

Le noyau SQL Server est responsable de l'interaction avec le système d'exploitation. Toutes les requêtes aux services du système d'exploitation sont faits via l'API Win32 et la run-time du langage C. Sous Windows NT, SQL Server tourne dans un sous système Win32 protégé. Absolument aucun appel n'est fait en mode privilégié (Privileged Mode); ils sont faits en mode utilisateur (User Mode). Cela veut dire que SQL Server ne peut provoquer un crash du système en entier, ni aucun crash d'autre processus utilisateur, et qu'aucun autre processus ne peut cracher SQL Server. SQL Server ne fait pas d'appel aux périphériques matériel et n'utilise pas d'API non documentées de Windows NT. Si le système entier tombe (cela provoque un écran bleu de la mort) et que SQL Server s'exécutait sur la machine, une chose est sûre: SQL Server n'a pas provoqué cela. Ce genre de crash est du à des périphériques fautifs ou incompatibles, des pilotes de périphériques boggués en mode privilégié, ou un bug critique dans le code du système d'exploitation de Windows NT (ce qui est rare).

Un but principal du design de SQL Server et de Windows NT est la scalability. Le même fichier binaire qui s'exécute sur un portable tourne aussi sur un super serveur SMP avec plusieurs processeurs. SQL Server existe en version pour les architectures matérielles Intel et RISC sur le même CD. Windows NT est une plate-forme idéale pour un serveur de bas de données car il fournit un environnement 32 bits protégé totalement protégé. Les fondations d'une plate-forme de base de données sont: multitâche, gestion de mémoire virtuelle, architecture SMP et I/O asynchrone. Windows NT fournit tout cela, et SQL Server les utilise complètement. Le moteur SQL Server tourne dans un seul processus. Ce processus contient plusieurs threads d'exécution. Windows NT planifie l'exécution de chaque thread sur l'ensemble des processeurs.

Architecture, Threads et SMP

SQL Server a une implémentation qui diffère des autres systèmes de base de données SMP (symmetric multiprocessing):

Pour comprendre comment fonctionne SQL Server, il est intéressant de comparer sa stratégie avec celle utilisée par d'autres produits. Sur un système mono-thread thread comme la plupart des variantes Unix, un serveur de base de données a plusieurs processus, un par CPU. Certaines implémentations ont même un processus par utilisateur, ce qui est très coûteux en mémoire. Ces processus communiquent avec la mémoire partagée, qui contient les verrous, le cache, les queues, et les information des contextes clients. Ces processus doivent implémenter des tâches relatives à un système d'exploitation: simulation des threads, coordination des processus. Du fait que les processus sont liés à des CPUs spécifiques, le dynamic load balancing peut être difficile ou impossible. Pour des facilités de portage, ces produits utilisent la même approche quand ils s'exécutent sous un système qui supportent la gestion des threads en natif, comme Windows NT.

La figure 3-7 montre les différences entre l'architecture à base de threads de SQL Server et les architecture SMP des autres systèmes.

Figure 3-7. SQL Server a un design multi-threads et mono-processus processus.

SQL Server utilise toujours plusieurs threads, même sur un système mono-processeur. Les threads sont crées et détruits suivant l'activité du système, donc leur nombre n'est pas constant. En standard, le nombre de threads varie entre 16 et 100, suivant la configuration. Un pool de threads gère chaque réseau que SQL Server peut supporter en simultané, un autre gère les checkpoints, un autre gère le processus lazywriter, et un autre gère l'écriture au journal. Un thread séparé gère aussi les tâches de nettoyage général des bases, comme le skrinking de base (mode autoshrink). Un autre pool de thread gère les commandes des utilisateurs.

Le Pool de Worker Thread

Bien que SQL Server semble offrir à un thread à chaque utilisateur, le système est un peu plus compliqué. A cause de l'inefficacité d'utilisation de centaines de threads pour supporter des centaines d'utilisateurs, SQL Server gère des pools de worker threads (threads de travail).

Lorsqu'un client soumet une commande, la gestion de réseau SQL Server place la commande dans une queue et le prochain thread disponible dans le pool de worker thread prend en charge la requête. Techniquement, la queue est gérée sous Windows NT avec les IOCompletion port. Le worker thread de SQL Server attend sur la queue de completion qu'une requête soit postée sur le port de completion. Si aucun worker thread n'est disponible, SQL Server créé dynamiquement un nouveau thread jusqu'à ce que le nombre maximal de worker thread configuré soit atteint. La commande d'un client doit attendre un worker thread avant d'être libérée.

Même dans un système avec des milliers d'utilisateurs connectés, la plupart sont au repos à un moment donné. Lorsque l'activité diminue, SQL Server élimine au fur et à mesure des threads au repos, libérant ainsi des ressources et de la mémoire.

Le design du pool de worker thread est efficace pour gérer des milliers d'utilisateurs connectés sans avoir à utiliser un moniteur transactionnel. La plupart des autres produits, incluant ceux sur systèmes centraux, ont besoin d'un moniteur transactionnel pour obtenir un niveau d'utilisateur connecté que SQL Server peut gérer sans composant extérieur. C'est une fonctionnalité importante.

Le pool de threads prenant en charge les commandes est réparti sur tous les CPUs. SQL Server peut éclater des requêtes complexes en plusieurs parties exécutées sur plusieurs CPUs en parallèle. Ceci est vrai si le nombre de processeurs est supérieur au nombre de connexions. Cette option de configuration s'appelle cost threshold for parallelism.

Dans un schéma normal, chaque worker thread exécute chaque requête soumise. Si un thread fait une opération qui provoque un défaut de page, seul le thread fautif est bloqué. (Un défaut de page intervient si le thread fait une requête mémoire et que le gestionnaire de mémoire virtuel du système d'exploitation doit swapper sur disque. Une telle requête mémoire prend du temps à cause du fait que les opérations I/O sur disque sont mille fois moins rapides que l'accès à la mémoire.)

Considérons maintenant quelque chose de plus important qu'un défaut de page. Supposons que la requête utilisateur prise en charge provoque une opération illégale qui entraîne une violation d'accès (par exemple, un thread essaie de lire de la mémoire non allouée). Windows NT termine immédiatement le thread fautif— une fonctionnalité importante d'un système d'exploitation vraiment protégé. Du fait que SQL Server gère les exceptions structurées Win32, seul l'utilisateur qui a fait la requête est affecté. Tous les autres utilisateurs ne sont pas affectés et le système n'est pas tombé. Bien sûr, ce bug ne devrait pas arriver ou très rarement dans la réalité. Un logiciel n'est jamais parfait.

NOTE
Bien que Windows 95 et Windows 98 ne supportent pas les systèmes SMP et les IOCompletion port, la discussion précédante ne s'applique seulement lorsque SQL Server tourne sur Windows NT. La discussion suivante sur les I/O disque ne s'applique aussi que sur Windows NT.

Les opérations I/O disque sur Windows NT

SQL Server 7 utilise deux fonctionnalités de Windows NT pour améliorer les performances des I/O disque: les I/O groupées (scatter I/O) et les I/O asynchrones. La description suivante est adaptée des livres SQL Server en ligne:

I/O Scatter Elles sont introduites dans Windows NT 4, Service Pack 2. Avant, toutes les données lues ou écrites sur Windows NT devaient être faites dans une zone contiguë de mémoire. Si la lecture transfert 64 KB de données, la requête de lecture doit spécifier une adresse de zone 64 KB de mémoire contiguë. Les I/O scatter permettent de réaliser un lecture ou écriture pour transférer des données depuis ou vers des zones de mémoires diverses.

Si SQL Server 7 lit dans un extent de 64 KB, il n'a pas besoin d'allouer une seule zone de 64 KB et de copier les pages individuelles dans les pages du cache de buffers. Il peut allouer huit pages de buffers et réaliser une seule opération de I/O groupées (scatter I/O) qui spécifie les adresses des huit pages de buffers. Windows NT place les huit pages directement dans les pages de buffers, éliminant ainsi l'opération de copie.

Les I/O asynchrones Dans une opération I/O asynchrone, après qu'une application demande une opération de lecture ou d'écriture, Windows NT rend immédiatement le contrôle à l'application. L'application peut se consacrer à d'autres tâches et tester plus tard si l'opération est terminée. Au contraire, une opération I/O synchrone ne rend pas le contrôle à l'application tant que le système d'exploitation n'a pas fini l'opération de lecture ou d'écriture. SQL Server supporte de multiples opérations I/O asynchrones simultanées sur chaque fichier d'une base. Le nombre maximum de I/O opérations pour n'importe quel fichier est configuré par l'option max async io. Si max async io est laissé par défaut à 32, un maximum de 32 opérations I/O asynchrones sera supporté par chaque fichier à un moment donné.