SQL Server如何能运行在Linux?

摘要

        使SQL Server在Linux上运行涉及将所谓的平台抽象层(“PAL”)引入SQL Server。该层用于在一个位置对齐所有操作系统或平台特定代码,并允许其余代码库保持与操作系统无关。由于SQL Server在单一操作系统Windows上的悠久历史,它从不需要PAL。实际上,SQL Server数据库引擎代码库对Windows上流行的库提供了许多引用,以提供各种功能。在将SQL Server引入Linux时,我们为自己设置了严格的要求,以便将SQL Server RDBMS的全部功能,性能和规模价值带到Linux。这包括能够在Windows上的SQL Server上运行良好的应用程序在Linux上对SQL Server同样有效的能力。Drawbridge用SQL Server现有的平台层SQL Server操作系统(SOS)来创建我们称之为SQLPAL的东西。为了安全容器的目的,Drawbridge项目提供了底层操作系统和应用程序之间的抽象,SOS提供了强大的内存管理,线程调度和IO服务。创建SQLPAL使得现有的Windows依赖项可以在Linux上使用,借助Drawbridge设计的一部分,专注于操作系统抽象,同时将关键的OS服务留给SOS。我们还在更改SQL Server数据库引擎代码以绕过Windows库并直接调用SQLPAL以获得资源密集型功能。

支持Linux的要求

SQL Server是微软的旗舰数据库产品,其背后有近30年的发展历史。在较高的层次上,下面的列表代表了我们的要求,因为我们设计了使SQL Server RDBMS在多个平台上可用的解决方案:

  1. 质量和安全性必须符合我们在Windows上为SQL Server设置的相同高标准
  2. 在功能,性能和规模方面提供相同的值
  3. Windows和Linux上的SQL Server之间的应用程序兼容性
  4. 在SQL Server代码库中实现持续快速的创新,并确保跨平台立即显示新功能和修复
  5. 为将来的SQL Server套件服务(例如Integration Services)奠定基础

为了使SQL Server支持多个平台,工程任务本质上是删除或抽象其在Windows上的依赖项。可以想象,经过数十年针对单个操作系统的开发,代码库中存在大量特定于操作系统的依赖关系。此外,代码库是巨大的。SQL Server中有数千万行代码。

SQL Server依赖于Windows开发中常用的各种库及其功能和语义,分为三类:

  • “Win32”(例如user32.dll)
  • NT内核(ntdll.dll)
  • Windows应用程序库(例如MSXML)

您可以将它们视为核心库函数,它们中的大多数与操作系统内核无关,只能在用户模式下执行。

虽然SQL Server依赖于Win32和Windows内核,但最复杂的依赖是多年来为了提供新功能而添加的Windows应用程序库。这里有些例子:

  • SQL Server的XML支持使用MSXML,用于在SQL Server中解析和处理XML文档。
  • SQLCLR承载两种系统类型的公共语言运行时(CLR)以及用户定义的类型和CLR存储过程。
  • SQL Server有一些用COM编写的组件,比如用于备份的VDI接口。
  • 通过Microsoft分布式事务处理协调器(MS DTC)控制异构分布式事务
  • SQL Server代理与许多Windows子系统(shell执行,Windows事件日志,SMTP邮件等)集成。

这些依赖关系是我们克服的最大挑战,以实现我们的目标,即在Windows和Linux上实现相同的价值和SQL Server之间的高度兼容性。例如,重新实现像SQLXML这样的东西需要花费大量的时间,并且存在不能提供与以前相同的语义的高风险,并且可能会破坏应用程序。完全删除这些依赖项的选项意味着我们还必须删除它们在Linux上从SQL Server提供的功能。如果依赖关系是边缘情况并且仅影响很少的客户可见特征,我们可以考虑它。事实证明,删除它们会导致我们不得不从Linux上的SQL Server中删除大量功能,这违反了我们关于跨操作系统的兼容性和价值的目标。

我们可以采取逐步实现这种重新实施的方法,一点一点地带来价值。虽然这是可能的,但它也会违背要求,因为这意味着Linux和Windows上的SQL Server之间会存在很大的差距。解决方案在于正确的平台抽象层。

建立PAL

跨多个操作系统支持的软件总是具有某种平台抽象层(PAL)的实现。PAL层负责从软件本身抽象底层操作系统及其库的调用和语义。接下来的几节将我们研究的一些技术作为构建PAL for SQL Server的解决方案。

SQL操作系统(SOS或SQLOS)

在SQL Server 2005发行版中,在SQL Server引擎和Windows之间创建了一个称为SQL操作系统(SOS)的平台层。该层负责用户模式线程调度,内存管理和同步(请参阅SQLOS以供参考)。创建SOS的一个关键原因是它允许向客户和支持(动态管理视图/ DMV和扩展事件/ XEvent的子集)提供集中的低级管理和诊断功能。该层允许我们通过非抢先运行并让SQL Server自己进行资源管理来最小化调度执行所涉及的系统调用数。虽然SOS提高了性能并极大地帮助了可支持性和调试,但它没有从上面描述的OS依赖性中提供适当的抽象层,即Windows语义通过SOS进行并暴露给数据库引擎。

SQL Server如何能运行在Linux?_第1张图片

在我们将从数据库引擎中完全删除底层操作系统依赖关系的场景中,最好的选择是将SOS扩展到适当的平台抽象层(PAL)。  所有对Windows API的调用都将通过SOS中的一组新等效API进行路由,并且将在SOS底部添加一个新的主机扩展层,以便与操作系统进行交互。虽然这会解决系统调用依赖性,但它对较高级库的依赖性没有帮助。

吊桥

Drawbridge是一个微软研究项目(见Drawbridge)供参考)专注于大幅减少在同一硬件上托管许多虚拟机时产生的虚拟化资源开销。该研究涉及两个想法。第一个想法是“picoprocess”,它包括一个空地址空间,一个代表picoprocess与主机操作系统交互的监视器进程,以及一个允许驱动程序在启动时填充地址空间并实现一个内核驱动程序的内核驱动程序。主机应用程序二进制接口(ABI),允许picoprocess与主机交互。第二个想法是用户模式库操作系统,有时也称为LibOS。Drawbridge提供了一个可用的Windows库操作系统,可用于在Windows主机上运行Windows程序。

SQL Server如何能运行在Linux?_第2张图片

我们的需求与Drawbridge研究的最初目标不一致。例如,picoprocess的想法不是将SQL Server移动到其他平台所需要的。然而,有一些突出的协同作用:

  1. 库操作系统在用户模式下实现了大多数1500多个Windows ABI,只需要45-50个ABI即可与主机进行交互。这些ABI用于地址空间和内存管理,主机同步和IO(网络和磁盘)。这使得需要实现非常小的表面区域以与主机交互。从平台抽象的角度来看,这非常有吸引力。
  2. Library OS能够托管其他Windows组件。已经实现了足够的Win32和NT层来托管CLR,MSXML和SQL套件所依赖的其他API。这意味着我们可以在不重写整个功能的情况下获得更多功能。

还有一些风险和回报权衡:

  1. Microsoft Research项目已完成,并且不支持Drawbridge。因此,我们需要获取源快照并根据我们的目的修改代码。风险是围绕在操作系统库上增加团队成本,将其修改为适合SQL Server,并使其与Windows相媲美的成本。从积极的方面来说,这意味着一切都处于用户模式,我们将拥有堆栈中的所有代码。性能关键代码可以进行优化,因为我们可以根据需要修改堆栈的所有层,包括SQL Server,库操作系统和主机接口,以使SQL Server执行。由于进程中没有真正的边界,因此SQL Server可以调用Linux。
  2. 最初的Drawbridge项目是在Windows上构建的,并使用了内核驱动程序和监视器进程。这将需要被删除,以支持仅用户模式的架构。在新架构中,Windows上的主机扩展(在Drawbridge设计中称为PAL)将从内核驱动程序转移到用户模式程序。有趣的是,其中一位研究人员为Linux开发了一个粗略的原型,证明它可以完成。
  3. 由于这些技术是独立创建的,因此存在大量重叠功能。SOS具有用于对象管理,内存管理,线程/调度,同步和IO(磁盘和网络)的子系统。库OS和主机扩展也具有类似的功能。这些系统需要合理化为单一实施。

 

Technologies

SOS

Library OS

Host Extension

Object Management

 

Memory Management

Threading/Scheduling

Synchronization

I/O (Disk, Network)

 

认识 SQLPAL 

经过调查,我们决定采用混合策略。我们将从Drawbridge合并SOS和Library OS来创建SQL PAL(SQL平台抽象层)。对于SQL Server不需要的库OS的区域,我们将删除它们。要合并这些体系结构,需要在堆栈的所有层中进行更改。

新架构由一组SOS直接API组成,这些API不通过任何Win32或NT系统调用。对于没有SOS直接API的代码,他们将通过托管的Windows API(如MSXML)或NTUM(NT用户模式API - 这是1500+ Win32和NT系统调用)。所有子系统(如存储,网络或资源管理)都将基于SOS,并将在SOS direct和NTUM API之间共享。

SQL Server如何能运行在Linux?_第3张图片

该架构提供了一些有趣的特性:

  • 正在运行的所有内容归结为相同的平台汇编代码。CPU无法区分提供Win32功能的代码与SQL Server或本机Linux代码之间的区别。
  • 尽管架构显示了分层,但在流程中没有真正的界限。如果在SQL Server中运行的性能至关重要的代码需要调用Linux,它可以通过SOS直接API直接使用极少量的汇编程序来正确设置堆栈并处理结果。完成此操作的示例是磁盘IO路径。还有少量转换代码可以从Windows分散/聚集输入结构转换为Linux向量IO结构。其他磁盘IO类型不需要任何转换或分配。
  • 可以通过SQLPAL管理进程中的所有资源。在SQL Server中,在SQLPAL之前,大多数资源(如内存和线程)都受到控制,但是有一些东西可以控制。一些库和Win32 / NT API将自己创建线程并在不使用SOS API的情况下进行内存分配。使用这种新架构,即使Win32和NT API也将基于SQLPAL,因此每个内存分配和线程都将由SQL PAL控制。正如您所看到的,这也有益于Windows上的SQL Server。
  • 对于Linux上的SQL Server,我们使用大约81 MB的未压缩Windows库,因此它只占典型Windows安装的一小部分(不到1%)。SQLPAL本身目前大约为8 MB。

过程模型

下图显示了运行时地址空间的外观。主机扩展只是一个本机Linux应用程序。当主机扩展启动时,它会加载并初始化SQLPAL,然后SQLPAL会启动SQL Server。SQLPAL可以启动软件隔离的进程,这些进程只是在同一地址空间内运行的线程和分配的集合。我们将它用于SQLDumper之类的东西,SQLDumper是一个在SQL Server遇到问题时运行的应用程序,用于收集启发的崩溃转储。

需要重申的一点是,即使这可能看起来像很多层,但SQL Server和主机之间没有任何硬边界。

SQL Server如何能运行在Linux?_第4张图片

SQLPAL的演变

在项目开始时,SQL Server建立在SOS上,而Library OS是独立的。最终的目标是将合并的SOS和库操作系统作为SQL PAL的核心。对于公开预览,此合并尚未完全完成,但SQLPAL的核心已被SOS取代。例如,线程和内存已经使用SOS功能而不是原始的Drawbridge实现。

结果是在CTP1版本中运行了两个SOS实例:一个在SQL Server中,一个在SQLPAL中。这很好,因为SQL Server中的SOS实例仍在使用调用SQLPAL的Win32 API。已更改SOS代码的SQLPAL实例以调用主机扩展ABI(即本机Linux代码)而不是Win32。

现在我们正在努力从SQL Server中删除SOS实例。我们正在从SQLPAL公开SOS API。一旦完成,一切都将流经单个SQLPAL SOS实例。

 

参考:

https://cloudblogs.microsoft.com/sqlserver/2016/12/16/sql-server-on-linux-how-introduction/

https://blog.csdn.net/orchidcat/article/details/78434423

https://blog.csdn.net/qiansg123/article/details/80130733

你可能感兴趣的:(sqlserver,linux)