Mysql-经典实战案例(3): pt-archiver 实现 MySQL 千万级大表分库分表(上)
零基础实战:使用 pt-archiver 实现 MySQL 千万级大表的水平分表(Hash分片)
本文适合人群:MySQL新手、想低成本实践数据库分表的开发者
环境要求:MySQL 5.7+、Linux系统(建议CentOS/Ubuntu)
你将学会:
- 📦 1分钟生成百万测试数据
- 🔧 安全拆解大表为5个哈希分片表
- 🛠 零停机分表迁移实操技巧
一、为什么需要分表?
假设您有一张 订单表 orders 数据达到 1000万行,面临以下问题:
1️⃣ 查询变慢:SELECT * FROM orders WHERE user_id='xxx' 需要扫描全表
2️⃣ 维护困难:索引膨胀、备份耗时
3️⃣ 容灾风险:单表损坏可能导致业务瘫痪
解决方案:
👉 Hash分表:将数据按 user_id 的哈希值分散到 orders_0~orders_4 五个分片中,查询永远只需扫一张小表!
二、5分钟快速搭建测试环境
环境准备清单
-
安装 MySQL 5.7(已安装可跳过)
# Ubuntusudo apt install mysql-server-5.7# CentOSsudo yum install mysql-community-server -
安装 Percona Toolkit
# 所有Linux版本通用wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.debsudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.debsudo apt-get updatesudo apt-get install percona-toolkit -
创建测试数据库
CREATE DATABASE test_sharding;USE test_sharding; -
开启LOCAL INFILE参数
允许客户端从本地文件系统中读取数据文件,并将其内容加载到远程 MySQL 服务器的表中,使用pt-archiver分片导入的前提参数。
local_infile = on
三、1分钟生成百万测试数据
复制下列代码到 MySQL客户端,快速生成100万测试订单:
-- 创建原始订单表
CREATE TABLE orders (id INT AUTO_INCREMENT PRIMARY KEY,user_id VARCHAR(20) NOT NULL, -- 分片键(关键字段)amount DECIMAL(10,2) NOT NULL,create_time DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;-- 快速填充100万数据(耗时约30秒)
INSERT INTO orders (user_id, amount)
SELECT CONCAT('user_', FLOOR(RAND() * 1000000)),ROUND(RAND() * 100, 2)
FROM (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) a,(SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) b,(SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) c,(SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) d,(SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) e,(SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) f,(SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) g,(SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) h,(SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) i;
执行成功后验证:
SELECT COUNT(*) FROM orders;
四、哈希分表实战:拆解大表为5个分片
1. 创建分片表
-- 创建5个分片表(结构与原表一致)
CREATE TABLE orders_0 LIKE orders;
CREATE TABLE orders_1 LIKE orders;
CREATE TABLE orders_2 LIKE orders;
CREATE TABLE orders_3 LIKE orders;
CREATE TABLE orders_4 LIKE orders;
2. 关键分片逻辑
通过 哈希函数 CRC32 将数据均匀分散到分片中:
CRC32(user_id) % 5 = 0 → 存入 orders_0
CRC32(user_id) % 5 = 1 → 存入 orders_1
... 以此类推
3. 使用 pt-archiver 迁移数据
将原表数据按 Hash 规则迁移到分片表(不锁表、不影响线上业务):
迁移到 orders_0 分片
/opt/percona-toolkit-3.6.0/bin/pt-archiver --source h=127.0.0.1,P=3306,u=root,p=密码,D=test_sharding,t=orders --dest h=127.0.0.1,P=3306,u=root,p=密码,D=test_sharding,t=orders_0 --where "CRC32(user_id) %5=0" --limit 500 --commit-each --bulk-insert --no-delete --no-check-charset
迁移其他分片
修改 --where 条件和目标表名,依次执行:
# orders_1(余数1)
pt-archiver ... --where "CRC32(user_id) %5=1" --dest t=orders_1# orders_2(余数2)
pt-archiver ... --where "CRC32(user_id) %5=2" --dest t=orders_2
...(省略orders_3/4)
五、分片结果验证
1. 核对各分片数据量
SELECT table_name AS '分片表',FORMAT(table_rows,0) AS '数据量'
FROM information_schema.tables
WHERE table_schema = 'test_sharding' AND table_name LIKE 'orders_%';
期望结果(误差应小于2%):
+-----------+-----------+
| 分片表 | 数据量 |
+-----------+-----------+
| orders_0 | 390,780 |
| orders_1 | 390,112 |
| orders_2 | 389,778 |
| orders_3 | 388,776 |
| orders_4 | 389,778 |
+-----------+-----------+
2. 数据完整性检验
-- 所有分片总和 = 原表总数
SELECT (SELECT COUNT(*) FROM orders_0) + (SELECT COUNT(*) FROM orders_1) +(SELECT COUNT(*) FROM orders_2) +(SELECT COUNT(*) FROM orders_3) +(SELECT COUNT(*) FROM orders_4) AS total_count;-- 应与原表数据量一致
SELECT COUNT(*) FROM orders;
注意!pt-archiverBug不会迁移max(id)那条数据,需要手动完成最后一行数据的迁移
定位数据差异
SELECT *
FROM orders
WHERE NOT EXISTS (SELECT 1 FROM orders_0 WHERE orders_0.id = orders.id UNION ALLSELECT 1 FROM orders_1 WHERE orders_1.id = orders.id UNION ALLSELECT 1 FROM orders_2 WHERE orders_2.id = orders.id UNION ALLSELECT 1 FROM orders_3 WHERE orders_3.id = orders.id UNION ALLSELECT 1 FROM orders_4 WHERE orders_4.id = orders.id
)
LIMIT 1;+---------+-----------+--------+---------------------+
| id | user_id | amount | create_time |
+---------+-----------+--------+---------------------+
| 1953125 | user_9823 | 39.33 | 2025-03-14 17:03:24 |
+---------+-----------+--------+---------------------+
使用insert 插入最后一条数据到orders_4表
INSERT INTO orders_4 (id, user_id, amount, create_time)
SELECT id, user_id, amount, create_time
FROM orders
WHERE id=1953125;
六、常见问题排雷指南
1. 迁移性能慢(每秒不到1000条)
-
✅ 优化技巧:
-- 增加批量大小(视内存调整) --limit 1000 \ --bulk-insert \
2. 主键冲突错误
-
✅ 解决方案:
- 迁移前清空分片表:
TRUNCATE orders_0 - 或使用
--replace参数覆盖已有数据
- 迁移前清空分片表:
3. 数据分布不均匀
-
✅ 原因排查:
- 检查分片键是否有倾斜(如某user_id占比过高)
- 改用 一致性哈希算法(如
SHA1(user_id))
七、分表后如何查询数据?
通过业务代码计算目标分片,直连对应表:
# Python示例:按user_id定位分片
user_id = "user_12345"
shard_no = crc32(user_id.encode()) % 5 # 计算分片编号
table_name = f"orders_{shard_no}"
query = f"SELECT * FROM {table_name} WHERE user_id = %s"
总结
通过本方案,我们实现了:
- 🚀 100万数据安全拆分:无锁迁移、分钟级完成
- 📊 分布式查询提速:查询性能提升5~10倍
- 🔒 数据零丢失保证:每一步操作均可回滚验证
下一篇预告:
1、如何完成垂直分表?将单表中高频访问的"热数据"与低频使用的"冷数据"分离存储!
2、如何可以将分片逻辑封装到中间件(如 MyCAT),彻底告别单表性能瓶颈!
相关文章:
Mysql-经典实战案例(3): pt-archiver 实现 MySQL 千万级大表分库分表(上)
零基础实战:使用 pt-archiver 实现 MySQL 千万级大表的水平分表(Hash分片) 本文适合人群:MySQL新手、想低成本实践数据库分表的开发者 环境要求:MySQL 5.7、Linux系统(建议CentOS/Ubuntu) 你将学…...
使用JSON存储数据的场景
Json 作为一种通用的数据格式,由于其结构灵活、可拓展等特点,在某些场景下我们也会直接将数据以 Json 格式存储到数据库中。 本文将探讨在开发中使用 JSON 存储数据的常见场景,并通过具体的实例帮助大家更好地理解其应用。 1. 半结构化数据…...
文生图网站推荐(2025.3)
以下是2024-2025年期间值得推荐的文生图网站,综合了免费性、中文友好度、操作便捷性及功能特色,涵盖不同用户需求: 一、国内主流平台 通义万相(阿里云) 特点:每日免费50次生成,模型和风格多样&a…...
网页制作代码html制作一个网页模板
制作一个简单而实用的网页模板:HTML基础入门 在数字时代,网页已成为信息展示和交流的重要平台。HTML(HyperText Markup Language)作为网页制作的基础语言,为开发者提供了构建网页的基本框架。本文将带你了解如何使用H…...
AI视觉测试工具实战评测:以Applitools为例的技术解析与行业应用
在数字化转型的浪潮中,软件界面(UI/UX)的复杂性与迭代速度呈指数级增长。传统的人工视觉测试不仅耗时费力,且难以应对多平台、多分辨率下的界面一致性问题。AI视觉测试工具的出现,通过智能图像识别与自动化对比&#x…...
SSM框架——Spring面试题
Spring常见面试题 Spring框架中的单例bean是线程安全的吗 不是线程安全的 Spring框架中有一个Scope注解,默认的值就是singleton,单例的。 因为一般在spring的bean的中都是注入无状态的对象,没有线程安全问题,如果在bean中定义了可…...
华为OD机试 - 计算观看演唱会场次(Java 2023 B卷 200分)
题目描述 为了庆祝中国共产党成立100周年,某公园将举行多场文艺表演。由于演出分布在不同的场地,一个人只能同时观看一场演出,且不能迟到早退。连续观看的演出之间最少需要有15分钟的时间间隔。小明是一个狂热的文艺迷,想观看尽可…...
云原生大佬重生,记忆逐步复苏(十三:selinux模块)
目录 1:什么是selinux 1.1 SELinux 的作用 1.2. SELinux 的工作原理 1.3. SELinux 的运行模式 2:解析selinux文件上下文标签策略 3:selinux的布尔值 4:调查和解决selinux问题 1:什么是selinux SELinux(Security-Enhanced L…...
Redis hyperloglog学习
背景知识 【伯努利试验】: 【伯努利试验】是一个概率论中的概念,指在相同的条件下重复进行n次独立的试验,每次试验只有两种可能的结果,且这两种结果发生的概率是固定的 抛硬币作为伯努利试验:在抛硬币时,我…...
MySQL高频八股——事务过程中Undo log、Redo log、Binlog的写入顺序(涉及两阶段提交)
大家好,我是钢板兽! 在上一篇文章中,我分别介绍了 Undo Log、Redo Log 和 Binlog 在事务执行过程中的作用与写入机制。然而,实际应用中,这三种日志的写入是有先后顺序的。因此,本篇文章将深入探讨它们的写…...
二阶近似 是什么意思
二阶近似 是什么意思 一、二阶近似的概念与举例 二阶近似是数学分析中通过泰勒展开对函数进行近似的方法,保留到二阶项(即包含一阶导数和二阶导数)。在优化问题(如模型训练)中,常用于近似损失函数,帮助更精准地更新模型参数。 举例: 假设损失函数为 L ( θ ) \mathc…...
Oracle GoldenGate 全面解析
Oracle GoldenGate 全面解析 Oracle GoldenGate 是一种实时数据集成和复制解决方案,广泛应用于数据同步、数据库迁移、高可用性和灾难恢复等场景。以下将详细解答您提出的关于 Oracle GoldenGate 的一系列问题。 1. Oracle GoldenGate 的架构组成及其核心组件的作用 架构组成…...
C++进阶——AVL树的实现
1、AVL的概念 1.1 AVL 树的发明 AVL 树由 G.M. Adelson-Velsky 和 E.M. Landis 在 1962 年的论文《An algorithm for the organization of information》中提出。他们的设计目标是解决二叉搜索树在动态操作(插入、删除)中可能退化为链表的问题。 1.2 …...
S32K144入门笔记(十三):LPIT的API函数解读
目录 1. SDK中的函数 2. API函数的释义 2.1 获取默认参数 2.2 初始化 2.3 启动与停止 2.4 计数值的设置于读取 2.5 中断API 1. SDK中的函数 在使用SDK的非抽象驱动函数时,函数的定义与声明在文件lpit_driver.c和lpit_driver.h中,一共有19个函数&a…...
打包当前Ubuntu镜像 制作Ubuntu togo系统
我的系统的基本情况说明: 我原来的系统的具体型号如下: uname -rLinux Engine 5.15.0-134-generic #145~20.04.1-Ubuntu SMP Mon Feb 17 13:27:16 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux我原来的硬盘以及分区策略如下: 可以看到我的分区…...
系统架构设计师—案例分析—架构设计
文章目录 经典架构风格对比面向对象架构风格/显示调用风格优点缺点举例 事件驱动的系统/隐式调用风格优点缺点举例 基于规则的系统架构风格优点缺点举例 管道过滤器风格优点缺点举例 仓库风格优点缺点举例 解释器风格优点缺点举例 分层架构风格优点缺点举例 经典架构风格对比 …...
基于javaweb的SpringBoot智能相册管理系统图片相册系统设计与实现(源码+文档+部署讲解)
技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论…...
Android 14 Telephony 网络选择功能介绍
一、总体介绍 (一)功能 手动搜网的流程:用户通过UI触发,调用TelephonyManager的API,比如startNetworkScan,然后这个请求会传递到RIL层,通过AT命令与基带通信,进行网络扫描。结果返回后,经过TelephonyRegistry通知应用层。中间可能涉及IPC,比如Binder通信,因为应用和…...
Leetcode 刷题笔记1 单调栈part01
leetcode 739 每日温度 对于单调栈问题,我觉得是在循环外部增加一些辅助项减少时间复杂度,但增加内存空间的利用 class Solution:def dailyTemperatures(self, temperatures: List[int]) -> List[int]:ans [0] * len(temperatures)stack []for i …...
深入解析音频编解码器(Audio CODEC):硬件、接口与驱动开发
音频编解码器(Audio CODEC)是音频处理系统中的核心组件,负责 模拟信号与数字信号的相互转换,广泛应用于 智能音箱、嵌入式系统、消费电子产品 等设备。本篇文章将从 硬件结构、接口解析、驱动开发 和 软件配置 等方面,…...
深度学习【迭代梯度下降法求解线性回归】
梯度下降法 梯度下降法是一种常用迭代方法,其目的是让输入向量找到一个合适的迭代方向,使得输出值能达到局部最小值。在拟合线性回归方程时,我们把损失函数视为以参数向量为输入的函数,找到其梯度下降的方向并进行迭代࿰…...
[Lc14_priority_queue] 最后一块石头重量 | 数据流中的第 K 大元素 | 前K个高频单词 | 数据流的中位数
目录 1.最后一块石头的重量 题解 2.数据流中的第 K 大元素 题解 3.前K个高频单词 题解 代码 ⭕4.数据流的中位数 题解 在C中,使用标准库中的priority_queue,默认情况下它是一个最大堆(即大堆排序),这意味着最…...
熔断和降级的区别,具体使用场景有哪些?
熔断与降级的核心区别在于触发条件和应用目标,具体差异及使用场景如下: 一、核心区别 对比维度熔断降级触发原因下游依赖服务故障(如超时、异常率过高)触发系统整体负载过高或流量洪峰管理目标层级框架级保护(无业务优…...
利用hexo+github部署属于自己的个人博客网站(2025年3月所写)
利用hexogithub部署属于自己的个人博客网站 前情提要:如果你出现了莫名其妙的报错,可能与权限有关,可以以管理员的身份运行git bash或者cmd 本篇博客仅限于利用hexo搭建博客,并且部署到github上面,让自己可以有一个访…...
首页性能优化
首页性能提升是前端优化中的核心任务之一,因为首页是用户访问的第一入口,其加载速度和交互体验直接影响用户的留存率和转化率。 1. 性能瓶颈分析 在优化之前,首先需要通过工具分析首页的性能瓶颈。常用的工具包括: Chrome DevTo…...
使用usb-cam包时填充摄像头参数话题
问题描述: 在启动usb摄像头之后,像apriltag_ros等包需要读取摄像头的内参信息,但是usb-cam默认是没有内参信息发布的,需要自己填写或标定。 解决方案: 如果你有内参数据或者急于验证后续代码的逻辑正确性,…...
pandas学习笔记(一)——基础知识和应用案例
pandas学习笔记 基础语法参考菜鸟教程:https://www.runoob.com/pandas/pandas-tutorial.html # jupyter import pandas as pd import matplotlib from matplotlib import pyplot as plt import numpy as npmatplotlib.use(TkAgg)data {timestamp: [1, 2, 3, 4, 5…...
SpringBoot + Mybatis Plus 整合 Redis
Redis 在用户管理系统中的典型应用场景 结合你的用户增删改查接口,以下是 Redis 的实用场景和具体实现方案: 场景作用实现方案用户信息缓存减少数据库压力,加速查询响应使用 Spring Cache Redis 注解缓存登录 Token 存储分布式 Session 或…...
【AI 大模型】RAG 检索增强生成 ⑤ ( 向量数据库 | 向量数据库 索引结构和搜索算法 | 常见 向量数据库 对比 | 安装并使用 向量数据库 chromadb 案例 )
文章目录 一、向量数据库1、向量数据库引入2、向量数据库简介3、向量数据库 索引结构和搜索算法4、向量数据库 应用场景5、传统数据库 与 向量数据库 对比 二、常见 向量数据库 对比三、向量数据库 案例1、安装 向量数据库 chromadb2、核心要点 解析① 创建数据库实例② 创建数…...
解决single cell portal点击下载但跳转的是网页
Single cell RNA-seq of Tmem100-lineage cells in a mouse model of osseointegration - Single Cell Portal 想下载个小鼠数据集: 点击下载跳转为网页: 复制bulk download给的链接无法下载 bulk download给的原链接: curl.exe "http…...
