跳转到主要内容

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

当您初次登录到 developerWorks 时,将会为您创建一份概要信息。您在 developerWorks 概要信息中选择公开的信息将公开显示给其他人,但您可以随时修改这些信息的显示状态。您的姓名(除非选择隐藏)和昵称将和您在 developerWorks 发布的内容一同显示。

所有提交的信息确保安全。

  • 关闭 [x]

当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

所有提交的信息确保安全。

  • 关闭 [x]

联邦数据库的语句中断处理

胡中庭, 软件工程师, IBM
胡中庭,IBM 软件开发中心软件工程师,北京交通大学硕士毕业,在Federation Server Development Group (联邦数据库项目组)工作两年半至今。
杨筱强, 软件工程师, IBM
杨筱强,目前在 IBM 中国软件开发实验室任软件工程师,主要从事 DB2 联邦数据库 Runtime 部分的开发工作,对数据联邦和信息检索有浓厚的兴趣。

简介: 联邦数据库 IFS (InfoSphere Federation Server) 的 SQL 语句的中断过程和传统的数据库有着很大的区别。本文从开发者的角度上给大家介绍一种全新的SQL语句中断方法,它基于联邦数据库的语句执行模式,通过中断语句在数据端的执行,进而使得整条语句在引擎端和数据源端被完整的中断,得到用户理想的结果。此外,本文还会对中断处理后的数据连续性做出一定的分析,以解决用户在实际使用中遇到的一些问题。

发布日期: 2009 年 8 月 27 日
级别: 初级
访问情况 : 1294 次浏览
评论: 


引言

中断处理在任何大型的系统(数据库或者操作系统)中都有着十分重要的作用。一个数据库系统的应用程序可能有很多 SQL 语句组成,这些语句包括 DDL (Data Definition Language, 数据描述语言 ) 和 DML (Data Management Language, 数据管理语言 ), 用户在执行这些语句的时候会遇到各种各样的问题,以至于语句无法完整或者正确的执行,在某些特殊的情况下,用户会考虑中断一些正在执行过程中的语句,这些情况大致包括:

  • 语句执行时间过长,或者用户等待了很长时间并且没有等待到预期的结果。
  • 用户已经看到自己满意的结果,并不需要相应的语句完整的执行下去。
  • 一些比较特殊的原因诸如数据库发生死锁,内存泄漏导致的内存不足等。

传统的数据库系统都需要支持中断处理,其处理过程一般分成以下几个过程,执行具体的请求前注册特定的中断处理函数或者程序,然后接受并且执行相应的请求,接下来当中断请求被处理的时候,执行已经注册的函数或程序,最后回到之前的请求继续执行。这种简单的中断模型并不适应于复杂的分布式联邦数据库语句。

联邦数据库的语句执行模型有别于传统的数据库系统,客户端把语句执行请求通过特定的协议发给引擎端,引擎端通过数据库的编译系统把得到的语句分成两个部分,一部分将运行在引擎端,另外一部分将会在数据源端进行执行,当且仅当数据源端执行完毕并且把相应的结果集返回时,引擎端才能进一步进行处理。同时,这两部分可能会在完全两个不同的进程中执行。因此,这种不同的执行模型需要另外一种基于数据源的中断模型去处理整个语句中断过程。

本文所描述的联邦数据库的语句中断处理(本文以下特指 DB2 LUW 数据源),它是一种基于多进程的,多阶段执行的,分布式的数据库中断处理方法,它具备以下特性和优点:

  • 处理多阶段执行的语句,对于联邦数据库的语句执行模型有着完备的支持。
  • 处理多进程,不同进程会处理不同的请求,对于多进程中断的支持使得每个进程都可以保证中断的连续性。
  • 支持各种不同的 DML 语句,其中包括查询,插入删除或者更改,存储过程等。
  • 支持不同的中断级别,包括语句级别和事务级别。(下文会详细描述)

图 1. 联邦数据库中断的工作流程
图 1. 联邦数据库中断的工作流程

联邦数据库中断处理概述

联邦数据库中断的捕获

DB2(本文提到的 DB2 均指 DB2 LUW)的中断处理是一种基于 Breathing Point(中断检查点)的中断处理。所谓 Breathing Point 是指在程序实现过程中,在一些已知的函数或者过程当中加入一些检查点,通过在程序执行过程中动态检查一些中断状态标志位的变化去捕获中断并且调用相应的中断处理函数,以达到中断程序执行的目的。对于 Breathing Point 的实现有很多种,但是其本质上要求相关函数或者过程有适当的机会去做检查。对于 IFS 上的语句,由于其执行过程的重要一部分是在远程数据源上,这就意味着如果语句的执行在远端是没有办法返回并且去做相应的检查的,由此看出在 IFS 上使用 Breathing Point 的方式去实现中断是不可能的。

另外,传统的操作系统应用程序中断是基于操作系统的中断回调函数的,其过程是利用操作系统提供的中断号,注册相应的中断回调函数,当中断发生时由操作系统本身对中断进行响应,调用注册的回调函数完成中断,其中断的捕获依赖操作系统的实现。这种方式的最大缺点是其不可控制性,原因是操作系统中断回调函数的执行是应用程序不可控制的,尤其是执行的 Timestamp(时间点)。对于 IFS 上使用这种方式可能会给系统带来极大的负面效果,因为第三方库提供的程序接口的实现是不可控制的。下面是一个例子:

假设数据源语句执行的接口是 Stat_Execute,中断借口是 Stat_Break,实现如下:

void Stat_Execute () 
 { 
 grab_mutex(thread_lock);
  ... do some initial processing release_mutex(thread_lock); 
  ... do actual request processing 
  (block on remote server until request completes) 
 } 


 void Stat_Break () 
 { 
 grab_mutex(thread_lock); 
 ... do some initial processing release_mutex(thread_lock); 
 ... do cancel processing (send request to remote server) 
 }
 
 

这里,一种如下的执行过程将会导致数据源端遇到死锁的情况:

  • 在线程执行之前通过操作系统接口注册了中断回调函数,也就是代码里面的 Stat_Break。
  • 执行的线程调用了 Stat_Execute并且已经通过 Grab_mutex得到了锁资源,此时该线程在执行一些初始化的工作。
  • 这时候,中断发生,操作系统中断回调函数也就是 Stat_Break被执行(请注意操作系统中断回调函数随时都可以被调用)。该执行线程又再次希望去获得之前的锁资源。
  • 但是该线程之前并没有机会释放锁资源, 这就相当于在一个线程当中连续申请两次同一个锁资源,这样死锁就发生了。

上述的例子可以直观的让读者明白操作系统的中断处理在 IFS这种多阶段分布式语句处理系统中是不适用的。对于 IFS上,语句中断的捕获是通过不同的线程来实现,它使用一种我们称为 Statement Handler(语句处理函数)来触发,其实现的方式和操作系统的回调函数有一定的相似性,但是在 IFS中我们能够更方便的控制和处理它。大致的过程如下:

  • 在线程把语句发送到远端数据源之前,把 Statement Handler注册到相应的线程控制结构中,这样每个线程都会有其对应的 Statement Handler链表,而实际上这些 Statement Handler就是数据源提供的中断处理函数接口。
  • 线程开始执行远端数据源上的语句,用户的中断请求从客户端发出被引擎端接受。
  • 引擎端接受到中断请求,通过另外一个线程去获取当前执行线程的 Statement Handler,并且执行它去实现中断。

需要注意的是,这里我们并不需要重新获得数据库的连接信息,因为执行中断和被中断的线程同属于一个进程,所以数据库的连接信息是可以被重用的。当然,在某些特殊的第三方客户端并不适用,这取决于客户端是否是 Threaded Safe(线程安全)的。

联邦数据库中断的架构

这一节我们主要介绍联邦数据库中断的架构。 IFS 由于其语句执行的特殊性使得其中断主要分成以下几个重要的方面:

  • 中断连续性:
Select t1.c2, n1.c1 from t1, n1 where t1.c1 = n1.c2
 
 

之前我们已经描述过,对于一条 IFS 下的 DML 语句,我们可以把它分成引擎端和数据源端两个部分。数据源端的执行是针对远程的结果集部分,而引擎端则是针对近程的结果集。下面是一个例子:

对于这样一条 JOIN 语句,其中 t1 代表的是 DB2 的一个近程表,而 n1 代表的是 DB2 LUW 远端数据源上的一个 nickname(别名),对这样一条语句来说,获取 n1 的信息就属于数据源端的部分,而获取 t1 并且进行数据的集合操作就属于引擎端的。

那么,中断这样的语句就需要对两个部分作不同的处理,如果语句的执行停留在数据源端,那么必须通过先中断远程部分使得远程语句返回,来达到中断整个语句的目的。

  • 分布式中断:
Select n1.c1, n2.c1 n3.c1 from n1, n2, n3
Where n1.c2 = n2.c2 and n1.c3 = n3.c3 and n2.c4 = n3.c4
 
 

在一个 IFS 的分布式引擎上可能会连接一个或者更多的数据源,那么一条 DML 语句可能牵涉不同的数据源。这样,一条语句可能会变得十分复杂。

上面这条 DML 语句包含了三个不同的 nickname,对于三个不同数据源上的表,这条语句的中断就比较复杂,因为其包含了三条远端的语句,那么,每条语句都要求在中断过程中被分别处理。

  • 不同模式下的中断:

这里提到也是联邦数据中断的核心过程,在这之前有必要提及 IFS 上语句运行的模式,Trusted(可信赖模式)和 Fenced(保护模式)。在包括 v9.5 后的 DB2 版本里 db2agent 已经由进程改为线程,即每一个数据库连接由一个线程去完成。那么,在 IFS 上 Trusted 和 Fenced 两种模式的区别主要区别在于上面提到的引擎端和数据源端语句的执行是否在一个进程中,即在 Trusted 模式下,近端和远端的执行都在一个线程中完成,就是 db2agent,而在 Fenced 模式下,远端部分由 db2fmp 进程下的一个线程去完成。那么对于两种不同的模式,其中断的架构如下:

1、Trusted 模式下的中断架构


图 2. Trust 模式下的联邦数据库中断处理
图 2. Trust模式下的联邦数据库中断处理

对于 Trusted 模式,其中断的过程分为以下几个步骤:

  • 客户端应用程序把语句执行请求发送给引擎端。引擎端使用一个 db2agent 处理相应的请求。
  • 在语句请求的远端被发送到数据源上执行之前,对这个 db2agent 设置 statement handler 也就是语句处理函数。
  • 客户端因为某种原因发出中断请求。引擎端得到了这个中断请求,初始化另外一个 db2agent 去处理中断。
  • 处理中断的 db2agent 将会去调用之前设置好的语句处理函数,这样,远程语句就会被顺利的中断并且返回。
  • IFS 将会按照相应的逻辑进行中断的后续处理工作,接下来控制权将返回给客户端。

2、Fenced 模式下的中断架构

对于 Fenced 模式,其中断的过程分为以下几个步骤:

  • 基本逻辑和 Trusted 模式下是相似的。处理中断和被中断的 db2agent 还是会分别执行中断和运行的功能。
  • 最主要的区别是数据源的语句试运行在另外一个叫做 db2fmp 进程里的一个线程中,因而,负责中断的 db2agent 将不可能直接中断远程语句,相应的,它会通过 IPC(Inter Process Communication,进程间通信)的方法给 db2fmp 发送一个中断请求。
  • 相比于 Trusted 模式,真正执行数据源端语句运行和中断的是两个在 db2fmp 进程下的线程,而原先的 db2agent 只负责和 db2fmp 进行通信。
  • 同样,IFS 还需要分别对被中断的线程进行一些类似于清理的后续工作。

图 3. Fenced 模式下联邦数据库的中断处理
图 3. Fenced模式下联邦数据库的中断处理

中断级别以及数据的连续性

对于大型的数据库管理系统来说,数据的连续性是极其重要的。最常用的维护数据连续性的方式就是事件。用户可以根据应用程序的上下文选择提交或者回滚,以次方式来控制应用程序对数据库内容的修改。

这里我们所谓的中断级别,就是指在中断过程中在合适的时机利用 IFS 自身的事件回滚和连接的中断来维护中断过程中的数据连续性。在这里我们可以先明确一下两个概念。

  • Inbound connection(内连接),图 1 是 IFS 的中断架构,也是其语句执行的基本架构,从中我们看到的从客户端到 IFS 引擎端的连接,称为内连接。
  • Outbound connection(外连接),还是图 1,从 IFS 引擎到数据源端的连接,称为外连接。

对于 IFS 的中断处理,我们提供了两个中断级别,相应的就是两种不同的中断方式:

  • 事件级别:在这个级别中,中断处理使得当前应用程序的事件回滚,同时内连接和外连接都相应的断开,最后整个应用程序都停止,处理当前应用程序的线程都被回收。这个级别适用于用户中断的目的是整个应用程序,比如在数据源出现死锁,内存泄漏导致的程序失败,这个时候程序执行的结果已经不可靠的情况。在中断结束以后,任何之前没有被提交的数据库更改都不会起任何作用。
  • 语句级别:在这个级别中,中断处理的目标只是当前的语句,内连接和外连接都不会被断开。应用程序仍旧可以继续执行下去,相应处理程序的线程也仍旧处于可运行的状态。这个级别适用于用户中断的目的是语句,换句话说,用户只是期望当前的语句不用执行,比如执行实践过长,或者已经得到足够的执行信息(这种情况通常发生在 SELECT 语句中)。那么,在中断结束后,事件也没有被回滚,用户可以根据接下来程序执行的状况决定提交或者回滚。

对于上述两个中断级别,中断的方式也是不同的。对于事件级别,可以使用 DB2 提供的“ force application ”方式进行中断,其命令格式为:

>>-FORCE APPLICATION--+-ALL--------------------------+---------->
                      |    .-,------------------.    |   
                      |    V                    |    |   
                      '-(----application-handle-+--)-'   
>--+------------+----------------------------------------------><
   '-MODE ASYNC-'  

 
 

那么对于语句级别,就可以使用在操作系统上一般的中断方式在控制台使用键盘敲入“ Ctrl-C ”来进行。当然不是所有的控制台都可以接受“ Ctrl-C ”,在这样的情况下,我们推荐使用操作系统的“ kill ”命令,具体的:

Kill -2 db2_process_id
Db2_process_id就是DB2 前端进程的ID。

 
 

我们将在下面一节给出一些具体的实例。


联邦数据库中断实例

本节将给出联邦数据库中断的一些用户实例,我们这里假设用户已经按照标准定义了 IFS 中的一些实体,这些实体包括 Wrapper, Server, Nickname, FSTP (Federated Stored Procedure) 。

  • 实例一:用“force application作联邦数据库的中断
db2 => connect to test
db2 => select * from n1

 
 

首先在系统中我们连接至数据库并且执行 SELECT 语句,目的是从 n1(一个 DRDA 数据源上的别名)中获取表里面的数据。我们使用如下命令:

这个时候,在获取数据时因为某些特殊原因,在一段时间内并没有得到结果,接下来我们可以使用“ list application ”命令来查看应用程序的执行状况。

db2 list applications show detail

CONNECT Auth Id   Application Name     Appl.      Application Id    Seq#  
Number of  Coordinating DB  Coordinator     Status           Status Change Time 
DB Name  DB Path  Handle    Agents     partition number pid/thread
--------- -------- ------ ---- ------ -------- --------------------
IIDEV11       db2stmm              13         *LOCAL.DB2.090615225225                  
 00001 1          0        10539     Connect Completed     Not Collected
TEST     /home/iidev11/iidev11/NODE0000/SQL00003/
IIDEV11        db2fw3               19         *LOCAL.DB2.090615225231
00001 1          0      8740    Connect Completed    Not Collected 
TEST     /home/iidev11/iidev11/NODE0000/SQL00003/
IIDEV11        db2bp                7          *LOCAL.iidev11.090615225221
 00002 1          0      2829   Federated request pending      Not Collected 
TEST     /home/iidev11/iidev11/NODE0000/SQL00003/
IIDEV11       db2fw2               18         *LOCAL.DB2.090615225230 
00001 1          0      9768   Connect Completed    Not Collected
TEST     /home/iidev11/iidev11/NODE0000/SQL00003/
IIDEV11       db2fw1               17         *LOCAL.DB2.090615225229 
00001 1          0      10025    Connect Completed   Not Collected  
TEST     /home/iidev11/iidev11/NODE0000/SQL00003/
IIDEV11       db2fw0               16         *LOCAL.DB2.090615225228 
00001 1          0     10282   Connect Completed   Not Collected
TEST     /home/iidev11/iidev11/NODE0000/SQL00003/
IIDEV11       db2wlmd              15         *LOCAL.DB2.090615225227
00001 1          0     9511   Connect Completed   Not Collected 
TEST     /home/iidev11/iidev11/NODE0000/SQL00003/
IIDEV11        db2taskd             14         *LOCAL.DB2.090615225226 
00001 1          0     10796    Connect Completed    Not Collected
TEST     /home/iidev11/iidev11/NODE0000/SQL00003/
IIDEV11        db2evml_DB2DETAILDEA 20         *LOCAL.DB2.090615225232 
00001 1          0      9254    Connect Completed    Not Collected 
TEST     /home/iidev11/iidev11/NODE0000/SQL00003/

 
 

从中可看出,ID 为 7 的应用程序正在被编号为 2829 的 db2agent 处理,同时应用程序处于“ Federated request pending ”的状态,这个状态告诉我们语句的执行在远端没有返回结果。你也可以使用如下命令观察相应的 db2agent 的状态,可以看出这个 db2agent 正连接到相应的数据库实例中(部分输出)。

db2pd –edus
EDU ID    TID         Kernel TID     EDU Name           USR (s)      SYS (s)
。。。。。。
2829      2829       717403     db2agent (TEST)     3.476331     0.096430

 
 

接下来,用户就可以使用下面的命令中断应用程序。

Force application (7)
 
 

当执行完以后,整个应用程序都会被终止,而且 2829 号 db2agent 会处于空闲的状态,可以使用之前的命令,用户会得到以下结果(部分输出)。

如果此时系统上运行其他的应用程序,对当前的应用程序进行中断将不会影响其他程序的执行,那么上面运行“ db2 list applications show detail ”的结果将会包括其他的应用程序。

  • 实例二:用“Ctrl-C或者“kill -2作联邦数据库的中断

和上面的例子有一定的相似,这里我们使用“ Ctrl-C ”或者“ kill -2 ”的方式,让我们看一下和上面的区别,当中断前,我们使用“ psdb2 ”命令察看当前应用程序的 db2(db2 前端处理进程,属于 db2 客户端)进程。

psdb2:
532906 db2
311330 db2acd
107068 db2sysc
516442 /home/iidev11/sqllib/bin/db2bp 405606A5011 5 A
471538 /home/iidev11/sqllib/bin/db2bp 598686A5011 5 A

 
 

由于当前系统只有一个应用程序,我们可以看出进程号为 532096 的 db2 进程就是处理当前应用程序客户端的前端进程。于是我们可以使用

Kill -2 532906
 
 

或者,在之前执行 SELECT 语句的终端上使用“ Ctrl-C ”来对语句进行中断,中断的结果和上面的“ force application ”是不一样的。具体的“ db2pd -edus ”的部分输出

db2pd –edus
EDU ID    TID       Kernel TID     EDU Name        USR (s)      SYS (s)
。。。。。。
2829      2829      717403         db2agent (TEST)        3.476331     0.096430

 
 

以及“ list applications ”的部分输出

db2 list applications show detail
CONNECT Auth Id  Application Name Appl.  Application Id  Seq#  
Number of  Coordinating DB  Coordinator     Status  Status Change Time   
DB Name  DB Path Handle   Agents   partition number pid/thread
。。。。。。
db2bp     7          *LOCAL.iidev11.090615225221     00002 1     0
2829  UOW_WAITING Not Collected   TEST
。。。。。。

 
 

我们不妨看出,相应的 db2agent 仍旧连接在数据库上,同时整个应用程序还是存在,它的状态由其接下来运行的结果所决定。

Fetch Statement (SELECT)
IUD Statement (Insert, Update, Delete)
FSTP Statement (Federated Stored Procedure)
Statement Under Passthru Mode

 
 

下面列出的是联邦数据库中断可以支持的语句:


联邦数据库中断的限制

1、目前联邦数据库的语句中断处理仅限于 DB2 LUW 数据源,在以后的版本上会陆续支持其它数据源。

2、对于 Fenced ATQ (Asynchronous Table Queue) 被设置的情况下,联邦数据库的语句中断不能够正常执行。关于 ATQ,请参考以下链接。 http://www.ibm.com/developerworks/db2/library/techarticle/dm-0611norwood/


参考资料

学习

获得产品和技术

  • 下载 IBM 软件试用版,体验强大的 DB2®,Lotus®,Rational®,Tivoli®和 WebSphere®软件。

  • 下载 DB2 9 for Linux, UNIX, and Windows 的免费试用版。

  • 现在可以免费使用 DB2。下载 DB2 Express-C,这是为社区提供的 DB2 Express Edition 的免费版本,它提供了与 DB2 Express Edition 相同的核心数据特性,为构建和部署应用程序奠定了坚实的基础。

讨论

作者简介

胡中庭,IBM 软件开发中心软件工程师,北京交通大学硕士毕业,在Federation Server Development Group (联邦数据库项目组)工作两年半至今。

杨筱强,目前在 IBM 中国软件开发实验室任软件工程师,主要从事 DB2 联邦数据库 Runtime 部分的开发工作,对数据联邦和信息检索有浓厚的兴趣。

关于报告滥用的帮助

报告滥用

谢谢! 此内容已经标识给管理员注意。


关于报告滥用的帮助

报告滥用

报告滥用提交失败。 请稍后重试。


developerWorks:登录


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 使用条款

 


当您初次登录到 developerWorks 时,将会为您创建一份概要信息。您在 developerWorks 概要信息中选择公开的信息将公开显示给其他人,但您可以随时修改这些信息的显示状态。您的姓名(除非选择隐藏)和昵称将和您在 developerWorks 发布的内容一同显示。

请选择您的昵称:

当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

(长度在 3 至 31 个字符之间)


单击提交则表示您同意developerWorks 的条款和条件。 使用条款.

 


为本文评分

评论

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Information Management
ArticleID=423650
ArticleTitle=联邦数据库的语句中断处理
publish-date=08272009
author1-email=huzhongt@cn.ibm.com
author1-email-cc=
author2-email=yangxq@cn.ibm.com
author2-email-cc=

标签

Help
使用 搜索 文本框在 My developerWorks 中查找包含该标签的所有内容。

使用 滑动条 调节标签的数量。

热门标签 显示了特定专区最受欢迎的标签(例如 Java technology,Linux,WebSphere)。

我的标签 显示了特定专区您标记的标签(例如 Java technology,Linux,WebSphere)。

使用搜索文本框在 My developerWorks 中查找包含该标签的所有内容。热门标签 显示了特定专区最受欢迎的标签(例如 Java technology,Linux,WebSphere)。我的标签 显示了特定专区您标记的标签(例如 Java technology,Linux,WebSphere)。