文档首页
MySQL NDB 集群 API 开发者指南
相关文档 下载本手册
PDF (US Ltr) - 3.6Mb
PDF (A4) - 3.6Mb


2.3.24 NdbScanOperation 类

本节提供有关 NdbScanOperation 类的信息。

NdbScanOperation 类概述

父类

NdbOperation

子类

NdbIndexScanOperation

描述

NdbScanOperation 类表示事务中使用的扫描操作。此类继承自 NdbOperation

方法

下表列出了此类的公共方法以及每个方法的用途

表 2.62 NdbScanOperation 类方法和描述

名称 描述
close() 关闭扫描
deleteCurrentTuple() 删除当前元组
lockCurrentTuple() 锁定当前元组
nextResult() 获取下一个元组
getNdbTransaction() 获取此扫描的 NdbTransaction 对象
getPruned() 用于确定此扫描是否被剪枝到单个分区
readTuples() 读取元组
restart() 重新启动扫描
updateCurrentTuple() 更新当前元组

此类没有公共构造函数。要创建 NdbScanOperation 的实例,必须使用 NdbTransaction::getNdbScanOperation() 方法。

类型

此类定义了两种公共类型,如下所示

有关使用 NdbScanOperation 的更多信息,请参见 第 1.4.2.3.3 节 “扫描操作”第 1.4.2.3.4 节 “使用扫描更新或删除行”

NdbScanOperation::close()

描述

调用此方法将关闭扫描。使用此方法关闭扫描后,此扫描返回的行将不再可用。

有关多个线程尝试使用独占锁执行相同扫描以及这如何影响关闭扫描的信息,请参见 具有独占锁的扫描

签名
void close
    (
      bool forceSend = false,
      bool releaseOp = false
    )
参数

此方法采用此处列出的两个参数

  • forceSend 默认为 false;通过将此参数设置为 true 来调用 close(),以强制发送事务。

  • releaseOp 也默认为 false;将其设置为 true 以释放操作。

    无论 releaseOp 参数的值如何,只要使用 close() 方法关闭了导航结果集的游标,就会释放 NdbScanOperation 为接收扫描行而分配的缓冲区。

返回值

.

NdbScanOperation::deleteCurrentTuple()

描述

此方法用于删除当前元组。

签名
const NdbOperation* deleteCurrentTuple
    (
      NdbTransaction* takeOverTrans,
      const NdbRecord* record,
      char* row = 0,
      const unsigned char* mask = 0,
      const NdbOperation::OperationOptions* opts = 0,
      Uint32 sizeOfOpts = 0
    )

有关更多信息,请参见 第 2.3.22 节 “NdbRecord 接口”

参数

NdbRecord 接口一起使用时,此方法采用此处列出的参数

  • 应执行锁定的交易 (takeOverTrans);在使用 NdbRecord 进行扫描时,此参数不是可选的。

  • 扫描引用的 NdbRecord。即使没有读取任何记录,也需要此 record 值。

  • 从中读取的 row。如果未进行读取,则将其设置为 NULL

  • mask 指针是可选的。如果它存在,则扫描仅检索掩码中相应位已设置的列。

  • OperationOptions (opts) 可用于对操作定义进行更精细的控制。传递一个 OperationOptions 结构,其中包含指示哪些操作定义选项存在的标志。并非所有操作类型都支持所有操作选项;下表显示了每种操作类型支持的选项

    表 2.63 NdbRecord OperationOptions 的操作类型

    操作类型(方法) OperationOptions 支持的标志
    readTuple() OO_ABORTOPTIONOO_GETVALUEOO_PARTITION_IDOO_INTERPRETED
    insertTuple() OO_ABORTOPTIONOO_SETVALUEOO_PARTITION_IDOO_ANYVALUE
    updateTuple() OO_ABORTOPTIONOO_SETVALUEOO_PARTITION_IDOO_INTERPRETEDOO_ANYVALUE
    writeTuple() OO_ABORTOPTIONOO_SETVALUEOO_PARTITION_IDOO_ANYVALUE
    deleteTuple() OO_ABORTOPTIONOO_GETVALUEOO_PARTITION_IDOO_INTERPRETEDOO_ANYVALUE

  • 可选的 sizeOfOptions 参数用于保持此接口与先前定义的 OperationOptions 结构的向后兼容性。如果接口实现检测到异常大小,则可以使用它来确定如何解释传递的 OperationOptions 结构。要启用此功能,调用方应为此参数的值传递 sizeof(NdbOperation::OperationOptions)

  • 如果指定了选项,则还必须指定其长度 (sizeOfOpts)。

返回值

成功返回 0,失败返回 -1

NdbScanOperation::getNdbTransaction()

描述

获取此扫描的 NdbTransaction 对象。

签名
NdbTransaction* getNdbTransaction
    (
      void
    ) const
参数

.

返回值

指向 NdbTransaction 对象的指针。

NdbScanOperation::getPruned()

描述

此方法用于确定给定的扫描操作是否已修剪到单个分区。对于使用 NdbRecord 定义的扫描,可以在执行扫描之前或之后调用此方法。对于未使用 NdbRecord 定义的扫描,getPruned() 仅在执行扫描后才有效。

签名
bool getPruned
    (
      void
    ) const
参数

.

返回值

如果扫描被修剪到单个表分区,则返回 true

NdbScanOperation::lockCurrentTuple()

描述

此方法锁定当前元组。

签名

可以使用可选的单个参数调用此方法,可以使用以下两种方法之一

NdbOperation* lockCurrentTuple
    (
      void
    )

NdbOperation* lockCurrentTuple
    (
      NdbTransaction* lockTrans
    )

使用 NdbRecord 时,也支持此方法的以下签名

NdbOperation *lockCurrentTuple
    (
      NdbTransaction* takeOverTrans,
      const NdbRecord* record,
      char* row = 0,
      const unsigned char* mask = 0
    )

此方法还支持指定一个或多个 OperationOptions(在使用 NdbRecord 时也是如此)

NdbOperation *lockCurrentTuple
    (
      NdbTransaction* takeOverTrans,
      const NdbRecord* record,
      char* row = 0,
      const unsigned char* mask = 0,
      const NdbOperation::OperationOptions* opts = 0,
      Uint32 sizeOfOptions = 0
    )
参数(不带 NdbRecord)

此方法采用一个可选参数 - 应执行锁定的交易。如果省略,则交易为当前交易。

参数(使用 NdbRecord)

使用 NdbRecord 接口时,此方法采用以下参数,如下列表所示

  • 应执行锁定的交易 (takeOverTrans);在使用 NdbRecord 进行扫描时,此参数不是可选的。

  • 扫描引用的 NdbRecord。这是必需的,即使没有读取任何记录。

  • 从中读取的 row。如果未进行读取,则将其设置为 NULL

  • mask 指针是可选的。如果它存在,则扫描仅检索掩码中相应位已设置的列。

  • opts 参数可以采用以下任何 OperationOptions 值:OO_ABORTOPTIONOO_GETVALUEOO_ANYVALUE

  • 如果指定了选项,则还必须指定它们的长度(sizeOfOptions)。

NdbRecAttr 样式扫描上调用 NdbRecord 扫描锁接管是无效的,在 NdbRecord 样式扫描上调用 NdbRecAttr 样式扫描锁接管也是无效的。

返回值

此方法返回指向 NdbOperation 对象的指针,或者返回 NULL

NdbScanOperation::nextResult()

描述

此方法用于获取扫描交易中的下一个元组。每次调用 nextResult() 后,NdbOperation::getValue() 中定义的缓冲区和 NdbRecAttr 对象将使用扫描元组中的值进行更新。

当在文件末尾执行 nextResult() 时,NDB 返回错误代码 4210(Ndb 发送的信息超过指定长度),并且通过将额外的交易对象返回到正确的 TC 节点的空闲列表来释放它。

签名

可以使用以下两种方法之一调用此方法。第一个如下所示

int nextResult
    (
      bool fetchAllowed = true,
      bool forceSend = false
    )

也可以如下所示使用此方法

int nextResult
    (
      const char*& outRow,
      bool fetchAllowed = true,
      bool forceSend = false
    )
参数(2 参数版本)

此方法采用以下两个参数

  • 通常,NDB API 会在必要时联系 NDB 内核以获取更多元组;将 fetchAllowed 设置为 false 会阻止这种情况发生。

    通过将其设置为 false 来禁用 fetchAllowed 会强制 NDB 处理其缓存中已有的任何记录。当没有更多缓存记录时,它返回 2。然后,您必须使用等于 truefetchAllowed 调用 nextResult(),以便联系 NDB 获取更多记录。

    虽然 nextResult(false) 返回 0,但您应该使用 execute(NdbTransaction::NoCommit) 将记录传输到另一个交易。当 nextResult(false) 返回 2 时,您通常应该执行并提交其他交易。这将导致所有锁被转移到另一个交易,进行更新或删除,然后释放锁。之后,您可以调用 nextResult(true) 以便在 NDB API 中获取和缓存更多记录。

    注意

    如果您没有将记录传输到另一个交易,则下次联系 NDB 内核以获取更多记录时,将释放这些记录上的锁。

    当您要更新或删除在给定交易中获得的所有记录时,禁用 fetchAllowed 非常有用,因为这样做可以节省时间并加快扫描记录的更新或删除速度。

  • forceSend 默认为 false,通常可以省略。但是,将此参数设置为 true 意味着立即发送交易。有关更多信息,请参见 第 1.4.4 节“自适应发送算法”

参数(3 参数版本)

也可以使用以下三个参数调用此方法

  • 调用 nextResult() 会在 outRow 中设置一个指向下一行的指针(如果返回 0)。此指针仅在下次调用 nextResult() 时有效(仅当 fetchAllowed 为 true 时)。必须事先使用 NdbTransaction::scanTable()(或 NdbTransaction::scanIndex())指定定义行格式的 NdbRecord 对象。

  • 如果为 false,fetchAllowed 会强制 NDB 处理其缓存中已有的任何记录。有关此参数的更多详细信息,请参见上一 参数 小节中的说明。

  • 如上一 参数 小节以及 第 1.4.4 节“自适应发送算法” 中所述,将 forceSend 设置为 true 意味着立即发送交易。

返回值

此方法返回以下 4 个整数值之一,解释如下列表所示

  • -1:表示发生错误。

  • 0:已收到另一个元组。

  • 1:没有更多要扫描的元组。

  • 2:没有更多缓存记录(调用 nextResult(true) 以获取更多记录)。

示例

请参见 第 2.5.5 节“NDB API 基本扫描示例”

NdbScanOperation::readTuples()

描述

此方法用于执行扫描。

签名
virtual int readTuples
    (
      LockMode mode = LM_Read,
      Uint32   flags = 0,
      Uint32   parallel = 0,
      Uint32   batch = 0
    )
参数

此方法采用此处列出的四个参数

  • mode;这是一个 LockMode 值。

    使用排他锁进行扫描。 使用排他锁进行扫描时,必须格外小心,因为如果两个线程同时在同一范围内执行此扫描,则很有可能导致死锁。如果扫描也有序(即使用 SF_OrderBySF_Descending),则发生死锁的可能性会增加。

    NdbScanOperation::close() 方法也会受到此死锁的影响,因为在实际关闭扫描之前,所有未完成的请求都将得到处理。

  • 一个或多个 ScanFlag 值。多个值通过 OR 进行组合

  • parallel 中扫描的片段数;使用 0 要求使用最大可能数量。

  • batch 参数指定下一个 NdbScanOperation::nextResult(true) 方法调用从服务器返回到客户端的记录数。使用 0 自动指定最大值。

返回值

成功返回 0,失败返回 -1

NdbScanOperation::restart()

描述

使用此方法可以在不更改任何 getValue() 调用或搜索条件的情况下重新启动扫描。

签名
int restart
    (
      bool forceSend = false
    )
参数

通过将 forceSend 设置为 true 来调用此方法,以强制发送交易。

返回值

成功返回 0;失败返回 -1

NdbScanOperation::ScanFlag

本节提供有关 ScanFlag 数据类型的信息。

描述

此类型的取值是与 readTuples() 方法一起使用的扫描标志。可以使用多个值,在这种情况下,它们作为该方法的第二个参数通过 OR 进行组合。有关更多信息,请参见 NdbScanOperation::readTuples()

枚举值

下表显示了可能的值及其说明

表 2.64 NdbScanOperation::ScanFlag 的值和说明

描述
SF_TupScan 按 TUP 顺序扫描(即,按内存中行的顺序)。仅适用于表扫描。
SF_DiskScan 按磁盘顺序扫描(磁盘上行的顺序)。仅适用于表扫描。
SF_OrderBy

有序索引扫描(升序);从索引扫描返回的行已排序,并按索引键排序。按升序或降序进行的扫描都会受此标志的影响,该标志会导致 API 在每个片段的有序扫描之间执行归并排序,以获得单个排序结果集。

注意:

  • 有序索引是分布式的,表的每个片段都有一个有序索引。

  • 范围扫描通常在所有索引片段之间并行进行。有时,可以将它们修剪到一个索引片段。

  • 每个索引片段范围扫描都可以按升序或降序返回结果。默认值为升序;要选择降序,请设置 SF_Descending 标志。

  • 当并行扫描多个索引片段时,结果将发送回 NDB,在返回给用户之前,可以选择在 NDB 对其进行归并排序。此归并排序使用 SF_OrderBySF_OrderByFull 标志进行控制。

  • 如果未使用 SF_OrderBySF_OrderByFull,则每个索引片段的结果都按顺序排列(升序或降序),但来自不同片段的结果可能会交错。

  • 使用 SF_OrderBySF_OrderByFull 时,将在内部施加一些额外的约束;这些约束列举如下

    1. 如果范围扫描未修剪到一个索引片段,则必须并行扫描所有索引片段。(可以使用小于完全并行度的并行度来执行无序扫描。)

    2. 在返回任何行之前,必须先获取每个索引片段的结果,以确保正确的归并排序。这会序列化扫描的“滚动”,从而可能导致行吞吐量降低。

    3. 在所有索引片段返回任何批处理之前,无序扫描可以将行返回给 API 客户端,并且可以将下一批处理请求与行处理重叠。

SF_OrderByFull 这与 SF_OrderBy 相同,只是所有键列都会自动添加到读取位掩码中。
SF_Descending 导致按降序执行有序索引扫描。
SF_ReadRangeNo 对于索引扫描,设置此标志后,可以调用 NdbIndexScanOperation::get_range_no() 来读回 NdbIndexScanOperation::setBound() 中定义的 range_no。此外,设置此标志后,如果还设置了 SF_OrderBySF_OrderByFull,则会先返回范围内的所有结果,然后再返回后续范围内的任何结果。
SF_MultiRange 指示此扫描是多范围扫描的一部分;每个范围都单独扫描。
SF_KeyInfo 请求将 KeyInfo 发送回调用方。这使得可以使用 lockCurrentTuple() 接管扫描获取的行锁,方法是确保内核发送回标识行和锁所需的信息。默认情况下,使用 LM_Exclusive 的扫描会启用此标志,但必须显式指定才能接管 LM_Read 锁。(有关详细信息,请参阅 LockMode 文档。)

NdbScanOperation::ScanOptions

本节提供有关 ScanOptions 数据结构的信息。

父类

NdbScanOperation

描述

此数据结构用于将选项传递给 NdbRecordscanTable()scanIndex() 方法(NdbTransaction 类)。通过设置 optionsPresent 字段中的相应位来标记每个选项类型的存在。只有 optionsPresent 字段中标记的选项类型需要合理的数据。

所有数据在操作定义时从 ScanOptions 结构(以及任何子结构)中复制出来。如果不需要任何选项,则可以将 NULL 作为 ScanOptions 指针传递。

成员

下表显示了构成此结构的元素

表 2.65 NdbScanOperation::ScanOptions 属性、类型和描述

名称 类型 描述
optionsPresent Uint64 存在哪些选项。
[...] 类型:
  • SO_SCANFLAGS: 0x01

  • SO_PARALLEL: 0x02

  • SO_BATCH: 0x04

  • SO_GETVALUE: 0x08

  • SO_PARTITION_ID: 0x10

  • SO_INTERPRETED: 0x20

  • SO_CUSTOMDATA: 0x40

  • SO_PARTINFO: 0x80

选项类型。
scan_flags Uint32 控制扫描行为的标志;有关详细信息,请参阅 NdbScanOperation::ScanFlag
parallel Uint32 扫描并行度;0(默认值)设置最大并行度。
batch Uint32 从数据节点到 API 节点的传输批量大小;0(默认值)允许自动选择此值。
extraGetValues GetValueSpec 要为匹配 sdcan 条件的每一行读取的额外值。
numExtraGetValues Uint32 要读取的额外值的数量。
partitionId Uint32 将扫描限制为具有此 ID 的分区;或者,您可以在此处提供 PartitionSpec。对于索引扫描,可以为每个范围提供分区信息。
interpretedCode NdbInterpretedCode 要作为扫描的一部分执行的解释代码。
customData void* 与此扫描操作关联的数据指针。
partitionInfo PartitionSpec 用于限制此扫描的分区信息。
sizeOfPartInfo Uint32 边界分区信息的大小。

有关更多信息,请参见 第 2.3.22 节 “NdbRecord 接口”

NdbScanOperation::updateCurrentTuple()

描述

此方法用于更新当前元组。

签名

最初,可以使用单个可选参数调用此方法,如下所示

NdbOperation* updateCurrentTuple
    (
      void
    )


NdbOperation* updateCurrentTuple
    (
      NdbTransaction* updateTrans
    )

在使用 NdbRecord 进行扫描时,也可以使用此方法,如下所示

NdbOperation* updateCurrentTuple
    (
      NdbTransaction*      takeOverTrans,
      const NdbRecord*     record,
      const char*          row,
      const unsigned char* mask = 0
    )

有关详细信息,请参阅 第 2.3.22 节 “NdbRecord 接口”

参数(原始)

此方法采用一个可选参数 - 应执行锁定的交易。如果省略,则交易为当前交易。

参数(使用 NdbRecord)

使用 NdbRecord 接口时,此方法采用以下参数,如下所述

  • 接管事务 (takeOverTrans)。

  • record (NdbRecord 对象),引用用于扫描的列。

  • 要从中读取的 row。如果不需要读取任何属性,请将其设置为 NULL

  • mask 指针是可选的。如果它存在,则扫描仅检索掩码中相应位已设置的列。

返回值

此方法返回一个 NdbOperation 对象或 NULL