MySQL 日志表改造为分区表

news2024/9/22 13:45:41

文章目录

    • 前言
    • 1. 分区表改造方法
    • 2. 操作步骤
      • 2.1 调整主键
      • 2.2 无锁变更
      • 2.3 回滚策略
    • 3. 分区表维护
      • 3.1 创建分区
      • 3.2 删除分区
      • 3.3 分区表查询
    • 后记

前言

业务有一张日志表,只需要保留 3 个月的数据,仅 3 月的数据就占用 80G 的存储空间,如果不定期清理那么磁盘容纳不下,但是每次清理的时候,使用 DELETE 删除非常慢,还会产生大量的 Binlog 日志,而且删除后会产生大量的空间碎片,回收需要重建表,期间还会造成临时空间增长(Online DDL 排序需要使用临时空间)需要先扩磁盘,等待空间收缩后再缩容,非常麻烦。

了解到这张表几乎不会查询,只会在发生问题的时候查询,所以非常适合使用分区表。所以就提出将普通表改造成分区表的方案,本文将介绍整个过程,如果业务也有相似的场景,可以作为参考。

1. 分区表改造方法

分区表改造,需要全程锁表,业务表示无法给出窗口时间,所以需要借助 OnlineDDL 工具,通过无锁变更的方式来改造。这里使用的工具是 gh-ost 它的原理大致如下:

官方图解 (https://github.com/github/gh-ost)

在这里插入图片描述

主要执行过程:

  1. 检查是否有外键触发器及主键信息;
  2. 检查是否主库或从库,是否开启 log_slave_updates 以及 binlog 信息;
  3. 检查 gho 和 ghc 结尾的临时表是否存在;
  4. 创建 ghc 结尾的表,存数据迁移的信息,以及 binlog 信息等;
  5. 初始化 stream 的连接,添加 binlog 的监听;
  6. 根据 alter 语句创建 gho 结尾的幽灵表;
  7. 开启迁移数据,按照主键把源表数据写入到 gho 结尾的表上,以及 binlog apply;
  8. 进入 cut-over 阶段,锁住主库的源表,等待 binlog 应用完毕,然后替换 gh-ost 表为源表;
  9. 清理 ghc 表,删除 socket 文件。

cut-over 即表 rename 阶段,gh-ost 利用了 MySQL 的一个特性,原子性的 rename 请求,在所有被 blocked 的请求中,rename 优先级永远是最高的。gh-ost 基于此设计了该方案:一个连接对原表加锁,另启一个连接尝试 rename 操作,此时会被阻塞住,当释放 lock 的时候,rename 会首先被执行,其他被阻塞的请求会继续应用到新表。

2. 操作步骤

下方为脱敏后的表结构,目前已有 80G 的数据,业务依赖 created_at 作为保留日期参考字段,目前有 4~8 月的数据。

CREATE TABLE `xxxx_log` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
  `user_id` bigint(20) NOT NULL COMMENT '用户id',
  `user_name` varchar(60) DEFAULT NULL COMMENT '用户名',
  `user_ip` varchar(60) NOT NULL COMMENT '用户ip',
  `service_ip` varchar(60) NOT NULL COMMENT '服务端ip',
  `url` varchar(500) NOT NULL COMMENT '访问url',
  `req_method` varchar(60) DEFAULT NULL COMMENT '请求类型',
  `access_time` bigint(20) DEFAULT NULL COMMENT '请求时间',
  `service_id` varchar(60) DEFAULT NULL COMMENT '服务id',
  `parameter` varchar(500) DEFAULT NULL COMMENT '请求参数',
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `api_id` bigint(20) DEFAULT NULL COMMENT '资源ID',
  `request_result` varchar(200) DEFAULT NULL COMMENT '请求结果',
  `response_param` text COMMENT '响应出参'
  PRIMARY KEY (`id`),
  KEY `idx_user_id` (`user_id`) USING BTREE,
  KEY `idx_created_at` (`created_at`) USING BTREE,
  KEY `idx_service_id` (`service_id`) USING BTREE,
  KEY `idx_server_id` (`server_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='请求日志表';

2.1 调整主键

调整主键,该操作不会锁表,不会影响用户写入,但是会造成一定负载,建议业务低峰执行:

ALTER TABLE xxxx_log DROP PRIMARY KEY, ADD PRIMARY KEY (id, created_at), ALGORITHM=INPLACE, LOCK=NONE;

2.2 无锁变更

gh-ost 的使用方法参加之前的文档:

无锁变更工具使用说明:MySQL gh-ost DDL 变更工具

分区表执行的 DDL 语句如下:

ALTER TABLE xxxx_log
PARTITION BY RANGE(to_days(created_at)) (
    PARTITION p2024_01 VALUES LESS THAN (to_days('2024-02-01')),
    PARTITION p2024_02 VALUES LESS THAN (to_days('2024-03-01')),
    PARTITION p2024_03 VALUES LESS THAN (to_days('2024-04-01')),
    PARTITION p2024_04 VALUES LESS THAN (to_days('2024-05-01')),
    PARTITION p2024_05 VALUES LESS THAN (to_days('2024-06-01')),
    PARTITION p2024_06 VALUES LESS THAN (to_days('2024-07-01')),
    PARTITION p2024_07 VALUES LESS THAN (to_days('2024-08-01')),
    PARTITION p2024_08 VALUES LESS THAN (to_days('2024-09-01')),
    PARTITION p2024_09 VALUES LESS THAN (to_days('2024-10-01')),
    PARTITION p2024_10 VALUES LESS THAN (to_days('2024-11-01')),   
    PARTITION p2024_11 VALUES LESS THAN (to_days('2024-12-01')),     
    PARTITION p2024_12 VALUES LESS THAN (to_days('2025-01-01')) 
);

执行完后,该表就被改造为分区表。

2.3 回滚策略

调整主键,由于 id 本身就是唯一的,所以对业务来说没有影响,不需要回滚。

调整分区表,从刚才的原理介绍可以了解到,整个过程只会增加负载,在 copy 数据到影子表的过程中,切换后还可以选择保留原表,测试无误后删除,随时可以再 rname 回去。

3. 分区表维护

3.1 创建分区

需要提前创建好分区,否则插入数据会失败,调整分区表的语句,已经创建了 2024 年整年的分区,所以到 2025 年之前,需要提前创建好 2025 年的分区,这个业务负责人和 DBA 都需要注意,否则会造成故障,分区要提前创建。

-- 创建 2025 年的分区 SQL 语句。
ALTER TABLE xxxx_log ADD PARTITION (
  PARTITION p2025_01 VALUES LESS THAN (to_days('2025-02-01')),
  PARTITION p2025_02 VALUES LESS THAN (to_days('2025-03-01')),
  PARTITION p2025_03 VALUES LESS THAN (to_days('2025-04-01')),
  PARTITION p2025_04 VALUES LESS THAN (to_days('2025-05-01')),
  PARTITION p2025_05 VALUES LESS THAN (to_days('2025-06-01')),
  PARTITION p2025_06 VALUES LESS THAN (to_days('2025-07-01')),
  PARTITION p2025_07 VALUES LESS THAN (to_days('2025-08-01')),
  PARTITION p2025_08 VALUES LESS THAN (to_days('2025-09-01')),
  PARTITION p2025_09 VALUES LESS THAN (to_days('2025-10-01')),
  PARTITION p2025_10 VALUES LESS THAN (to_days('2025-11-01')),
  PARTITION p2025_11 VALUES LESS THAN (to_days('2025-12-01')),
  PARTITION p2025_12 VALUES LESS THAN (to_days('2026-01-01'))
);

3.2 删除分区

清理数据,了解业务只需要保留 3 个月的数据,那么可以直接 drop 分区清理数据,比如清理 2024 年第一季度的数据。

ALTER TABLE xxxx_log DROP PARTITION p2024_01, p2024_02, p2024_03;

3.3 分区表查询

分区表查询的方式和普通表没有差别,不过建议查询时带上分区字段,否则查询要扫描所有的分区,会比较慢。当然也可以直接选择在某个分区里面查询。

-- 在 p2024_04 查询最大和最小的 created_at
SELECT max(created_at), min(created_at) FROM xxxx_log PARTITION (p2024_04);

后记

这类日志表类型的表,需要定期清理和归档,且业务平时也不会查询,历史数据都是静态的,分区表的特性就比较友好。改造为分区表后可大幅提升可维护性。

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

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

相关文章

二维数组指针,指针数组,指针函数

指针 操作 二维字符型数组 1、 首先理解二维数组指针 int a[3][4]; 第一步,确定基类型:上面的数组从本质上讲,是一维数组的数组,写成int[4] a[3]可以更好的理解,a[3]是一个一维数组,其数组…

【机器学习sklearn实战】岭回归、Lasso回归和弹性网络

一 sklean中模型详解 1.1 Ride regression 1.2 Lasso regression 1.3 ElasticNet 二 算法实战 2.1 导入包 import numpy as np import pandas as pd from sklearn import datasets from sklearn.model_selection import train_test_split, GridSearchCV from sklearn.linear…

【开源分享】PHP在线客服系统网站源码 附搭建教程

在互联网时代,用户对于线上服务的便捷性和高效性要求越来越高。官网在线客服系统作为企业与用户之间实时沟通的工具,不仅能够提高用户满意度,还能够有效促进业务转化。然而,市面上的在线客服系统大多价格昂贵且功能单一&#xff0…

[论文翻译] LTAChecker:利用注意力时态网络基于 Dalvik 操作码序列的轻量级安卓恶意软件检测

LTAChecker: Lightweight Android Malware Detection Based on Dalvik Opcode Sequences using Attention Temporal Networks 摘要: Android 应用程序已成为黑客攻击的主要目标。安卓恶意软件检测是一项关键技术,对保障网络安全和阻止异常情况至关重要。…

1.redis7安装

安装: redis下载地址: Index of /releases/ 本次使用的版本为7.0.0. yum install gcc-c 下载上传到 /opt/redis 目录,tar -zxvf redis-7.0.0.tar.gz 解压缩 cd redis-7.0.0 执行make 执行make install. 默认会安装到 /usr/local/bi…

超融合一体机是什么意思?有什么好处

超融合一体机是什么意思?超融合一体机是一种集成了计算、存储和网络功能的一体化硬件设备。通过软件定义的方式,提供了高度集成、高可用性、高性能的数据中心解决方案。这种一体机将多个物理服务器、存储设备和网络设备整合在一个机箱内,通过…

轻空间成功完成陕西渭南砂石料场气膜仓项目

轻空间(江苏)膜结构科技有限公司凭借卓越的技术实力与丰富的项目经验,成功完成了陕西省渭南市砂石料场气膜仓的建设。这一项目的顺利交付,不仅满足了当地对高效仓储的需求,也为西北地区的仓储设施建设树立了标杆。 陕西…

twoPhaseEulerFoam 全解读之二(转)

twoPhaseEulerFoam 全解读之二(转) 本系列将对OpenFOAM-2.1.1 中的 twoPhaseEulerFoam 求解器进行完全解读,共分三部分:方程推导,代码解读,补充说明。本篇对 twoPhaseEulerFoam 中的 UEqn.H 和 pEqn.H 中的…

C# 高级数据处理:深入解析联接 Join 与 GroupJoin 操作的应用与实例演示

文章目录 一、联接概述二、Join 操作符1. Join 操作符的基本用法2. Join 操作符示例 三、GroupJoin 操作符1. GroupJoin 操作符的基本用法2. GroupJoin 操作符示例 总结 在数据处理中,联接(Join)操作是一种非常常见的需求,它允许我…

C语言典型例题30

《C程序设计教程(第四版)——谭浩强》 习题2.7 从银行贷了一笔款d,准备每月还款额为p,月利率为r,计算多少个月能还清。 设d30000元,p6000元,r1%。对求得的月份取小数点后一位,对第二…

【深度学习与NLP】——RNN架构解析

目录 RNN架构解析 1.1 认识RNN模型 学习目标 什么是RNN模型 RNN模型的作用 RNN模型的分类 小节总结 1.2 传统RNN模型 学习目标 传统RNN的内部结构图 小节总结 RNN架构解析 1.1 认识RNN模型 学习目标 了解什么是RNN模型.了解RNN模型的作用.了解RNN模型的分类. 什么…

如何使用Jmeter对HTTP接口进行压力测试?

我们不应该仅仅局限于某一种工具,性能测试能使用的工具非常多,选择适合的就是最好的。笔者已经使用Loadrunner进行多年的项目性能测试实战经验,也算略有小成,任何性能测试(如压力测试、负载测试、疲劳强度测试等&#…

openai gym box space configuration

题意:在OpenAI Gym环境中配置一个“Box”空间 问题背景: I need an observation space ranging from [0,inf) 我需要一个观察空间,其范围是从 [0, ∞)(0到正无穷大) Im new to openai gym, and not sure what the fo…

【算法】最短路径算法思路小结

一、基础:二叉树的遍历->图的遍历 提到搜索算法,就不得不说两个最基础的思想: BFS(Breadth First Search)广度优先搜索 DFS(Depth First Search)深度优先搜索 刚开始是在二叉树遍历中接触这…

为什么企业需要安装加密软件

保护敏感数据: 企业通常拥有大量的敏感数据,如客户信息、财务数据、知识产权等。这些数据如果未经保护而被泄露,可能会对企业造成严重的经济损失和声誉损害。加密软件能够对这些敏感数据进行加密,即使数据被窃取,也无…

AI 时代,网关更能打了?

作者:澄潭、望宸 网关在网络通信中扮演着诸多角色,包括数据转发、协议转化、负载均衡、访问控制和身份验证、安全防护、内容审核,以及服务和 API 颗粒度的管控等,因此常见的网关种类有流量网关、安全网关、微服务网关、API 网关等…

73.游戏分析工具的添加对象与删除对象

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 内容参考于:易道云信息技术研究院 上一个内容:72.树形列表绑定对应的右键菜单 以它的代码为基础进行修改 删除对象在 CwndRAN 文件中…

猎码安卓APP开发IDE,amix STUDIO中文java,HTML5开发工具

【无爱也能发电】Xili 2024/8/2 10:41:20 猎码安卓APP开发IDE,amix java开发工具 我研发这些只有一小部分理由是为了赚钱,更多是想成就牛逼的技术产品。 目前的产品就够我赚钱的,我持续更新就好了,没必要继续研究。 IDE不赚钱,谁…

【Redis进阶】缓存应用

目录 缓存击穿 概念 缓存击穿的原因 缓存击穿的影响 缓存击穿的应对措施 设置分布式锁 提前更新缓存 请求分级和降级 缓存穿透 概念 缓存穿透的原因 缓存穿透的应对措施 缓存空值 布隆过滤器 限流和黑名单 缓存雪崩 缓存雪崩概念 缓存雪崩的原因 应对措施 缓…