使用 DB2 UDB V8.2 进行 32 位和 64 位应用程序开发

来源:百度文库 编辑:神马文学网 时间:2024/04/29 03:22:54
Gwyneth Evans (grevans@ca.ibm.com), 软件开发人员, IBM Canada, Inc.
2004 年 11 月 01 日
如果您要从 32 位 DB2® 实例迁移到 64 位 DB2 实例,或者将 32 位应用程序部署到 64 位的平台上,抑或只是想以后能够很容易实现这种迁移,那么本文很适合您。本文将概述 DB2 Universal Database™(DB2 UDB) 的 32 位和 64 位应用程序以及例程,同时还将解释有关开发 DB2 应用程序和例程以及将它们部署到 64 位平台的一些考虑事项及最佳实践。
在讨论 DB2 对 32 位和 64 位的支持之前,首先将查看并理解本文的上下文中牵涉到的一些术语和重要概念,这十分重要:
平台:计算机硬件和操作系统的基本技术,定义了计算机如何运行,以及可以在它上面运行什么样的软件。 硬件:计算机以及它的相关架构。 操作系统: 控制计算机硬件并允许其他应用程序和用户使用计算机的软件。操作系统由一个内核和一组操作系统库组成,其中内核直接与硬件打交道,而那些操作系统库则是构建和运行应用程序所必需的。 DB2 实例:一个逻辑数据库服务器环境,DB2 数据库就是在该环境中创建的。 数据库客户机:向数据库服务器请求访问数据库对象和数据、运行应用程序或者请求基于应用程序的服务的计算机或软件程序。 数据库服务器:计算机或程序,包含并管理数据库,同时处理客户机发出的对数据库数据的请求。 32 位:一台计算机可以并行处理的二进制数字的个数(bit),或者表示内存寻址。例如,一台 32 位的计算机有 32 位宽的数据寄存器,并使用 32 位来标识内存中的每个地址。 64 位:参见 32 位。一台 64 位的计算机有 64 位宽的数据寄存器,并使用 64 位来标识内存中的每个地址。




回页首
您是否计划将数据库客户机或服务器迁移到 64 位平台,或者只是想构建和部署适合 64 位 DB2 实例的应用程序或例程,那么理解 DB2 对 32 位和 64 位应用程序开发的支持十分重要。同样重要的是,采用一些最佳实践有助于应用程序和例程的部署,并确保它们在目标环境中的功能与预期的一致。
本文分为三部分:首先将向您介绍 32 位和 64 位对象的概念,然后帮助您了解有关 32 位和 64 位 DB2 配置和特性支持的信息,最后帮助您制定出用于开发和部署适合 64 位 DB2 实例的应用程序的策略。
第 I 部分:32 位和 64 位对象概述第 II部分:DB2 32 位和 64 位 应用程序和例程支持第 III 部分:开发和部署可移植的 32 位和 64 位 DB2 应用程序




回页首
广泛理解 32 位和 64 位对象在计算环境中的相关性十分重要,因为它们之间的某些依赖性可能影响到各个方面,包括所需购买的硬件,部署应用程序的方式等。
32 位计算机硬件使用 32 位来表示内存地址以及处理指令和数据。64 位硬件使用 64 位来做同样的事情。通常,32 位操作系统运行在 32 位的硬件上,而 64 位操作系统则运行在 64 位的硬件上,不过在某些 64 位的硬件上运行 32 位操作系统也是可能的。
操作系统由一个内核和一组操作系统库组成,其中内核直接与硬件打交道。操作系统要么带有 32 位的内核,要么带有 64 位的内核,或者,在某些情况下同时带有这两种内核。通常,32 位操作系统内核可以使用 4 GB 的实际内存(即操作系统和正在运行的应用程序共享的物理 RAM),而 64 位操作系统内核可以使用更多的实际内存。当然,有些 32 位操作系统内核可以使用多于 4 GB 的内存,但是在这一点上仍然不如 64 位的内核。在某些操作系统上,可能必须有 64 位内核来运行 64 位应用程序,因为这种应用程序在使用 32 位内核的情况下是不能运行的。所有 UNIX® 操作系统都属于这种情况,只有 AIX® 例外。在 AIX 上,情况十分特殊,您可以任意使用 32 位或 64 位内核来运行 32 位和 64 位应用程序。然而,为了防止可伸缩性问题,在运行 32 位应用程序时最好使用 64 位内核。
操作系统库很重要,因为有了这些系统库才能构建和运行应用程序。为了构建 32 位应用程序,必须链接 32 位系统库。同样,为了构建 64 位应用程序,必须有 64 位系统库。不过,在一个特定的操作系统中,即使提供了 64 位系统库,也不一定意味着这个系统真正可以运行 64 位应用程序。这种情况对于 32 位 Windows® 操作系统更是常见,在 32 位 Windows 上,虽然有些 64 位应用程序不能运行,但是可以编译和链接它们。对于 UNIX 平台也是如此,因为在某些情况下,您可以在 32 位的硬件上安装带 64 位支持的操作系统,还有一些情况下,32 位内核不能运行 64 位应用程序。实际上,可以把 32 位操作系统看作只能运行 32 位应用程序的操作系统,尽管 64 位操作系统也能运行 64 位应用程序,但需要使用 64 位硬件,而且可能还需要使用 64 位操作系统内核。
32 位应用程序是按照内存地址的大小为 32 位(4 个字节)来编译的。这些应用程序可以直接使用至多 4 GB 的虚拟内存 —— 即一台计算机上可以提供的潜在内存。不管系统上可用于操作系统和其他应用程序之间共享的实际内存(RAM)有多少,这一虚拟内存限制始终存在。另一方面,64 位应用程序按照内存为 64 位(8 个字节)来编译,可以使用多于 4 GB 的虚拟内存,这不受限制。操作系统通常还会对应用程序施加更多的虚拟内存限制,因此,虽然应用程序具有 32 位的寻址能力,但理论上每个应用程序的最大虚拟内存可能只有 1-2 GB。
当您在 32 位或 64 位平台上编译应用程序时,默认情况下应用程序被编译为在某种特定平台上运行。通过使用特殊的特定于编译器的编译选项,并适当地链接到合适的 32 位或 64 位库,也可以在带有某些编译器的 32 位操作系统上创建 64 位应用程序,或者在 64 位操作系统上创建 32 位应用程序。
32 位应用程序通常可以同时在 32 位和 64 位操作系统上运行,不过在很多采用 32 位内核的操作系统上不能运行 64 位应用程序。
从 DB2 的角度来看,当然也存在 32 位和 64 位的 DB2 对象。32 位和 64 位 DB2 实例就是其中的一个例子。您可以在 32 位或 64 位操作系统上创建 32 位 DB2 实例,但是只能在 64 位操作系统上创建 64 位 DB2 实例。有些混合 32 位和 64 位操作系统,例如 AIX Version 5.1,便支持这两种类型的 DB2 实例。同一个数据库服务器上可以存在多个 DB2 实例,以服务不同的用户需求(测试实例与生成实例),并且不一定要有相同的位数。
DB2 应用程序可以同时在具有大多数编译器的 32 位和 64 位 DB2 实例中创建为 32 位或 64 位的对象,但是为了得到应有的功能,必须将 32 位或 64 位 DB2 应用程序分别链接到 DB2 的 32 位和 64 位库,两种 DB2 实例都提供了这样的库。
32 位 DB2 外部例程是在被调用时装载和运行 32 位外部库的 DB2 外部例程(过程,用户定义函数)。在调用 64 位外部例程时,则装载和运行 64 位外部库。
对 32 位和 64 位对象之间的关系有了基本的理解之后,就更容易明白必须如何管理 DB2 应用程序开发实践,以便系统可以支持 32 位和 64 位应用程序的开发和部署。




回页首
就 32 位和 64 位跨平台开发而言,DB2 UDB 确实是一种通用的数据库。没有哪种数据库像 DB2 那样,为在如此多的平台上开发和部署应用程序提供了如此多的支持。谈到 32 位和 64 位应用程序的开发支持,DB2 走在了前列。下面的小节将介绍 DB2 的关键 32 位和 64 位平台和应用程序开发支持。
下面的 Linux、UNIX 和 Windows 平台上的 DB2 Universal Database 产品在 32 位和 64 位平台上都可以使用:
DB2 产品
DB2 UDB Express Edition
DB2 UDB Personal Edition
DB2 UDB Personal Developer’s Edition
DB2 UDB Developer’s Edition
DB2 UDB Workgroup Server Edition
DB2 UDB Workgroup Server Unlimited Edition
DB2 UDB Enterprise Server Edition
您可以使用 Personal Developer’s Edition 或任何其他产品开发数据库应用程序,前提是在客户机上安装了 DB2 Application Development Client。
要了解更多关于 DB2 产品、扩展器、工具以及其他信息管理软件产品的信息,请参阅http://www.ibm.com/software/data/db2/udb。
一旦确定了哪种 DB2 产品能满足您的需要,就必须为数据库系统选择硬件。下面的表列出了可用作 DB2 数据库服务器或 DB2 客户机的受支持的 32 位和 64 位平台。.
32 位平台 64 位平台 混合平台
AIX AIX AIX hybrid (5.1)
HP PARSIC HP PARSIC HP IPF HP IPF Linux Intel 32 位 Linux AMD Linux PPC Linux EMt64 Linux zSeries Linux Itanium 64 位 (IA64) Solaris Linux PPC Windows 32 位 Linux zSeries Solaris Windows IA64
有很多因素可能影响对用于开发和测试系统或生产系统的平台的选择。通常,这种决定最终归结为价格、性能、可伸缩性和可靠性。当需要为了数据库服务器在 32 位或 64 位硬件平台作出选择时,应该考虑使用 64 位平台的以下优点:
可以有更多的内存用于构建和运行更大的应用程序。 更有效的数据处理和更好的应用程序性能。
通常,生产系统的效率对于数据管理策略的成功十分关键,这就是为什么常常在生产系统中使用更快的 64 位硬件作为数据库服务器的原因。
如果单独运行开发、测试和生产系统,那么显然当开发和生产系统在相同的平台上,或者至少运行相同的操作系统时,应用程序的部署是最容易的。
您可以混合和匹配选作 DB2 数据库客户机和服务器的平台,因为 DB2 支持从 32 位和 64 位客户机到数据库服务器的本地和远程连接。
本地数据库连接用于将 DB2 客户机或客户机应用程序连接到与客户机驻留在同一台计算机上的 DB2 数据库服务器,而不需要网络协议。另一方面,远程数据库连接是连接到驻留在不同计算机上的 DB2 数据库服务器,因而需要 TCPIP 之类的网络协议。下面的表展示了 DB2 对 32 位和 64 位客户机与 32 位和 64 位 DB2 数据库服务器之间本地和远程连接的全部支持。
DB2 客户机 32 位 DB2 服务器(本地和远程) 64 位 DB2 服务器(本地和远程)
32 位客户机 支持 支持 (1)
64 位客户机 支持 支持
如果 DB2 客户机和 DB2 数据库服务器在不同类型的平台上,那么这种广泛的支持是一个重要特性。这还意味着 32 位和 64 位应用程序可以连接 32 位和 64 位数据库服务器上的数据库并与这些数据库通信。
要获得对 DB2 受支持的 32 位和 64 位硬件以及用于 DB2 Versions 7 和 8 的客户机-服务器配置的详细描述,请参阅主题 “Supported and non-supported client configurations”,在DB2 Quick Beginnings Guide (PDF) 和Information Center (HTML) 中都可以找到这个主题。
DB2 支持用于各个受支持平台的多种编译器、解释器和相关开发软件。您可以在 32 位或 64 位 DB2 实例中的任何一种 DB2 实例中构建 DB2 32 位和 64 位应用程序,只要该 DB2 实例中带有前面提到的差不多所有 DB2 都支持的编译器,这些编译器提供了 32 位和 64 位应用程序编译支持。
在开始编写应用程序之前,应确认您所想要的编译器或开发软件能够支持 32 位和 64 位应用程序的开发需要。要获得关于用于各种硬件平台的 DB2 受支持的开发软件的详细描述,请参阅主题 “Supported development software”,在DB2 Application Development Guide: Building and Running Applications (PDF) 和Information Center (HTML) 中都可以找到这个主题。
在构建和链接 32 位或 64 位 DB2 应用程序之前,最好要确切地知道将来可以在哪里运行这些应用程序。下面的表展示了可以在其上运行 DB2 32 位和 64 位客户机应用程序的硬件和操作系统,这里假设这些应用程序被正确地编译和链接:
客户机应用程序 32 位硬件 + 操作系统,带有 32 位 DB2 实例 64 位硬件 + 操作系统,带有 32 位或 64 位 DB2 实例
32 位客户机应用程序 支持 支持 (1)
64 位客户机应用程序 不支持 支持
(1) Windows 32 位应用程序可以在 Windows 64 位平台上运行,而不需要对环境作任何改变。在 UNIX 上,通过重新绑定应用程序并以适当的库路径设置运行应用程序,便可以将已有的 32 位应用程序部署到所有 64 位平台上,只有 Linux IA64 和 Linux for zSeries® 例外。
关于如何正确地构建、链接和链接要部署到不同平台的应用程序的建议,将在本文的第 III 部分 中详细讨论。
例程(存储过程、UDF 和方法)不同于应用程序。例程 – 封装了数据库和编程逻辑的数据库对象 - 运行在数据库服务器上,是通过执行特定于例程的 CREATE 语句创建的,该语句定义了例程的一些特征。
SQL 例程支持
对于 DB2 Version 8.2,SQL 过程定义像 SQL 函数、表、触发器和其他数据库对象定义一样,完全保存在数据库中。SQL 过程不再与任何驻留在数据库服务器上的可执行代码产生关联,这意味着不存在与 SQL 例程的创建、调用、部署或迁移有关联的 32 位或 64 位相关因素。
外部例程支持
外部例程的例程体是以一种编程语言编写的,它被编译成一个库,当例程被调用时,就要装载并运行这个库。在 CREATE 语句中有两个子句用于外部例程,它们是 FENCED 和 NOT FENCED,这两个子句将决定外部例程是在一个不同于数据库管理器的 fenced 环境中运行,还是在与数据库管理器相同的寻址空间中运行。通常,unfenced 例程比 fenced 例程执行起来要更好一些,因为它们通过共享内存与数据库管理器通信,而不是通过 TCPIP 通信。默认情况下,不管 CREATE 语句中使用了哪些其他的子句,例程总是被创建为 fenced 例程。
下面的表说明了 DB2 对在运行相同操作系统的 32 位和 64 位数据库服务器上运行 fenced 和 unfenced 32 位和 64 位例程的支持:
例程类型 32 位服务器 64 位服务器
32 位 fenced 过程或 UDF 支持 支持 (1)(2)(3)
64 位 fenced 过程或 UDF 不支持(4) 支持
32 位 unfenced 过程或 UDF 支持 不支持 (2)
64 位 unfenced 过程或 UDF 不支持 (4) 支持
(1) 在 64 位服务器上运行 32 位例程不如在 64 位服务器上运行 64 位例程那么快。
(2) 32 位例程必须创建为 FENCED 和 NOT THREADSAFE 才能在 64 位服务器上运行。
(3) 在 Linux IA 64 位数据库服务器上不能调用 32 位例程。
(4) 64 位应用程序和例程不能在 32 位寻找空间中运行。
在表 5 中要注意的重要一点是,32 位 unfenced 过程不能在 64 位 DB2 服务器上运行。如果必须将 32 位 unfenced 例程部署到 64 位平台,那么应该在编目这些例程之前将 NOT FENCED 子句从用于这些例程的 CREATE 语句中去掉。
32 位和 64 位外部例程解析
当执行引用例程的 SQL 语句(例如用于调用过程的 CALL 语句或者可以在 select 列表中包含列函数的 SELECT 查询)时,DB2 根据 DB2 系统编目表中的例程定义解析例程引用,并在 SQL 语句的执行过程中调用例程。
当调用外部例程时,DB2 根据名称在数据库服务器上找到例程的外部类或库文件,然后装载并运行外部类或库文件。在 32 位平台上,外部例程总是作为 32 位对象来装载和运行。在 64 位平台上,出于性能考虑,DB2 假设例程调用的目标库是 64 位的对象。因此,DB2 首先尝试作为 64 位的对象来执行例程的外部库或类。如果不行的话,DB2 便自动尝试作为 32 位 fenced 例程库来装载和运行该库。
如果在数据库服务器的文件系统中同时具有一个例程的库或类的 32 位和 64 位版本,那么为了得到最佳性能,应该确保该例程的 CREATE 语句标识了正确的外部库或类文件,而不是让 DB2 去搜索正确的版本来运行。
要了解关于例程解析和调用的更多信息,请参阅Routine invocation —— 一个 IBM DB2 文档主题。
64 位数据库服务器上 32 位外部例程的性能
由于对实现外部例程的选择常常基于提高客户机应用程序性能的需要,因此从外部例程中获得最大性能通常被优先考虑。在 64 位数据库服务器上,外部例程的性能部分上是由外部例程是装载 32 位还是 64 位外部例程库来决定的。
除了 Java™ 例程以外,在 64 位服务器上调用 32 位例程在性能上不如在 64 位服务器上调用 64 位例程,因为出于性能考虑,DB2 首先尝试将例程当作 64 位对象来执行,然后才尝试将例程作为 32 位对象来执行,而后者要求特殊的 32 位 fenced 模式处理。对于单独的 32 位例程调用,其开销显得微不足道,但是当这个例程被调用很多次时,开销就变得比较显著了。如果您关心性能的话,那么建议您重新构建(编译、绑定和链接)例程源代码来创建 64 位例程库。
64 位数据库服务器上 32 位 Java 例程的性能
关于运行在 64 位数据库服务器上的 32 位 Java 例程的一个好消息是,如果使用 32 位 JVM 来运行这些 Java 例程,那么它们的性能与使用 64 位 JVM 时的 64 位 Java 例程的性能不相上下,所以您可以不需要 64 位 JVM。
32 位 Java Virtual Machines (JVM) 可以在 64 位 DB2 数据库服务器上运行,并且可用于运行 32 位 Java 例程。然而,运行在 64 位数据库服务器 上的 32 位 Java 例程伸缩性不是很好,因为它们必须编目成 FENCED NOT THREADSAFE,并以这种形式运行,这意味着每次调用这样的例程时,都需要使用它们自己的 JVM。如果您预测到需要例程有高度的可伸缩性,那么应使用不同的编程语言来从创建在这些例程。
DB2 Development Center 为开发、构建、调试和部署 SQL 和 Java 例程提供了一个图形化的用户界面,它是作为 DB2 Application Development Client 的一个可选组件提供的。DB2 Development Center 作为以下客户机应用程序中的一种受到支持:
AIX 32 位 AIX 64 位 Linux Intel 32 位 Linux IA2 64 位 Sun 32 位 Sun 64 位 Windows 32 位 Windows IA 64 位
DB2 Development Center 服务器支持
DB2 Development Center 支持到以下 DB2 数据库服务器的连接:
AIX 32 位 AIX 64 位 DB2 z/OS (V6) DB2 z/OS (V7) DB2 z/OS (V8) iSeries (V5r2) iSeries (V5r3) HP-UX PA64 HPUX IPF64 Linux Intel 32 位 Linux IA2 64 位 Linux /390 Linux z/Series Sun 32 位 Sun 64 位 Windows 32 位 Windows IA 64 位
DB2 Development Center 例程开发和调试支持
DB2 Development Center 支持到很多 DB2 服务器的连接,并支持用于很多 DB2 服务器的 SQL 和 Java(JDBC 和 SQLJ)例程的构建和调试。下面的表总结了 DB2 Development Center 对例程开发和调试的支持:
服务器平台 SQL 过程开发 SQL 过程调试 Java 过程开发 Java 过程调试 SQL 标量 & 表 UDF 开发
Windows 32 位 是 是 是 是(1) 是
Windows IA64 是 是 是 否 是
Linux Intel 32 位 是 是 是 否 是
Linux IA2 64 位 是 是 是 否 是
Sun 32 位 是 是 是 否 是
Sun 64 位 是 是 是 否 是
AIX 32 位 是 是 是 是(1) 是
AIX 64 位 是 是 是 否 是
Linux /390 是 否 是 否 是
HP 32 位 是 是 是 否 是
HP 64 位 是 是 是 否 是
HP-UX 64 位 是 否 是 否 是
Linux zSeries 是 否 是 否 是
DB2 z/OS (V6) 是 否 否 否 否
DB2 z/OS (V7) 是 否 是 否 否
DB2 z/OS (V8) 是 是 是 否 否
iSeries (V5r2) 是 否 否 否 否
iSeries (V5r3) 是 否 是 否 否
(1) 在这种服务器上开发的 Java 存储过程只能在 Windows 32 位 和 AIX 32 位 Development Center 客户机中进行调试。
有了 Development Center,便可以执行其他 32 位/ 64 位独立应用程序开发活动,包括创建和运行:可以读 WebSphere MQ® Queues 的 UDF、访问 OLE DB 数据提供程序的 UDF,以及使用 XML 数据的 UDF。用 SQL 或 Java 以外的编程语言编写的例程可以通过命令行和 CLP 创建和运行。还可以在 Development Center 的 Server View 中执行这些过程。这些过程不能在 Development Center 中修改或调试。要获得 Development Center 特性和功能的完整列表,请参阅:
Overview of the DB2 Development Center - an IBM DB2 documentation topicDB2 Development Center — DB2 下一代 AD 工具
DB2 Development Center 例程导入、导出和部署支持
DB2 Development Center 提供了 Import Wizard、Export Wizard 和 Deployment Wizard,这些向导可用于帮助您转移例程定义和部署例程。Import 和 Export 向导可用于将未编译的 SQL 或 Java 例程定义从源机器转移到目标机器。通过使用这些向导,还可以将编译过的例程库和源文件一起转移。
一旦将先前导出的例程定义导入到一个 Development Center 项目中,便可以使用 Deployment Wizard 来部署 SQL 或 Java 例程。部署向导提供了重新构建导出的例程源代码,或者使用编译过的与例程定义一起导入的必需的库来部署例程这两个选项。
Deployment Wizard 在目标服务器上编目例程,并在必要时在目标服务器上重新构建例程库或类。Deployment Wizard 为重新使用已有的例程库或类(如果适用的话)提供了一种选择,然而,如果目标数据库服务器运行的操作系统不同于源数据库服务器运行机的操作系统,那么这就变得不可能了,因此 Deployment Wizard 将重新构建所需的库或类。
SQL 例程部署支持(非 Development Center 支持)
在 DB2 Version 8.2 中,SQL 过程是本地实现的 —— 也就是说,它们是完全在数据库管理器中通过执行相关的 CREATE 语句来实现的数据库对象。SQL 的实现不存在处于数据库管理器之外的部分。这意味着,在 DB2 Version 8.2 中创建或部署 SQL 过程时,不需要考虑 64 位平台。SQL 函数总是本地实现的,因此在创建或部署时也不需要考虑 64 位的问题。
在 DB2 Version 8.2 之前,DB2 的 SQL 存储过程是作为可以在数据库服务器上运行的嵌入式 SQL C 代码实现的。通过在目标机器上重新创建例程,或者通过 GET ROUTINE 和 PUT ROUTINE 命令转移编译过的存储过程,可以将这些 SQL 过程部署到另外一台计算机上。如果目标计算机与创建该过程所在的机器上运行相同的操作系统和相同级别的 DB2,但是没有安装 C 编译器,那么可以使用这些命令。如果您想将用 DB2 Version 8.2 之前版本的 DB2 创建的 32 位 SQL 过程部署到具有相同版本 DB2 的 64 位 目标平台上,那么必须显式地在目标平台上重新创建 SQL 过程。
外部例程部署支持(非 Development Center 支持)
部署外部例程时需要两个主要步骤:
通过在目标服务器上执行例程的 CREATE 语句,在目标数据库服务器中编目例程。 重新构建和部署例程库或类到目标服务器的函数目录中,这是可选的。
外部例程库和类实际上是和客户机应用程序一样创建的,不同的是还需要一些附加的链接器(linker)选项。因此,在不使用 Development Center 的情况下,例程的部署非常类似于客户机应用程序的部署。客户机应用程序的部署在本文的第 II 部分讨论。




回页首
不管您是想在 32 位 DB2 实例上开发 64 位应用程序、部署 32 位应用程序到 64 位实例,还是想保证以后这样做时没有障碍,都应该遵循下面这一节中列出的最佳实践。
作为一条通用法则,如果您使用 32 位 DB2 实例开发数据库应用程序或例程,并预测到将来要将它们部署到 64 位 DB2 实例上,那么在开发这种数据库应用程序或例程时应该特别小心,尽可能使它们具有可移植性。为了使应用程序和例程有可移植性,应使用标准的平台无关的代码。例如,如果保持采用 ISO 中提供的功能性的一个子集的习惯,那么 C 规范将确保代码更有可能具有可移植性。当然,在代码中避免使用特定于平台的方法或硬编码的文件或目录名同样有所帮助。当部署应用程序时,您不想看到某些方法在目标平台上不受支持,或者因为目标环境不同于开发环境而导致路径名无效。
在 32 位和 64 位应用程序中,数字数据类型可以用不同的位数来表示。例如,在 C 或 C++ 编程中,int 和 long 数据类型的长度没有指定。对于 DB2 支持的所有 UNIX 平台,在 32 位应用程序 中 long 类型总是用 32 位表示,而在 64 位应用程序中则用 64 位来表示。在 Windows 中,long 类型总是用 32 位表示。表 7 展示了 C 和 C++ 数据类型需要的位数在 32 位和 64 位应用程序之间的区别。
应用程序的类型 Char Short Int Long 内存地址
32 位 UNIX 和 Windows 8 16 32 32 32
64 位 UNIX 8 16 32 64 64
64 位 Windows 8 16 32 32 64
如果将一开始为 32 位平台编写的应用程序重新构建为 64 位应用程序,那么各种数据类型可能需要的不同长度将导致不正确的功能。例如,当运行那样的应用程序时,您可能会碰到数字数据被截断的情况,以及由于内存地址被截断而导致的无效数据,或者空指针引用错误。
为举例说明为什么应该使用推荐的可移植数据类型,请考虑下面的例子。假设您决定使用下面某一种本地数据类型来表示一个 BIGINT SQL 数据类型:
long long long __int64
您可以使用上面任何一种数据类型来表示 BIGINT,但是您必须愿意接受下面对应用程序的限制:
如果使用 “long long”,那么应用程序只能在 UNIX 平台上运行。 如果使用 “long”,那么应用程序只能在 64 位 UNIX 平台上运行。 如果使用 “__int64”,那么应用程序只能在 Windows 平台上运行。
为了防止这类移植性问题的发生,DB2 提供了一套可移植的宿主变量数据类型,您应该使用这些数据类型,而不是使用特定于平台的本地数据类型。位于 SQLLIB\include (Windows) 或 sqllib/include/ (UNIX) 目录中的 DB2 头文件 sqlsystm.h 包含了可用的可移植数据类型的定义。具体地说,在应用程序中应该使用这些可移植类型进行宿主变量的声明。图 8 展示了在应用程序中应该用于 SQL 宿主变量的推荐的 DB2 可移植数据类型。
SQL 数据类型 本地类型 推荐的 DB2 UDB 可移植类型
SMALLINT short
unsigned short sqlint16
sqluint16
INTEGER Integer sqlint32
BIG INTEGER long
unsigned long sqlint64
DOUBLE long
unsigned long sqlint32
DECIMAL long
unsigned long sqlint32
C/ C++ 与 Java 的比较:在 Java 中,long 总是 64 位,因此适合 BIG INTEGER 值。同样,在 Java 中,整型(integer)数据类型总是以 32 位表示,因此总是适合 SQL INTEGER 值。
要了解对于每种编程语言的建议数据类型的完整集合,请参阅本文后面的参考资料部分中的相关链接。
为了帮助您找出 C 和 C++ 代码中对 long 数据类型潜在的有问题的使用,DB2 提供了 LONGERROR 预编译选项。在将此选项显式地设为 YES 的情况下,在预编译 32 位 DB2 实例中的应用程序时,DB2 的预编译器一碰到类型为 long 的宿主变量就会返回一个错误。
使用 LONGERROR 选项预编译 32 位 DB2 实例中的应用程序代码是确保应用程序代码可以在 64 位 DB2 实例中成功运行的一种好方法。下面的步骤列出了如何做到这一点:
链接到 32 位或 64 位的数据库。 在将 LONGERROR 选项的值指定为 YES 的情况下,使用 PRECOMPILE 命令预编译应用程序。 对于每个因使用 long 数据类型而报告出来的错误,用一种可移植的宿主变量声明(例如 sqlint32 或 sqluint32)代替 long 数据类型声明。例如,将: EXEC SQL BEGIN DECLARE SECTION; long y; /* Generates an error on 64-bit platform */ EXEC SQL END DECLARE SECTION;
替换为: EXEC SQL BEGIN DECLARE SECTION; sqlint32 y; /* Acceptable to represent long on 64-bit platform */ EXEC SQL END DECLARE SECTION;
解决了 LONGERROR 报告出来的所有错误之后,再次根据目标数据库预编译应用程序,为应用程序创建一个包。
您应该将应用程序和例程构建为 32 位还是 64 位的对象呢?对于 Java 和 COBOL 以外的大多数编程语言,如果您知道应用程序或外部例程将被部署到 64 位的平台,并且将在 64 位 DB2 实例中运行,那么肯定应该编译它们的 64 位的版本。如果关心可移植性,那么应该选择 32 位,以简化开发和测试。如果有一组数量很多的应用程序和例程,那么可能需要概况出它们的执行时间,并将最常用的应用程序和例程编译成本地的 64 位代码。
对于 Java 应用程序和例程,情况要复杂一点,因为在本文发表之际,IBM 还没有发布 64 位的 Java 虚拟机。然而,让 32 位 DB2 应用程序和例程在带有 IBM 的 Java 1.4-level 32 位 JVM 的 64 位 DB2 实例仍是可能的。注意,所有 32 位 Java 与 DB2 数据库的通信都限于使用 Type 1 或 Type 2 JDBC 驱动程序。
至于 COBOL,DB2 只支持在所有受支持的 32 位操作系统上和除 Linux IA 64 位 和 Linux zSeries 以外的所有受支持的 64 位操作系统平台上运行 32 位 COBOL 应用程序。
通常,应尽可能为 32 位 DB2 实例构建 32 位的应用程序,而为 64 位 DB2 实例构建 64 位的应用程序,只有在这种支持不存在的情况下才可以例外。下一节将谈论如何让 32 位应用程序在 64 位 DB2 实例中运行。
为了减少应用程序运行时问题出现的可能性,应该在应用程序将来所在的平台上构建和测试应用程序代码。如果这一点不合实际,例如没有所需的编译器,那么可以在一个平台上构建应用程序,而将应用程序部署到它们将来运行时所在的平台上,但是在链接应用程序和指定运行时库路径时,应特别小心。
为了使功能正常,32 位 DB2 应用程序必须链接到一套 32 位的 DB2 库,而 64 位 DB2 应用程序必须链接到一套 64 位的 DB2 库。这些库的特定于 32 位或 64 位的版本,可以在下面的默认目录路径中找到,它们因平台而异:
$INSTHOME/sqllib/lib (UNIX) $INSTHOME\SQLLIB\lib (Windows)
其中 $INSTHOME 是 DB2 实例所有者的主目录。
默认情况下,在 32 位 DB2 实例中,该目录包含 32 位版本的 DB2 库,在 64 位 DB2 实例中,该目录包含 64 位版本的相同的库。您也可以在 64 位 DB2 实例中访问 32 位版本的库,而在 32 位 DB2 实例中访问 64 位版本的库,以执行跨平台开发。32 位和 64 位 DB2 库放在下面的目录中:
平台 32 位 DB2 库目录 64 位 DB2 库目录
Windows $INSTHOME\SQLLIB\lib32 $INSTHOME\SQLLIB\lib\Win64 (Windows IA 64)
UNIX $INSTHOME/sqllib/lib32 $INSTHOME/sqllib/lib64
注意: $INSTHOME 是 DB2 实例所有者的主目录。
您必须在编译/链接时将应用程序链接到适当的一组 DB2 库。而且还必须确保在编译/链接时,所链接到的库在应用程序运行时是可用的。您可以依赖于可用的默认库路径,或者显式地指定要使用的运行时库路径。下面的步骤列出了在不同场景中应该如何编译和链接应用程序:
构建要部署到 32 或 64 位 DB2 实例中的 32 位和 64 位应用程序的步骤
连接到一个数据库。 对于 32 位应用程序,连接到 32 位的数据库,对于 64 位应用程序,连接到 64 位的数据库。
预编译应用程序,以便为应用程序创建一个包。 编译应用程序。 对于 32 位应用程序,在 32 位模式下编译应用程序,或者指定一个 64 位模式的编译器选项,来创建 64 位应用程序。
将应用程序与适当的 32 位或 64 位 DB2 库进行链接,也可以指定运行时库路径: 链接应用程序 对于在 32 位 DB2 实例中构建的要部署到 32 位或 64 位 DB2 实例的 32 位应用程序,链接到默认 DB2 库路径中的库,或者显式地指定 32 位 DB2 库目录。 对于在 64 位 DB2 实例中构建的要部署到 64 位 DB2 实例中的 64 位应用程序,链接到默认 DB2 库路径中的库,或者显式地指定 64 位 DB2 库目录。 对于要部署到 32 位平台上的 64 位应用程序,链接到 64 位库目录中的库。
指定运行时库路径(可选) 为了让 DB2 应用程序能够正确运行,运行时库路径必须包括用于链接应用程序的 DB2 库,否则应用程序将因为库装载错误而运行失败。运行时库路径可以在链接时显式地设置,或者也可以在应用程序运行时指定。如果在运行时,用来链接应用程序的 DB2 库不在默认的 DB2 库目录中,则必须显式地指定在什么地方可以找到这些库。下面将详细描述指定运行时库路径的技术。
将应用程序绑定到目标服务器上的数据库。
当把应用程序从源计算机部署到另一台目标计算机时,考虑目标计算机上运行时库路径的规范很重要,因为在源计算机上链接库时所使用的所有相对路径在目标计算机上都可能是无效的。因此,在链接应用程序时,或者在运行应用程序之前,通过一个附加的链接器选项使用绝对路径来指定运行时库路径常常很有用 —— 大多数编译器都提供了对该选项的支持。
下面的例子研究了用来指定运行时库路径的一些选项:
例 1: 将应用程序部署到不同计算机上的相似的(32 位 / 64 位)实例中。
Joe 在他的 DB2 开发计算机上的一个 32 位 DB2 实例中,使用默认的 DB2 库路径构建了一个 32 位应用程序。Joe 想将这个应用程序部署到另一台计算机(他的生产计算机)上的一个 32 位的生产实例中。在这台部署计算机上,Joe 的本地 DB2 实例名是 JOEINST,他的主目录是 /home2/joe/。即:
Development computer # DB2INSTANCE = JOEINST # HOME = /home2/joe
Joe 的生产计算机有一个具有相同名称的 DB2 实例;然而,在这台计算机上 Joe 的主目录不同:
Production computer # DB2INSTANCE = JOEINST # HOME = /u/production
Joe 在链接时指定了一个运行时库路径,它包括相对路径值:
$HOME/sqllib/lib
当 Joe 试图在生产计算机上运行该应用程序时,由于装载器错误,运行将遭到失败,因为生产计算机上的 $HOME 解析后不同于开发环境中的路径,所有找不到所需的运行时库。这说明了为什么相对路径是有问题的。
解决这一问题的一种方法是在运行时装载路径中不使用 $HOME。另一种方法是,可以在链接时指定一个基于 DB2 绝对安装路径的运行时库路径。也就是说,Joe 可以将应用程序与下面的绝对运行时库路径相链接:
/usr/opt/db2_08_01/lib
只要生产环境中的 DB2 的版本和开发环境中 DB2 的版本相同(相同的版本和修复包),并且开发平台和生产平台都同时是 32 位或 64 位,那么这项技术就是有效的。
例 2:将应用程序从同一台计算机上的 32 位实例部署到 64 位实例
Azuma 在一个 32 位 AIX DB2 实例中开发了一个应用程序。当 Azuma 构建最近的应用程序时,他用下面的链接器选项指定了一个运行时库路径:
-L$/usr/opt/db2_08_01/lib
如果 Azuma 将他的实例更新为 64 位 DB2 实例,而保持所有其他目录路径不变,然后他尝试运行应用程序,结果由于装载器错误,导致应用程序不能运行,因为他链接应用程序时使用的运行时库路径现在被链接到 sqllib/lib64,而这里包含的是 64 位 DB2 库。
为了避免发生这种情况,Azuma 应该显式地将他的应用程序链接到 sqllib/lib32,而不是链接到默认的目录路径 sqllib/lib。如果 Azuma 这样做了,他的应用程序就不会因实例被更新时 DB2 默认库目录的改变而受到影响。加上我们在例 1 中学到的东西,对于 Azuma 来说,理想的运行时库装载路径的指定应该如下所示:
/usr/opt/db2_08_01/lib32
如果在 32 位实例上开发 32 位应用程序,并预测到可能要更新到 64 位 DB2 实例,或者不得不将应用程序部署到带有相同版本 DB2 的 64 位 DB2 安装的计算机上,那么这样指定库装载路径是一种很好的选择,因为安装路径是一样的。
但是,如果您合理地预测到要周期性地更新到将来版本的 DB2,那么这样指定库路径就不是很好。新版本的 DB2 和 DB2 修复包可能有不同的安装路径。如果 DB2 安装路径发生了变化,那么与基于 DB2 安装路径指定的运行时库路径链接的应用程序将无法再运行。
例 3:将应用程序从不同计算机上的 32 位实例部署到 64 位实例
例 2 中描述的技术也适用于将应用程序从不同计算机上的 32 位实例部署到 64 位实例,前提是这两台计算机都安装了相同版本的 DB2,并运行相同的操作系统。
您可以看到,您计划执行的部署类型将影响到应该如何在链接时为应用程序指定运行时库路径。只要开发环境和生产环境中 DB2 的版本是一样的,使用绝对路径来指定运行时库路径可以简化部署。
如果您将数据库客户机或服务器更新到 64 位的平台,并希望将已有的经过编译和链接的应用程序移植到新的 DB2 实例中,那么根据平台的不同,您可能需要在新 DB2 实例中重新构建应用程序,或者重新绑定应用程序并覆盖以前指定的运行时库路径。前面我们已讨论过,这样做的原因是,在 64 位 DB2 实例中默认的 DB2 库路径可能不包含链接应用程序时和运行时所使用的运行时库。
在部署应用程序之前,在一个模拟生产环境的测试环境中重新构建和编译应用程序仍然是最佳选择,但是如果时间限制或者不能访问原始应用程序源代码等原因阻碍了我们这么做,那么可以使用下面描述的技术。
将 Windows 32 位应用程序部署到 Windows IA 64 位平台
幸运的是,Windows 32 位客户机应用程序和例程可以在 Windows IA 64 位服务器上运行,而不需要对 64 位环境作任何更改。为了使这些应用程序可以运行,不需要重新构建应用程序来覆盖运行时库路径。然而,32 位 Windows 应用程序在 Windows IA 64 平台上的性能不是很好,所以,如果性能比较重要,那么强烈建议您将应用程序重新构建为 64 位 Windows 应用程序。
将 UNIX 32 位应用程序部署到 UNIX 64 位平台
除了 Linux IA 64 位、Linux PPC 64 位和 Linux zSeries 之外,所有受支持的 64 位版本的 DB2 都支持已有 32 位客户机应用程序的移植。为了在这些平台上移植 32 位客户机应用程序,必须重新绑定应用程序,并在正确地设置了库路径的情况下运行应用程序。
在 HP-UX 上,如果应用程序一开始是以 +s 选项链接的,那么只能移植 32 位客户机应用程序。如果一开始应用程序不是以 +s 选项链接,那么必须用 +s 编译器选项重新构建应用程序,或者用嵌入式运行时路径设置重新构建应用程序,以包括 32 位 DB2 库(参见下面内容)。
在 UNIX 上,64 位环境中用于 32 位 DB2 应用程序的正确的库路径是 INSTHOME/sqllib/lib32,其中 INSTHOME 是 Version 8 实例所有者的主目录;然而,如果您让 64 位应用程序也在这种环境中运行(或者打算这么做),那么不应该将 LIBPATH 环境变量的默认设置从 INSTHOME/sqllib/lib64 改为 INSTHOME/sqllib/lib32,因为新的设置将影响 DB2 实例中所有的应用程序(32 位和 64 位)。
所以,32 位和 64 位应用程序都应该各自引用适当的 DB2 库目录,您可以创建一个包装器脚本来运行应用程序,在运行应用程序之前让这个脚本来设置运行时库路径(或者任何其他必需的环境变量),在运行之后再重置这些设置。下面是一个可以使用的包装器脚本的例子:
#! /bin/sh echo export echo echo Running application... $1 echo ...Done running application.
其中 是为特定平台设置运行时库路径的环境变量。
平台 环境变量设置
AIX LIBPATH=$HOME/sqllib/lib32:$LIBPATH
Linux LD_LIBRARY_PATH=$HOME/sqllib/lib32:$LD_LIBRARY_PATH
Solaris LIBRARY_PATH=$HOME/sqllib/lib32:$LD_LIBRARY_PATH
HP-UX SHLIB_PATH=$HOME/sqllib/lib32:$SHLIB_PATH
-OR-
LD_LIBRARY_PATH=$HOME/sqllib/lib32:$LD_LIBRARY_PATH
注意:如果应用程序是以 +s 选项链接的,则该包装器只能在 HP-UX 上运行。
您可以通过在命令行中输入包装器脚本名称,后面跟上可执行文件名来运行这个包装器程序:

如果包装器脚本的库路径与被调用的可执行文件不兼容,那么对于调用其他可执行文件(例如带有 C 系统调用)的应用程序来说,在包装器内更改环境变量是不可行的。为了移植这些应用程序,必须重新链接目标文件,然后重新构建应用程序。
通常,应该用运行时库路径 lib32 来链接目标文件,而不是用平台上的环境变量。示例程序的 C、C++ 和 CLI 构建脚本使用适当的运行时路径来允许将新的应用程序轻松地移植到 64 位平台上去。
应该使用相同的链接选项来链接 64 位平台上已有 32 位应用程序的目标文件(请从下面查看示例中构建脚本的相关链接)。下面的标记可用于将 32 位 db2 库包括到运行时库路径中:
HP-UX: -Wl,+b$DB2PATH/lib32 Linux: -Wl,-rpath,$DB2PATH/lib32 Solaris: -R$DB2PATH/lib32 AIX: -L$DB2PATH/lib32
对于 AIX,可以使用 -blibpath 链接器选项来指定一个完整的运行时库路径。
注意:
这些命令都假设使用编译器进行链接,而不是使用 ld 直接进行链接。
在 Solaris 上,在将应用程序与运行时路径链接之前,必须将 LD_LIBRARY_PATH 和 LD_LIBRARY_PATH_32 复位。如果没有这么做,那么将使用 LD_LIBRARY_PATH 或 LD_LIBRARY_PATH_32 设置,而不是使用运行时路径设置。 在 Linux 上,如果使用 --enable-new-dtags 链接选项,那么在运行 32 位可执行文件之前,应将 LD_LIBRARY_PATH 复位。如果不这样做,那么就会使用 LD_LIBRARY_PATH 设置,而不是使用运行时路径设置。
要了解更多关于何时以及如何创建特定于平台的、可用于设置运行时库路径的脚本的信息,请参阅下面的主题:
Migrating applications from 32 位 to 64 位 environments —— 一个 IBM DB2 文档主题。




回页首
DB2 对跨平台开发的支持使您可以灵活地开发数据库应用程序,将它们部署到不同的平台上。本文提供了关于 DB2 32 位和 64 位应用程序和例程支持的信息,并展示了开发和构建应用程序时考虑数据库向不同平台的移植、同时使应用程序更易于部署的重要性。
本文应该有助于您:
理解计算系统中 32 位和 64 位对象之间的关系。 了解关于 DB2 对 32 位和 64 位应用程序和例程的支持。 了解如何开发易于移植的应用程序。 确定引用应用程序依赖的库路径的策略,以使应用程序能正常运行。
通常,您应该为开发和部署应用程序采取单一的策略,以减少对一些特殊情形的管理,从而可以节省不少时间,减少了一些挫折。在开发跨平台部署的应用程序的过程当中,真正的教训就是“想在前头”。在应用程序开发时,一点点的计划就可以令应用程序的部署顺利完成,换来无比的快乐。




回页首
感谢 Peeter Joot、Ryan Mayor、Ronald Trueblood 和 Dan Behman,他们为我提供了宝贵的信息,并抽时间审校了本文。
您可以参阅本文在 developerWorks 全球站点上的英文原文 。
IBM DB2 站点 是 DB2 和数据管理软件信息的主要来源。
IBM DB2 Information Center 包含了最新的 DB2 产品文档。
IBM DB2 PDF format product manuals 包含了 PDF 格式的产品文档。
IBM DB2 Information Center 包含了最新的 DB2 产品文档。
Enuring DB2 application portability 是一个 IBM 文档主题。
UNIX environment variable settings 是一个 IBM 文档主题。
Migrating to DB2 Version 8 64 位 (UNIX) 是一个 IBM 文档主题。

 

Gwyneth Evans 是多伦多 IBM Software Lab 中的 DB2 Solutions Development 小组在 DB2 UDB for Linux、UNIX 和 Windows 方面的软件和信息开发人员。先前,她曾作为一名应用开发人员,从事过 DB2 UDB for Linux、UNIX 和 Windows 产品的产品开发工作。