事务是阿里云E-MapReduce(简称EMR)产品自研的特性,目前处于Experimental阶段。本文为您介绍事务的状态、参数以及事务的相关操作。

前提条件

已在EMR控制台上创建ClickHouse集群,且集群中已配置了可使用的ZooKeeper服务,创建详情请参见创建集群

注意事项

  • 事务仅支持Insert,且Insert的对象必须是以Replicated*MergeTree或者*MergeTree为存储引擎的表。
  • 当前的事务为单机事务。
  • 本功能处在Experimental阶段,请谨慎使用。

事务API

ACTION TYPE

事务允许的操作如下表所示。
操作 描述
begin 开启一个事务。
write_data 在一个事务内写数据。
commit 提交一个事务。
rollback 回滚一个未提交的事务。

STATE TYPE

事务状态如下表所示。
状态 描述
UNKNOWN 事务未开启,此时仅允许begin操作。
INITIALIZED 事务已开启,此时允许所有操作。
COMMITTING 事务正在被提交,不允许执行begin或write_data两种操作。
COMMITTED 事务已经被提交,不再允许任何操作。
ABORTING 事务正在被回滚,不再允许任何操作。
ABORTED 事务已经被回滚,不再允许任何操作。

错误码

错误码 描述
0 执行成功。
11001 未知的事务操作类型。
11002 未知的事务状态。
11003 多个机器存在一个相同的事务处理。
11004 重定向至其他机器。
11005 不支持的存储引擎。
11006 事务未在任何机器上处理。
11201 当前事务状态为COMMITTING,但收到了begin请求。
11202 当前事务状态为COMMITTED,但收到了begin请求。
11203 当前事务状态为ABORTING,但收到了begin请求。
11204 当前事务状态为ABORTED,但收到了begin请求。
11301 当前事务状态为UNKNOWN,但收到了commit请求。
11302 当前事务状态为ABORTING,但收到了commit请求。
11303 当前事务状态为ABORTED,但收到了commit请求。
11401 当前事务状态为UNKNOWN,但收到了rollback请求。
11402 当前事务状态为COMMITTED,但收到了rollback请求。
11501 当前事务状态为UNKNOWN,但收到了write_data请求。
11502 当前事务状态为COMMITTING,但收到了write_data请求。
11503 当前事务状态为COMMITTED,但收到了write_data请求。
11504 当前事务状态为ABORTING,但收到了write_data请求。

HTTP PARAM

名称 类型 是否必选 描述
action 字符串 事务的操作。
id 字符串 事务的ID。
stacktrace 布尔值 是否在执行出错时向Client发送详细的堆栈信息,默认值为false。

Request Header

名称 类型 是否必选 描述
Host 字符串 ClickHouse HTTP Server的可访问地址,通常由ip:porthostname:port组成,其中port通常为8123。
Authorization 字符串 ClickHouse用以验证身份的字段,使用HTTP Basic Authentication作为验证手段。
注意 如果指定了该验证方式,则不能指定X-ClickHouse-UserX-ClickHouse-Key,否则会报错。
X-ClickHouse-User 字符串 ClickHouse用户名。
注意 通常不推荐该验证方式,因为该验证方式为明文。指定该验证方式,则不能指定 Authorization,否则会报错。
X-ClickHouse-Key 字符串 ClickHouse用户密码。
注意 通常不推荐该验证方式,因为该验证方式为明文。指定该验证方式,则不能指定 Authorization,否则会报错。
X-ClickHouse-TransactionId 字符串 ClickHouse事务ID,仅用于事务写。

Response Header

名称 类型 描述
Location 字符串 重定向的位置。

Response Body

Response Body会以JSON的形式返回,JSON内含字段如下。
名称 类型 描述
code 整型 错误码。
message 字符串 错误信息。

使用示例

开始事务

在core-1-1节点上开始一个ID为1f6676e3-496f-409e-b64e-0eb22b1c****的事务,执行命令如下。
POST /transaction?action=begin&id=1f6676e3-496f-409e-b64e-0eb22b1c**** HTTP/1.1
Host: core-1-1:8123
Authorization: Basic ZGVmYXVsdDo=
  • 执行成功时,返回如下信息。
    HTTP/1.1 200 OK
    Date: Fri, 14 Jan 2022 07:45:32 GMT
    Connection: Close
    Content-Type: application/json;charset=UTF-8
    {
      "code": 0,
      "message": "Success."
    }
  • 执行失败时,返回如下类似信息。
    HTTP/1.1 200 OK
    Date: Fri, 14 Jan 2022 08:00:43 GMT
    Connection: Close
    Content-Type: application/json;charset=UTF-8
    
    {
      "code": 11202,
      "message": "Received the request of transaction begin after the transaction was committed."
    }
  • 重定向时,返回如下信息。
    HTTP/1.1 307 OK
    Date: Fri, 14 Jan 2022 07:47:18 GMT
    Connection: Close
    Location: http://192.168.**.**:8123/transaction?action=begin&id=1f6676e3-496f-409e-b64e-0eb22b1c****
    Content-Type: application/json;charset=UTF-8
    
    {
      "code": 11004,
      "message": "Redirect to other replica."
    }
    说明 向其他节点上发送请求会被重定向至core-1-1,其IP地址为192.168.**.**。

事务写

在core-1-1节点上,向以下表结构中写入数据,写的过程包含在事务1f6676e3-496f-409e-b64e-0eb22b1c****中。
CREATE TABLE test.test ON CLUSTER cluster_emr
(
    `id` UInt32,
    `t` DateTime
)
ENGINE = MergeTree
PARTITION BY toStartOfFiveMinute(t)
ORDER BY id;
执行命令如下。
POST /?query=INSERT%20INTO%20test.test%20VALUES%20(1,'2022-01-13%2020:03:01') HTTP/1.1
Authorization: Basic ZGVmYXVsdDo=
Host: core-1-1.cluster-276***:8123
Content-Length: 0
X-ClickHouse-TransactionId: 31a8b711-c174-481a-be9d-e2c229c8****
  • 执行成功时,返回如下信息。
    HTTP/1.1 200 OK
    Date: Fri, 14 Jan 2022 07:53:20 GMT
    Connection: Keep-Alive
    Content-Type: text/tab-separated-values; charset=UTF-8
    X-ClickHouse-Server-Display-Name: core-1-1.cluster-276***
    Transfer-Encoding: chunked
    X-ClickHouse-Query-Id: 1135ae61-a38d-400d-94e1-df3a67cd****
    X-ClickHouse-Format: TabSeparated
    X-ClickHouse-Timezone: Asia/Shanghai
    Keep-Alive: timeout=3
    X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}                    
  • 执行失败时,返回如下类似信息。
    HTTP/1.1 500 Internal Server Error
    Date: Fri, 14 Jan 2022 08:01:54 GMT
    Connection: Keep-Alive
    Content-Type: text/tab-separated-values; charset=UTF-8
    X-ClickHouse-Server-Display-Name: core-1-1.cluster-276***
    Transfer-Encoding: chunked
    X-ClickHouse-Query-Id: c9a65f05-d52e-4f2a-a892-77f11799****
    X-ClickHouse-Format: TabSeparated
    X-ClickHouse-Timezone: Asia/Shanghai
    X-ClickHouse-Exception-Code: 11503
    Keep-Alive: timeout=3
    X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
    
    Code: 11503, e.displayText() = DB::Exception: Received the request of writing data after the transaction was committed. (version 21.3.**.**)
  • 重定向时,返回如下信息。
    HTTP/1.1 307 Temporary Redirect
    Date: Fri, 14 Jan 2022 07:52:15 GMT
    Connection: Keep-Alive
    Content-Type: text/plain; charset=UTF-8
    X-ClickHouse-Server-Display-Name: core-1-2.cluster-276***
    Transfer-Encoding: chunked
    Location: http://192.168.**.**:8123/?query=INSERT%20INTO%20test.test%20VALUES%20(1,'2022-01-13%2020:04:21')
    X-ClickHouse-Exception-Code: 11004
    
    Code: 11004, e.displayText() = DB::Exception: Failed to check replica under transaction path in zookeeper. (version 21.3.**.**)
    说明 向其他节点上发送请求会被重定向至core-1-1,其IP地址为192.168.**.**。

提交事务

在core-1-1节点上提交一个ID为1f6676e3-496f-409e-b64e-0eb22b1c****的事务,执行命令如下。
POST /transaction?action=commit&id=1f6676e3-496f-409e-b64e-0eb22b1c**** HTTP/1.1
Host: core-1-1:8123
Authorization: Basic ZGVmYXVsdDo=
  • 提交成功时,返回如下信息。
    HTTP/1.1 200 OK
    Date: Fri, 14 Jan 2022 07:55:09 GMT
    Connection: Close
    Content-Type: application/json;charset=UTF-8
    
    {
      "code": 0,
      "message": "Success."
    }
  • 提交失败时,返回如下类似信息。
    HTTP/1.1 200 OK
    Date: Fri, 14 Jan 2022 08:03:39 GMT
    Connection: Close
    Content-Type: application/json;charset=UTF-8
    
    {
      "code": 11303,
      "message": "Received the request of transaction commit after the transaction was aborted."
    }
  • 重定向时,返回如下信息。
    HTTP/1.1 307 OK
    Date: Fri, 14 Jan 2022 07:56:30 GMT
    Connection: Close
    Location: http://192.168.**.**:8123/transaction?action=commit&id=1f6676e3-496f-409e-b64e-0eb22b1c****
    Content-Type: application/json;charset=UTF-8
    
    {
      "code": 11004,
      "message": "Redirect to other replica."
    }
    说明 向其他节点上发送请求会被重定向至core-1-1,其IP地址为192.168.**.**。

回滚事务

在core-1-1节点上回滚一个ID为1f6676e3-496f-409e-b64e-0eb22b1c****的事务,执行命令如下。
POST /transaction?action=rollback&id=1f6676e3-496f-409e-b64e-0eb22b1c**** HTTP/1.1
Host: core-1-1:8123
Authorization: Basic ZGVmYXVsdDo=s
  • 回滚成功时,返回如下信息。
    HTTP/1.1 200 OK
    Date: Fri, 14 Jan 2022 08:03:08 GMT
    Connection: Close
    Content-Type: application/json;charset=UTF-8
    
    {
      "code": 0,
      "message": "Success."
    }
  • 回滚失败时,返回如下类似信息。
    HTTP/1.1 200 OK
    Date: Fri, 14 Jan 2022 07:58:41 GMT
    Connection: Close
    Content-Type: application/json;charset=UTF-8
    
    {
      "code": 11402,
      "message": "Received the request of transaction rollback after the transaction was committed."
    }
  • 重定向时,返回如下信息。
    HTTP/1.1 307 OK
    Date: Fri, 14 Jan 2022 07:59:33 GMT
    Connection: Close
    Location: http://192.168.**.**:8123/transaction?action=rollback&id=1f6676e3-496f-409e-b64e-0eb22b1c****
    Content-Type: application/json;charset=UTF-8
    
    {
      "code": 11004,
      "message": "Redirect to other replica."
    }
    说明 向其他节点上发送请求会被重定向至core-1-1,其IP地址为192.168.**.**。

相关配置

参数 描述
transaction.enable_public_ip ClickHouse Server中Transaction需要一个用于标识自身的IP地址,默认使用私网IP地址。

在EMR控制台ClickHouse服务的server-config页签中,设置此参数值为true,以使用公网IP地址标识自身,但需要所有节点均开启公网IP。

transaction.path_prefix Transaction在ZooKeeper中的目录前缀。默认为/clickhouse/transactions
transaction.transaction_timeout_ms Transaction超时时间,默认值为86400000毫秒(1天)。
transaction.auxiliary_zookeepers Transaction使用的ZooKeeper名称,默认为default,对应了配置在EMR控制台ClickHouse服务的server-metrika页签中参数zookeeper_servers的Zookeeper。
transaction.distributed_lock_timeout_ms 分布式锁超时的时间,默认值为120000毫秒(2分钟)。