打破黑盒子——GaussDB(DWS)导入导出业务监控方法总结
GDS、COPY、\COPY 等工具是 GaussDB(DWS) 提供的数据导入导出工具,常应用于数据迁移、数据同步、数据备份/恢复等场景。GDS 等工具在数仓日常维护中使用频率较高,难免遇到性能、功能问题,此时如果能监控到 GDS 在干什么、业务进度如何,必然能为排故提供有效参考,提高排查效率。本文从系统视图、运行日志两个方面介绍导入导出的监控方法,并配合实例进行说明,最后简要介绍 PostgreSQL 14 的 COPY 监控视图进行简单对比。
1. 视图
目前主要有2类系统视图可以对 GDS 业务进行不同角度的实时监控:
- backend状态
- 业务执行状态
下面分别对这两类视图进行解释说明。
1.1 backend 状态
通过系统视图 pg_stat_activity、pgxc_thread_wait_status,可以获知导入/导出backend线程的执行状态,如:是否 hang、是否死锁等。
pg_stat_activity 一般会过滤 state 使用,通过在查询结果中寻找相应的 query,对所在记录进行观察分析。
select * from pg_stat_activity where state = 'active';
查询结果类似下图,图中红框框住的是刚刚发起 GDS 导入业务。
pg_stat_activity 视图提供信息有限,可与视图 pgxc_thread_wait_status 进行关联查询等待状况,确认是否存在hang以及hang的直接原因:
select wait.*, stat.query, stat.state, stat.query_start from pgxc_thread_wait_status wait inner join pg_stat_activity stat on wait.tid = stat.pid;
查询结果类似下图,图中红框框住的是刚刚发起GDS导入业务,wait_status 列的内容是“wait node(total 3): datanode3”,表示CN此刻等待的节点共有3个,其中一个是datanode3。这个结果是与测试环境1CN 3DN一致的。
1.2 业务执行状态
2021年4月发布的 GaussDB(DWS) 8.1.1 开始提供导入导出实时监控视图:pg_bulkload_statistics、pgxc_bulkload_statistics、pgxc_bulkload_progress,支持对GDS、COPY、\COPY的实时监控。与既有约定一致,pgxc_bulkload_statistics、pgxc_bulkload_progress 是在 CN 上查询,用于获取整个集群的导入导出业务的实时状况,pg_bulkload_statistics 可在各节点上执行,用于获取当前节点的导入导出业务的实时状况。注意,这类视图需要有系统管理员权限才可以访问。
pg_bulkload_statistics、pgxc_bulkload_statistics 视图字段一样,详细说明见下表。
字段名称 | 字段类型 | 字段说明 |
---|---|---|
node_name | text | 节点名称 |
db_name | text | 数据库名称 |
query_id | bigint | 查询ID |
tid | bigint | 当前线程的线程号 |
lwtid | integer | 当前线程的轻量级线程号 |
session_id | bigint | GDS的会话ID |
direction | text | 业务类型,取值包括:gds to file、gds from file、gds to pipe、gds from pipe、copy from、copy to。 |
query | text | 查询语句 |
address | text | 当前导入/导出外表的location |
query_start | timestamp | 导入/导出开始时间 |
total_bytes | bigint | 待处理数据的总大小。仅GDS普通文件导入时,且该行记录来自CN节点才会显示,否则为空。 |
phase | text | 当前业务阶段,包括: INITIALIZING(初始化)、TRANSFER_DATA(传输中)、RELEASE_RESOURCE(结束)。 |
done_lines | bigint | 已传输行数 |
done_bytes | bigint | 已传输字节数 |
pgxc_bulkload_progress 视图只可用于GDS普通文件导入业务场景,本质上是基于 pgxc_bulkload_statistics 视图的聚合结果,其字段说明如下:
字段名称 | 字段类型 | 字段说明 |
---|---|---|
session_id | bigint | GDS的会话ID |
query_id | bigint | 查询ID |
query | text | 查询语句 |
progress | text | 业务进度百分比 |
这类视图可以直接使用,或按需使用字段过滤,或者关联其他表/视图进行查询。
查询集群级导入导出的场景举例:
-- 查询集群所有的导入导出业务实时状况
select * from pgxc_bulkload_statistics;
-- 查询集群导入业务的实时进度
select * from pgxc_bulkload_progress;
-- 另外,也可以基于这类视图进行适当的计算,如计算各 DN 传输速率:
select node_name, query, round(done_bytes / 1024 / extract(epoch from(current_timestamp - query_start)), 2) || 'kB/S' as avg_speed from pgxc_bulkload_statistics;
-- 计算总导入/导出速率:
with trans_bytes as (select query_id, query, sum(done_bytes) as total_bytes from pgxc_bulkload_statistics group by (query_id,query)) select trans_bytes.*, stat.query_start, round(total_bytes / 1024 / extract(epoch from(current_timestamp - stat.query_start)), 2) || 'kB/S' as speed from trans_bytes, pg_stat_activity as stat where trans_bytes.query_id = stat.query_id;
以上样例的执行效果如图:
查询节点级导入导出业务的场景举例:
-- 查询当前节点的导入导出业务的实时进度
select * from pg_bulkload_statistics;
-- 与pg_thread_wait_status关联查询,查看是否有hang
select stat.*, wait.wait_status, wait.wait_event from pg_bulkload_statistics stat join pg_thread_wait_status wait on stat.tid = wait.tid;
以上样例的执行效果如图:
2. 日志
导入导出业务会在不同的执行阶段向运行日志中写入业务状态记录,所以我们也可以通过日志查看执行状况。但是由于获取日志的不便性,以及分析日志的滞后性,日志获取状况是最最最后的方法,我们推荐实时视图作为导入导出监控的首选方法。
2.1 CN/DN 日志
根据业务的不同阶段和类型,打印日志内容如下表所示:
初始化阶段 | 数据传输阶段 | 结束阶段 | |
---|---|---|---|
gds import | session XXXXX gds import is in the INITIALIZING state. | sesssion: XXXXX gds import is transforming from INITIALIZING to TRANSFER_DATA state. | Session XXXXX gds import has transformed from TRANSFER_DATA to RELEASE_RESOURCE state. |
gds export | session: XXXXX gds export is in the INITIALIZING state. | session: XXXXX gds export is transforming from INITIALIZING to TRANSFER_DATA state. | Session XXXXX gds export has transformed TRANSFER_DATA to RELEASE_RESOURCE state. |
copy from | copy from is in the INITIALIZING state. | copy from is transforming from INITIALIZING to TRANSFER_DATA state. | copy from has transformed from TRANSFER_DATA to RELEASE_RESOURCE state. |
copy to | copy to is in the INITIALIZING of state. | copy to is transforming from INITIALIZING to TRANSFER_DATA state. | copy to has transformed from TRANSFER_DATA to RELEASE_RESOURCE state. |
2.2 GDS 日志
GDS 通过设置启动参数 --debug-level 可以控制打印日志级别。GDS 在关键环节上也有日志打印,如下列出的日志内容是比较重要的日志,默认日志级别可见:
(1)CN/DN 与 GDS 建连时:
关键内容: [HandleAccept] "ip:port" connected to GDS, fd is xxx, ptr is xxx
日志示例: 2021-07-30 16:24:08.274 72442 MT LOG: [HandleAccept] "127.0.0.1:58570" connected to GDS, fd is 4, ptr is 0xfc95d0
(2)CN/DN 将要关闭连接时(只有导出业务才会有,一般是先打印DN相关的关闭信息,最后是 CN):
关键内容: Session XXXX close connection in HandleRead. addr: ip:port, conn ptr is xxx
日志示例:2021-07-31 10:34:42.345 3478 WT LOG: Session 81627743246173930 close connection in HandleRead. addr: 127.0.0.1:46600, conn ptr is 0xfc7bc0
(3)CN/DN关闭连接时:
关键内容:xxx closed. Event: READING/WRITING
日志示例:2021-07-30 16:24:36.208 3478 WT LOG: Session: 81627743246142387 HandleError Node: datanode1 IP: 127.0.0.1:58580, fd is 17, connect ptr is 0xfc81b0 closed. Event: READING
(4)主线程成功把工作分配给工作线程:
关键内容:Session xxx is being transfered to worker.
日志示例:2021-07-30 16:30:06.148 72442 MT LOG: Session 81627743246142569 is being transfered to worker.
3. 结合实例,学以致用
3.1 例1:发现copy性能瓶颈
在 COPY 导出的时候,执行视图发现同一时刻只有1个DN的传输量在增加,表明是CN是阻塞地只接收某一DN到结束,然后才开始接收下一个DN数据,存在性能问题,说明copy有较大优化空间,可以尝试使用并行读取提高性能。
3.2 例2:区分是执行慢还是hang
某测试集群执行 GDS 业务比平常慢很多,耗时很长仍没有结束,怀疑是 GDS hang 住。通过查询导入导出视图发现传输数据是在缓慢增加的,进一步查看发现此刻集群上有其他导入导出业务在运行,此时集群已经承压较大,业务缓慢是正常现象,由此自证清白,排除了 hang 问题。
4. 知识扩展:PostgreSQL是怎么做的?
PostgreSQL 14 之前并没有专门针对导入导出业务的监控工具,如果要进行监控,只能使用 pg_stat_activity、pg_locks 等通用视图。社区也注意到了这方面的缺陷,故前不久发布的PostgreSQL 14新增了对COPY命令的实时监控视图 pg_stat_progress_copy,可监控所有正在执行的COPY命令,具体的代码提交请参考 ReportProgressOfCopyCommands。
每当 COPY 运行时,pg_stat_progress_copy 视图将为当前运行 COPY 命令的每个 backend 构造一行记录。下表对视图字段进行说明:
字段名称 | 字段类型 | 字段说明 |
---|---|---|
pid | integer | backend进程号 |
datid | oid | backend连接的database的oid |
datname | name | backend连接的database的名字 |
relid | oid | 执行COPY命令的表的OID。如果从SELECT查询复制,则设置为0。 |
command | text | 正在运行的命令为:COPY FROM或COPY TO。 |
type | text | 用于读/写数据的IO类型:FILE, PROGRAM, PIPE(用于COPY from STDIN和COPY to STDOUT),或CALLBACK(例如在逻辑复制的初始表同步过程中使用)。 |
bytes_processed | bigint | COPY命令已经处理的字节数。 |
bytes_total | bigint | COPY FROM命令中源文件的大小,以字节为单位。如果不可用,则设置为0。 |
tuples_processed | bigint | COPY命令已经处理的元组数目。 |
tuples_excluded | bigint | 由于COPY命令的WHERE子句排除了它们而未处理的元组的数目。 |
以下是使用 PostgreSQL 14 Beta2 版本执行 COPY 文件导入时,查询监控视图的结果:
对比可知,GaussDB(DWS) 导入导出监控视图提供的信息更全面,包括具体文件名、query 语句、执行时间、执行阶段等关键信息,基于此可以进行较为复杂的聚合计算,提供不同的监控视角;PostgreSQL 14 相对比较简单,但其字段 tuples_excluded 可以额外刻画 WHERE 过滤掉的tuples。
- 点赞
- 收藏
- 关注作者
评论(0)