大表数据如何在OceanBase中进行表分区管理的实践

news2024/9/20 15:29:16

背景

将Zabbix的数据库迁移至OceanBase后,以其中的几个大表作为案例,本文将分享如何利用ODC(OceanBase 开发者工具),来进行自动管理OB数据库中的表分区的方案。

因为原始表里已经有大量的数据,如果贸然对原始表去创建表分区的话,可能会造成长时间的缩影,所以,当前的整体思路是:

  1. 为每个要操作的表创建一个 [tb_name]---->临时表[tb_name_tmp],表结构语原始表保持一致;
  2. 通过代码为每个临时表 [tb_name_tmp]生成表分区创建语句;
  3. 为每个临时表 [tb_name_tmp]创建表分区;
  4. 将操作日前一天的数据通过 insert into select 写入到临时表 [tb_name_tmp]中,并校验
  5. 停止应用,并将剩余数据写入到临时表 [tb_name_tmp]中
  6. 将原始表[tb_name]重名为[tb_name_bak],并将临时表 [tb_name_tmp]重命名为[tb_name]
  7. 启动服务,并检查服务是否正常,如果服务异常,检查数据是否正确;
  8. 如果服务正常,在odc中为相关表创建表分区维护计划;
  9. 一段时间后,将原始表[tb_name_bak]进行归档或者移除;

操作对象

首先,明确需要操作的表对象是哪些:

表名作用保留时长清理间隔数据类型
history存储原始的历史数据90天每天数字(浮点数)
history_uint存储原始的历史数据90天每天数字(无符号)
history_str存储原始的短字符串数据90天每天字符型
history_text存储原始的长字符串数据90天每天文本
history_log存储原始的日志字符串数据90天每天日志
trends存储每小时统计数据(趋势)12个月每月数字(浮点数)
trends_uint保持每小时统计数据(趋势)12个月每月数字(无符号)
auditlog审计日志表

准备操作

查找各个表中的最早记录

如果记录最早时间早于保留时间,那就从保留日开始导入,如果晚于保留开始日期,则用最早记录的日期开始建立分区

SELECT FROM_UNIXTIME(MIN(clock)) FROM history;

SELECT FROM_UNIXTIME(MIN(clock)) FROM history_uint;

SELECT FROM_UNIXTIME(MIN(clock)) FROM history_str;

SELECT FROM_UNIXTIME(MIN(clock)) FROM history_text;

SELECT FROM_UNIXTIME(MIN(clock)) FROM history_log;

SELECT FROM_UNIXTIME(MIN(clock)) FROM trends;

SELECT FROM_UNIXTIME(MIN(clock)) FROM trends_uint;

创建分区表结构

SHOW CREATE TABLE history;
SHOW CREATE TABLE history_uint;
SHOW CREATE TABLE history_str;
SHOW CREATE TABLE history_text;
SHOW CREATE TABLE history_log;
SHOW CREATE TABLE trends;
SHOW CREATE TABLE trends_uint;

使用以下脚本来生成表分区

使用python生成创建表分区的SQL语句

by day

# -*- coding: utf-8 -*-            
# @Time     : 2023/6/8 10:17
# @Author   : YoKing Ma
# @FileName : create_tp_day.py
# @Software : PyCharm


import datetime

tb_name = input("Please input data table name:")

print(f"""
Please get the first day, use like this command:
SELECT FROM_UNIXTIME(MIN(clock)) FROM {tb_name}
""")
start_day = input("Please input the first day (2023-03-03): ")

# tb_name="history"
# start_day="2023-03-03"

try:
    first_date = datetime.datetime.strptime(start_day, "%Y-%m-%d")
    print(f"Your input date is [{first_date}]")
except ValueError:
    print("date format is error!")

pt_create=[]

period = 0
while period <= 90:
    curr_date = first_date + datetime.timedelta(days=period)
    curr_date_title = curr_date.strftime("%Y_%m_%d")
    tommow_date = curr_date + datetime.timedelta(days=1)
    period += 1
    sql_str=f'PARTITION p{curr_date_title} VALUES LESS THAN (UNIX_TIMESTAMP("{tommow_date}"))'
    pt_create.append(sql_str)

pt_sql_str = f"""ALTER TABLE {tb_name} PARTITION BY RANGE (clock)
("""
for sql in pt_create:
    pt_sql_str += '\n'
    pt_sql_str += sql
    pt_sql_str += ','


pt_sql_str += "\b\n);"

print(pt_sql_str)

by mouth

# -*- coding: utf-8 -*-            
# @Time     : 2023/6/8 11:27
# @Author   : YoKing Ma
# @FileName : create_tp_month.py
# @Software : PyCharm

## pip install python-dateutil

import datetime
from dateutil.relativedelta import relativedelta

tb_name = input("Please input data table name:")

print(f"""
Please get the first day, use like this command:
SELECT FROM_UNIXTIME(MIN(clock)) FROM {tb_name}
""")
start_month = input("Please input the first day (2023-03): ")

# tb_name="history"
# start_month="2022-02"

try:
    tmp_date = start_month.split('-')
    fyear = int(tmp_date[0])
    fmonth = int(tmp_date[1])
    fdate = datetime.datetime(fyear, fmonth, 1)
except ValueError:
    print("date format is error!")

pt_create=[]

period = 12
cdate = fdate
for i in range(0,13):
    title = f"{cdate.year}_{cdate.month}"
    ndate = cdate + relativedelta(months=+1)

    sql = f'PARTITION p{title} VALUES LESS THAN (UNIX_TIMESTAMP("{ndate}"))'
    pt_create.append(sql)
    cdate = ndate

pt_sql_str = f"""ALTER TABLE {tb_name} PARTITION BY RANGE (clock)
("""
for sql in pt_create:
    pt_sql_str += '\n'
    pt_sql_str += sql
    pt_sql_str += ','


pt_sql_str += "\b\n);"

print(pt_sql_str)

案例演示

如生成了 `history` 表的临时表 `history_tmp`

CREATE TABLE `history_tmp` (
  `itemid` bigint(20) unsigned NOT NULL,
  `clock` int(11) NOT NULL DEFAULT '0',
  `value` double NOT NULL DEFAULT '0',
  `ns` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`itemid`, `clock`, `ns`)
) DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_bin;

用上面的脚本,为`history_tmp`表创建表分区语句

ALTER TABLE history_tmp PARTITION BY RANGE ( clock)
(
PARTITION p2024_04_04 VALUES LESS THAN (UNIX_TIMESTAMP("2024-04-05 00:00:00")) ENGINE = InnoDB,
PARTITION p2024_04_05 VALUES LESS THAN (UNIX_TIMESTAMP("2024-04-06 00:00:00")) ENGINE = InnoDB,
……
PARTITION p2024_07_01 VALUES LESS THAN (UNIX_TIMESTAMP("2024-07-02 00:00:00")) ENGINE = InnoDB,
PARTITION p2024_07_02 VALUES LESS THAN (UNIX_TIMESTAMP("2024-07-03 00:00:00")) ENGINE = InnoDB,
PARTITION p2024_07_03 VALUES LESS THAN (UNIX_TIMESTAMP("2024-07-04 00:00:00")) ENGINE = InnoDB
);

迁移数据

分2次迁移数据,这样可以减少业务停机的时长

数据导入

第一次迁移可以把变更日前的数据全部导入,比如变更日为2024年的7月3日,那将2024年7月3日 00:00:00之前90天的数据全部导入到分区表中

INSERT /*+ append enable_parallel_dml parallel(8) */ INTO `history_tmp`(`itemid`, `clock`, `value`, `ns`)
SELECT `itemid`, `clock`, `value`, `ns`
FROM `history`
WHERE `clock` >= 1712160000 and `clock` < 1719936000;

数据校验

对比临时表中的最早和最晚的记录是否和原表一致,并检查行数是否一致。

因为zabbix有housekeeper服务,这个服务会不定时的删除表中过期的数据,所以,在导入数据的过程中会造成数据不一致的情况。可以先把zabbix的管家服务停止;
SELECT FROM_UNIXTIME(MIN(clock)) FROM history_tmp;
SELECT FROM_UNIXTIME(MAX(clock)) FROM history_tmp;
SELECT COUNT(1) FROM history WHERE `clock` >= 1712160000 and `clock` < 1719936000;      -- 402789803
SELECT COUNT(1) FROM history_tmp;   -- 402789803

校验通过后,可以停止zabbix服务,并进行剩余数据的导入。操作与上文类似就不再赘述。

修改表名

rename table history to history_bak;
rename table history_tmp to history;

修改完表名后,就启动zabbix服务,看服务日志是否有报错,报错的话需要解决报错,直至服务正常。

在ODC中创建表分区管理计划

为已经分区表创建分区计划(在odc中每个数据库只允许有1个分区计划,新的分区计划生效后,旧的就失效了)

1720061551

我这边history相关表是每日一个表分区,trends相关表是1个月做一次表分区的维护。

所以【分区策略】我就以2中类型展示:【日】和【月】

分区策略--日

1720061781

这里产生的SQL语句类似于:

ALTER TABLE `zabbix`.`history` DROP PARTITION (`p2024_04_04`);

ALTER TABLE `zabbix`.`history` ADD PARTITION (
	PARTITION `p2024_07_04` VALUES LESS THAN (1720108800));

策略中用到的表达式

分区创建表达式:unix_timestamp(DATE(NOW() - INTERVAL DAY(NOW())
表分区命名表达式:DATE_FORMAT(DATE(NOW() - INTERVAL DAY(NOW()) DAY + INTERVAL 1 DAY + INTERVAL 1 MONTH), 'p%Y_%m')

分区策略-月

1720061955

ALTER TABLE `zabbix`.`trends` DROP PARTITION (`p2023_7`);

ALTER TABLE `zabbix`.`trends` ADD PARTITION (
	PARTITION `p2024_08` VALUES LESS THAN (1725120000));

策略中用到的表达式

分区创建表达式:unix_timestamp(DATE(NOW() - INTERVAL DAY(NOW())
表分区命名表达式:DATE_FORMAT(DATE(NOW() - INTERVAL DAY(NOW()) DAY + INTERVAL 1 DAY + INTERVAL 1 MONTH), 'p%Y_%m')

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2149271.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

快速掌握Postman接口测试

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、前言 在前后端分离开发时&#xff0c;后端工作人员完成系统接口开发后&#xff0c;需要与前端人员对接&#xff0c;测试调试接口&#xff0c;验证接口的正…

【Verilog学习日常】—牛客网刷题—Verilog快速入门—VL16

使用8线-3线优先编码器Ⅰ实现16线-4线优先编码器 描述 ②请使用2片该优先编码器Ⅰ及必要的逻辑电路实现16线-4线优先编码器。优先编码器Ⅰ的真值表和代码已给出。 可将优先编码器Ⅰ的代码添加到本题答案中&#xff0c;并例化。 优先编码器Ⅰ的代码如下&#xff1a; module…

BERT模型解读与简单任务实现(论文复现)

BERT模型解读与简单任务实现&#xff08;论文复现&#xff09; 本文所涉及所有资源均在传知代码平台可获取 概述 相关背景 语言模型&#xff1a;语言模型是指对于任意的词序列&#xff0c;它能够计算出这个序列是一句话的概率。 预训练&#xff1a;预训练是一种迁移学习的概念…

c++类和对象(6个默认成员函数)第二级中阶

目录 6个默认成员函数介绍 构造函数 构造函数是什么&#xff1f; 构造函数的6种特性 析构函数 析构函数是什么&#xff1f; 析构函数的特性 拷贝构造函数 什么是拷贝构造函数 拷贝函数的特性 四.默认生成的拷贝构造实行的是浅拷贝&#xff08;值拷贝&#xff09;&am…

【2024】前端学习笔记9-内部样式表-外部导入样式表-类选择器

学习笔记 内部样式表外部导入样式表类选择器&#xff1a;class 内部样式表 内部样式表是将 CSS 样式规则写在 HTML 文档内部。通过<style>标签在 HTML 文件的<head>部分定义样式。 简单示例&#xff1a; <!DOCTYPE html><html><head><style…

【linux】基础IO(上)

1. 共识原理 文件 内容 属性文件分为 打开的文件 没打开的文件打开的文件 &#xff1a; 是进程打开的 ----- 本质是要研究文件和进程的关系没打开的文件 &#xff1a; 没打开的文件储存在磁盘上&#xff0c;由于没打开的文件很多&#xff0c;所以需要分门别类的防止好&…

常用函数式接口的使用

FunctionalInterface注解 函数式接口在java中是指:有且仅有一个抽象方法的接口。 虽然知道怎么使用&#xff0c;但是没有搞懂使用场景&#xff0c;暂且记录下使用方法吧&#xff0c;不至于看到源码的时候不知所云。 要我自己写代码&#xff0c;我是想不起来这样用的&#xff0…

YOLOv9改进策略【注意力机制篇】| 2024 SCSA-CBAM 空间和通道的协同注意模块

一、本文介绍 本文记录的是基于SCSA-CBAM注意力模块的YOLOv9目标检测改进方法研究。现有注意力方法在空间-通道协同方面未充分挖掘其潜力&#xff0c;缺乏对多语义信息的充分利用来引导特征和缓解语义差异。SCSA-CBAM注意力模块构建一个空间-通道协同机制&#xff0c;使空间注…

C语言 结构体和共用体——典型实例:洗发牌模拟

目录 如何表示52张扑克牌&#xff1f; 如何保存一副扑克牌&#xff1f; 如何发牌&#xff1f; 如何设计主函数&#xff1f; 如何模拟洗牌&#xff1f; 如何表示52张扑克牌&#xff1f; 如何保存一副扑克牌&#xff1f; 如何发牌&#xff1f; 如何设计主函数&#xff1f; 如…

窗户检测系统源码分享

窗户检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …

十大常用加密软件排行榜|2024年好用的加密软件推荐(企业必备)

在数字化时代&#xff0c;数据安全已经成为企业生存和发展的关键因素之一。随着网络攻击和数据泄露事件的频发&#xff0c;企业对数据加密的需求日益增长。选择一款可靠的加密软件&#xff0c;不仅能保护企业的核心数据&#xff0c;还能确保业务的连续性和合规性。本文将为您介…

Stable Diffusion 使用详解(11)--- 场景ICON制作

目录 背景 controlNet 整体描述 Canny Lineart Depth 实际使用 AI绘制需求 绘制过程 PS打底 场景模型选择 设置提示词及绘制参数 controlnet 设置 canny 边缘 depth 深度 lineart 线稿 效果 背景 这段时间不知道为啥小伙伴似乎喜欢制作很符合自己场景的ICON。…

共享wifi哪家公司正规合法?看这3点就够了!

随着共享wifi项目的热度不断上升&#xff0c;越来越多的公司都开始加入到共享wifi贴码的研发行列之中&#xff0c;让意向入局该项目的创业者拥有更多选择的同时&#xff0c;也让许多想要借此割一波韭菜的不法分子有了可乘之机。在此背景下&#xff0c;共享wifi哪家公司正规合法…

OpenHarmony(鸿蒙南向开发)——小型系统内核(LiteOS-A)【内核启动】

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 子系统开发内核 轻量系统内核&#xff08;LiteOS-M&#xff09; 轻量系统内核&#…

Docker安装rabbitmq并配置延迟队列

下载rabbitmq镜像 docker pull rabbitmq:management 运行rabbitmq镜像 docker run -id --namerabbitmq -p 5671:5671 -p 5672:5672 -p 4369:4369 -p 15671:15671 -p 15672:15672 -p 25672:25672 -e RABBITMQ_DEFAULT_USERtom -e RABBITMQ_DEFAULT_PASStom rabbitmq:management …

回归传统,Domino拷贝式迁移!

大家好&#xff0c;才是真的好。 前面讲太多普及型的概念&#xff0c;今天我们来点实在的内容。 在Notes/Domino的黄金年代&#xff0c;有一件事情大家干得风生水起&#xff0c;那就是Domino服务器迁移。 要么迁移到另一台硬件服务器上&#xff0c;要么迁移到新换的磁盘当中…

展会上想要留住俄罗斯客户,柯桥成人俄语培训

展品 экспонат 模型 макет 证明(书) свидетельство 预算 бюджет 确认订单 подтверждение заказа 缺点,毛病,缺陷 недостаток 退换 возвращать 更换 заменять 调整 урегулир…

[PTA]7-1 谁管谁叫爹

[PTA]7-1 谁管谁叫爹 输入格式&#xff1a; 输入第一行给出一个正整数 N&#xff08;≤100&#xff09;&#xff0c;为游戏的次数。以下 N 行&#xff0c;每行给出一对不超过 9 位数的正整数&#xff0c;对应 A 和 B 给出的原始数字。题目保证两个数字不相等。 输出格式&…

虹科干货 | CAN/CAN FD故障揭秘:快速排查与解决技巧

是否在处理CAN总线问题时感到头疼&#xff1f;是否在寻找简单直接的方法来解决那些看似复杂的连接故障&#xff1f;本文将为您提供实用技巧&#xff0c;让您能够轻松应对这些难题。 CAN总线因其高效、可靠的数据交换能力&#xff0c;在汽车、工业控制、航空航天等多个关键领域得…

【软件方案】智慧社区总体解决方案(PPT原件)

1.智慧社区整体建设方案内容 2.整体功能介绍 软件全套资料部分文档清单&#xff1a; 工作安排任务书&#xff0c;可行性分析报告&#xff0c;立项申请审批表&#xff0c;产品需求规格说明书&#xff0c;需求调研计划&#xff0c;用户需求调查单&#xff0c;用户需求说明书&…