【 使用环境 】生产环境
【 OB or 其他组件 】OB
【 使用版本 】 OceanBase 构建版本号:4.2.1.4-104000052024022918
【问题描述】生产2.6亿rows 数据量表 varchar 6k 扩容到7k,耗时太长未结束,磁盘使用超原表占用的2倍
【备注】基于 LLM 和开源文档 RAG 的论坛小助手已开放测试,在发帖时输入 [@论坛小助手] 即可召唤小助手,欢迎试用!
根因分析场景: DDL过程中报磁盘空间不足的问题 (虽然这里主要问题是耗时和空间使用,但与DDL操作相关)
根因分析命令: obdiag rca run --scene=ddl_disk_full
日志采集场景: 合并问题
日志采集命令: obdiag gather scene run --scene=observer.compaction
尊敬的用户,根据您描述的情况,在生产环境中对包含2.6亿行数据的大表进行varchar字段扩容操作时遇到了耗时过长以及磁盘使用超出预期的问题。我们建议您使用obdiag工具来进行日志采集和根因分析,以便更好地理解DDL执行期间的具体情况。
为了评估和加快这个过程,请先运行上述命令,并将采集到的日志提供给我们。这将有助于我们了解是否存在合并问题或其他潜在因素影响了DDL操作的效率。
另外,为了确定具体的问题,在此需要您提供一些信息:
- 在执行DDL之前是否有足够的空闲磁盘空间?请提供当前磁盘使用率。
- 是否有其他同时运行的大规模查询或写入操作可能影响性能?
- 该DDL操作是否在一个维护窗口内完成?如果不是,请说明是在什么情况下执行的。
- 您是否尝试过在非高峰时段执行类似的DDL操作?如果有,请分享结果。
- 能否提供关于这张表的更多信息,例如索引数量、分区策略等?
通过收集这些信息,我们可以更准确地分析问题并给出优化建议。
附上敏捷诊断工具 obdiag 使用帮助链接
根据您提供的信息,表的大小为99GB,在执行VARCHAR字段从6K扩展到7K的操作过程中,磁盘使用量超过了300GB。这表明在进行DDL(数据定义语言)操作时,OceanBase数据库会创建临时对象来处理表结构的变化,这可能会导致额外的空间消耗。
提前评估磁盘使用量
对于如何提前评估磁盘使用量的问题,您可以参考以下步骤:
-
估算临时表空间需求:
- 在执行DDL操作之前,OceanBase会为该表创建一个副本以确保数据一致性。因此,理论上需要至少与原表相同大小的额外空间。
- 对于大表,特别是当涉及到修改列类型或增加长度时,可能还需要更多的临时存储来保存中间状态的数据。具体来说,如果只是简单地扩大VARCHAR字段的长度,并且没有其他复杂的约束条件或索引调整,则额外所需的空间应该不会超过原表大小的一倍。
-
检查现有配置参数:
- 使用
SHOW PARAMETERS LIKE 'datafile_size';
等命令查看当前的数据文件配置情况,确保有足够的可用磁盘空间供DDL操作使用。 - 注意监控磁盘使用率,避免因磁盘满而导致DDL失败或其他服务受到影响。
- 使用
-
模拟测试环境:
- 如果有条件的话,在类似的非生产环境中先做一次相同的DDL变更,观察实际消耗了多少磁盘空间,以此作为参考。
-
利用SQL查询预估:
- 可以通过查询系统表来获取更精确的估计值。例如,可以使用类似如下的SQL语句来计算表中所有行的最大可能增长量:
其中SELECT SUM(LENGTH(column_name)) AS current_length, COUNT(*) * (new_length - old_length) AS estimated_growth FROM your_table;
column_name
是要更改的VARCHAR字段名,new_length
和old_length
分别是新的和旧的最大字符数限制。
- 可以通过查询系统表来获取更精确的估计值。例如,可以使用类似如下的SQL语句来计算表中所有行的最大可能增长量:
查看字段扩容进度
关于如何查看字段扩容进度的问题,OceanBase并没有直接提供一个专门用于跟踪DDL进度的视图或工具。但是,您可以采取以下几种方法间接了解DDL的状态:
-
监控系统资源:通过操作系统级别的工具(如Linux下的
top
、iostat
等)或者OCP平台上的性能指标图表,观察CPU、内存、I/O活动等是否处于高水平,这通常意味着有大型任务正在进行。 -
查询内部表:虽然不能直接显示DDL进度百分比,但可以通过查询某些系统表来判断DDL是否仍在运行。例如,可以查看
gv$ob_ddl_task_status
视图中的相关信息。 -
日志文件分析:检查observer的日志文件,寻找有关DDL操作的日志记录,这些日志可以帮助确认DDL是否已经开始以及它所处的大致阶段。
综上所述,为了避免未来遇到类似问题,建议在执行大规模DDL之前做好充分准备,包括但不限于预留足够的磁盘空间、选择合适的维护窗口期、以及在必要时联系技术支持团队获得专业指导。同时,尽量避免在业务高峰期进行此类操作,以免影响在线服务的稳定性。
更多信息请查看:
- 某租户下所有表占用磁盘大小
- 配置磁盘数据文件的动态扩容
- datafile_next
- 检查主机信息
- datafile_disk_percentage
- max_syslog_file_count
- backup_data_file_size
- memory_limit_percentage
(小助手的答复已结束,如未能解决您的问题,请继续提问并等待其他同学的回复,谢谢!)
±---------------±-----------------+
| current_length | estimated_growth |
±---------------±-----------------+
| 1814191789391 | 311556135000 |
±---------------±-----------------+ 100G的表,扩字段过程中怎么磁盘使用超过500G?
可以用过下面的语句查询一下
select tenant_id from __all_tenant where tenant_name = ‘租户名’;
select table_id from __all_virtual_table where table_name = ‘表名’ and tenant_id = ‘租户id’;
select svr_ip, svr_port, sum(original_size) as estimated_data_size from __all_virtual_tablet_sstable_macro_info where tablet_id in (select tablet_id from __all_virtual_tablet_to_table_history where table_id = xxx) and (svr_ip, svr_port) in (select svr_ip, svr_port from __all_virtual_ls_meta_table where role = 1) group by svr_ip, svr_port;
±-------------±---------±--------------------+
| svr_ip | svr_port | estimated_data_size |
±-------------±---------±--------------------+
| xxx.xx.xx.xx | 4882 | 2352734113549 |
±-------------±---------±--------------------+
ip脱敏了
参数查一下 磁盘 df -h查看一下
show parameters where name in (‘memory_limit’,‘memory_limit_percentage’,‘system_memory’,‘log_disk_size’,‘log_disk_percentage’,‘datafile_size’,‘datafile_disk_percentage’);
±------±---------±-------------------------±----------±------±------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------±-----------±--------±--------±------------------+
| zone | svr_type | name | data_type | value | info | section | scope | source | edit_level |
±------±---------±-------------------------±----------±------±------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------±-----------±--------±--------±------------------+
| zone5 | observer | log_disk_percentage | NULL | 0 | the percentage of disk space used by the log files. Range: [0,99] in integer;only effective when parameter log_disk_size is 0;when log_disk_percentage is 0: a) if the data and the log are on the same disk, means log_disk_percentage = 30 b) if the data and the log are on the different disks, means log_disk_perecentage = 90 | LOGSERVICE | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone5 | observer | log_disk_size | NULL | 0M | the size of disk space used by the log files. Range: [0, +∞) | LOGSERVICE | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone5 | observer | memory_limit_percentage | NULL | 90 | the size of the memory reserved for internal use(for testing purpose). Range: [10, 95] | OBSERVER | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone5 | observer | system_memory | NULL | 50G | the memory reserved for internal use which cannot be allocated to any outer-tenant, and should be determined to guarantee every server functions normally. Range: [0M,) | OBSERVER | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone5 | observer | datafile_disk_percentage | NULL | 0 | the percentage of disk space used by the data files. Range: [0,99] in integer | SSTABLE | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone5 | observer | datafile_size | NULL | 0M | size of the data file. Range: [0, +∞) | SSTABLE | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone2 | observer | log_disk_percentage | NULL | 0 | the percentage of disk space used by the log files. Range: [0,99] in integer;only effective when parameter log_disk_size is 0;when log_disk_percentage is 0: a) if the data and the log are on the same disk, means log_disk_percentage = 30 b) if the data and the log are on the different disks, means log_disk_perecentage = 90 | LOGSERVICE | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone2 | observer | log_disk_size | NULL | 0M | the size of disk space used by the log files. Range: [0, +∞) | LOGSERVICE | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone2 | observer | memory_limit_percentage | NULL | 90 | the size of the memory reserved for internal use(for testing purpose). Range: [10, 95] | OBSERVER | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone2 | observer | system_memory | NULL | 50G | the memory reserved for internal use which cannot be allocated to any outer-tenant, and should be determined to guarantee every server functions normally. Range: [0M,) | OBSERVER | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone2 | observer | datafile_disk_percentage | NULL | 0 | the percentage of disk space used by the data files. Range: [0,99] in integer | SSTABLE | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone2 | observer | datafile_size | NULL | 0M | size of the data file. Range: [0, +∞) | SSTABLE | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone1 | observer | log_disk_percentage | NULL | 0 | the percentage of disk space used by the log files. Range: [0,99] in integer;only effective when parameter log_disk_size is 0;when log_disk_percentage is 0: a) if the data and the log are on the same disk, means log_disk_percentage = 30 b) if the data and the log are on the different disks, means log_disk_perecentage = 90 | LOGSERVICE | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone1 | observer | log_disk_size | NULL | 0M | the size of disk space used by the log files. Range: [0, +∞) | LOGSERVICE | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone1 | observer | memory_limit_percentage | NULL | 90 | the size of the memory reserved for internal use(for testing purpose). Range: [10, 95] | OBSERVER | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone1 | observer | system_memory | NULL | 50G | the memory reserved for internal use which cannot be allocated to any outer-tenant, and should be determined to guarantee every server functions normally. Range: [0M,) | OBSERVER | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone1 | observer | datafile_disk_percentage | NULL | 0 | the percentage of disk space used by the data files. Range: [0,99] in integer | SSTABLE | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone1 | observer | datafile_size | NULL | 0M | size of the data file. Range: [0, +∞) | SSTABLE | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone3 | observer | log_disk_percentage | NULL | 0 | the percentage of disk space used by the log files. Range: [0,99] in integer;only effective when parameter log_disk_size is 0;when log_disk_percentage is 0: a) if the data and the log are on the same disk, means log_disk_percentage = 30 b) if the data and the log are on the different disks, means log_disk_perecentage = 90 | LOGSERVICE | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone3 | observer | log_disk_size | NULL | 0M | the size of disk space used by the log files. Range: [0, +∞) | LOGSERVICE | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone3 | observer | memory_limit_percentage | NULL | 90 | the size of the memory reserved for internal use(for testing purpose). Range: [10, 95] | OBSERVER | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone3 | observer | system_memory | NULL | 50G | the memory reserved for internal use which cannot be allocated to any outer-tenant, and should be determined to guarantee every server functions normally. Range: [0M,) | OBSERVER | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone3 | observer | datafile_disk_percentage | NULL | 0 | the percentage of disk space used by the data files. Range: [0,99] in integer | SSTABLE | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone3 | observer | datafile_size | NULL | 0M | size of the data file. Range: [0, +∞) | SSTABLE | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone4 | observer | log_disk_percentage | NULL | 0 | the percentage of disk space used by the log files. Range: [0,99] in integer;only effective when parameter log_disk_size is 0;when log_disk_percentage is 0: a) if the data and the log are on the same disk, means log_disk_percentage = 30 b) if the data and the log are on the different disks, means log_disk_perecentage = 90 | LOGSERVICE | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone4 | observer | log_disk_size | NULL | 0M | the size of disk space used by the log files. Range: [0, +∞) | LOGSERVICE | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone4 | observer | memory_limit_percentage | NULL | 90 | the size of the memory reserved for internal use(for testing purpose). Range: [10, 95] | OBSERVER | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone4 | observer | system_memory | NULL | 50G | the memory reserved for internal use which cannot be allocated to any outer-tenant, and should be determined to guarantee every server functions normally. Range: [0M,) | OBSERVER | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone4 | observer | datafile_disk_percentage | NULL | 0 | the percentage of disk space used by the data files. Range: [0,99] in integer | SSTABLE | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
| zone4 | observer | datafile_size | NULL | 0M | size of the data file. Range: [0, +∞) | SSTABLE | CLUSTER | DEFAULT | DYNAMIC_EFFECTIVE |
±------±---------±-------------------------±----------±------±------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------±-----------±--------±--------±------------------+
30 rows in set (0.01)
列操作扩容varchar 这种,怎么看进度呢?(数据重写) 以及评估磁盘使用量呢?
这个不大合理。varchar 变长是 onlineddl,并且也不会改老的数据。你发一下表结构,这个 ddl 应该是很快返回吧
你确认空间问题跟这个 ddl 有关系?
CREATE TABLE t_p_rrp_rate_result_his
(
ID
varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT ‘主键’,
EVENT_CODE
varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT ‘事件ID【废弃】’,
CUST_ID
varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT ‘客户号’,
CUST_NAME
varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT ‘客户名称’,
CUST_TYPE
varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT ‘客户类型’,
ORG_ID
varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT ‘客户机构’,
RATE_STATE
varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT ‘评审状态’,
RATE_CHANNEL
varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT ‘评级任务来源’,
RATE_DT
date DEFAULT NULL COMMENT ‘机评日期’,
RATE_LEVEL
varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT ‘机评等级(评级后设置, 评级)’,
RATE_SCORE
decimal(10,4) DEFAULT NULL COMMENT ‘机评积分(评级后设置, 积分)’,
RATE_BATCH_NO
varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT ‘机评批次号(跑批批次)’,
NEXT_RATE_DT
date DEFAULT NULL COMMENT ‘下次评级日期(评级后设置, 根据风险等级)’,
HEAR_DT
date DEFAULT NULL COMMENT ‘评级审批处理时限’,
LAST_RATE_DT
date DEFAULT NULL COMMENT ‘上一次评级时间(重评后设置, 来源机评日期)’,
LAST_RATE_LEVEL
varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT ‘上一次评级等级(重评后设置, 来源最终评级等级)’,
LAST_RATE_SCORE
decimal(10,4) DEFAULT NULL COMMENT ‘上一次评级积分(重评后设置, 来源最终评级积分)’,
RESULT_RATE_LEVEL
varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT ‘最终评级等级(机评、审查岗设置, 来源机评等级、调整等级)’,
RESULT_RATE_SCORE
decimal(10,4) DEFAULT NULL COMMENT ‘最终评级积分(机评、审查岗设置, 来源机评等级、调整积分)’,
AGAIN_ADJUST_AT
varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT ‘重评发起人【废弃】’,
AGAIN_ADJUST_DT
datetime DEFAULT NULL COMMENT ‘重评发起日期【废弃】’,
MODIFY_ID
varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT ‘评级调整记录表主键(审查岗、审批岗调整后设置)’,
RATE_INFO
text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT ‘机评分数明细【废弃】’,
IS_ROBOT_DEAL
tinyint(3) DEFAULT NULL COMMENT ‘是否机器人处理,1:待处理 2:已处理’,
RATE_INDEX_CONDITION_JSON
varchar(6000) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT ‘指标条件’,
RATE_EXCEPTIONAL_CASE_JSON
varchar(6000) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT ‘触发规则项’,
RATE_INDEX_RESULT_JSON
varchar(6000) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT ‘指标结果’,
RATE_SOURCE
tinyint(1) DEFAULT NULL COMMENT ‘评级来源 1:系统,0:人工’,
OTHER_ADJUST_REASON
varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT ‘其他调整原因’,
CREATED_AT
datetime DEFAULT NULL COMMENT ‘创建时间’,
CREATED_BY
varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT ‘创建人’,
UPDATED_AT
datetime DEFAULT NULL COMMENT ‘修改时间’,
UPDATED_BY
varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT ‘修改人’,
BATCH_DATE
date DEFAULT NULL COMMENT ‘批次日期’,
IS_TRIGGER_RE_RATING
tinyint(3) DEFAULT NULL COMMENT ‘是否触发重新评级:1是;0否(用于重评表标识)’,
IS_TRIGGER_DUE_DILIGENCE
tinyint(3) DEFAULT NULL COMMENT ‘是否触发尽职调查:1是;0否【废弃】’,
ADJUST_REASON
varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT ‘调整原因(英文分号拼接)[参见基础码值ADJUST_REASON]’,
MODEL_ID
varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT ‘权重评级模板id’,
risk_hit_type
varchar(2) DEFAULT NULL COMMENT ‘特定风险命中类型’,
risk_hit_content
varchar(64) DEFAULT NULL COMMENT ‘特定风险命中内容’,
CREATED_HIS_AT
datetime DEFAULT NULL COMMENT ‘写入历史表日期’,
PRIMARY KEY (ID
),
KEY idx_rate_result_his_cust_id
(CUST_ID
) BLOCK_SIZE 16384 LOCAL,
KEY idx_rate_result_his_batch_date
(BATCH_DATE
) BLOCK_SIZE 16384 LOCAL,
KEY idx_rate_result_his_rate_batch_no
(RATE_BATCH_NO
) BLOCK_SIZE 16384 LOCAL,
KEY idx_rate_result_his_rate_dt
(RATE_DT
) BLOCK_SIZE 16384 LOCAL
);
alter 执行一个多小时报错 out of disk space。期间primary zone 一直增长
超90多影响集群正常写入了,所以后面大表列修改,要提前评估磁盘使用量
无法再次编辑订正已回复的消息?405 Not Allowed
好,谢谢。
“alter 执行一个多小时报错 out of disk space。期间primary zone 一直增长”
这个 alter ddl 是怎么写的?
alter table t_p_rrp_rate_result_his modify column RATE_INDEX_RESULT_JSON
varchar(7000) NULL COMMENT ‘指标结果’;
estimated_data_size
这个查询 sql 也发一下。
select svr_ip, svr_port, sum(original_size) as estimated_data_size from __all_virtual_tablet_sstable_macro_info where tablet_id=225602 and svr_ip=‘xxx.xx.xx.xx’ and svr_port=‘4882’ group by svr_ip, svr_port;
参数查询 保存在文本里 这样不太友好查看
你是修改的字段的类型varchar的长度是吧 ob4.3排序导致的临时表空间的膨胀 不够优化 膨胀挺多的
我看这个源空间 2.1T了 这个修改命中的应该是offline ddl操作 你先查看一下参数 我在看看还需要扩容不
select * from oceanbase.gv$session_longops \G;这个可以查看进度
是的。这个修改,有其他更好的方式修改嘛?
select * from oceanbase.gv$session_longops只能看到 扫描的行数(当时有观察),10分钟左右1千万rows ,可以作为执行进度嘛? 当时还没扫描5千万行,磁盘就90%禁止写入报错了 ,使用了500多GB
磁盘设置的有阈值 所以看 memory_limit memory_limit_percentage的设置的大小 4.3之前的版本 膨胀挺大的 建议磁盘设置大点
看着是在leader节点上 预估的ddl操作的空间 需要截图那么多的空间 尽量在扩容磁盘