首页 > 数据库 >MySQL 大表丝滑变更 (online schema change)

MySQL 大表丝滑变更 (online schema change)

时间:2024-03-20 11:16:15浏览次数:30  
标签:table1 pt -- 大表丝 MySQL ADD online 变更

近接到业务需求,要对 1张6千万数据量 和 1张2千万数据量的,MySQL大表进行增加字段,增加索引变更,为不锁表影响业务,调研后决定使用 pt-online-schema-change 工具操作,现详细记录如下。

什么是大表

一张MySQL表的数据量如果在千万级或以上,则可以认定为大表。如果在百万级,但是字段数量非常多,也可以认为是大表。

什么是大表变更

主要指的是对大表,表结构的修改,常见的业务场景诸如,给表新增字段,新增索引等,参考SQL如下:

-- 增加字段
ALTER TABLE table1 ADD field1 varchar(64);

-- 增加索引 方式1
CREATE INDEX table1_index1 ON table1 (field1);

-- 增加索引 方式2
ALTER TABLE table1 ADD INDEX table1_index1 (field1);

-- 即增加字段、又增加索引,合并书写
ALTER TABLE table1
ADD field1 varchar(64),
ADD field2 varchar(64),
ADD field3 varchar(64),
ADD INDEX table1_index1 (field1),
ADD INDEX table1_index2 (field2),
ADD INDEX table1_index3 (field3);

注意最后一种合并写法,使用工具进行大表表更,都会要求传入变更的具体SQL,如果不合并而是分多次执行,则严重加大执行时间。
即便不使用工具直接执行SQL,也应该合并SQL一次性执行,以减少锁表时间。

大表变更存在什么问题

会锁表,整个SQL执行期间,该表无法读,也无法写,基本就是不可用的状态。至于具体锁表的时间,则跟数据量,字段数,执行变更语句的复杂性,都相关。

第三方工具1 pt-osc (pt-online-schema-change)

这个工具是 Percona 出品的,很早就有,成熟,之前在新浪工作,用的就是这个,也是本文的主角。

pt-osc 的工作原理如下:

  1. 创建新表:首先,pt-osc 会创建一个与原表结构相同的新空表。
  2. 修改表结构:在新表上执行所需的结构变更,如添加新列或索引。显然此时将非常快,新的空表即无数据,更无业务使用。
  3. 同步数据:通过在原表上创建触发器(DELETE、UPDATE、INSERT),将对原表的所有写操作(增删改)同步到新表中。同时,pt-osc 会以块的形式从原表中复制数据到新表。
  4. 交换表:数据复制完成后,pt-osc 会将原表重命名为一个临时名称(例如,_origin_old),然后将新表重命名为原表的名称(例如,_origin),从而完成表结构变更。
  5. 清理:最后,删除原表的触发器和临时表(如果需要)。

全过程为一个原子事物操作,执行过程若有问题,不会对原表进行任何修改。

概念解释 - 触发器

后面会用到这个概念,触发器比较复杂,也不建议业务使用,这里只简单解释一下。
MySQL 触发器(Trigger)是一种特殊的存储过程,它会在特定的数据库表上执行某些操作时自动触发。这些操作包括 INSERT、UPDATE、DELETE 等。触发器的主要目的是在数据变更之前或之后自动执行一些业务逻辑,以确保数据的完整性、执行复杂的业务规则或者进行数据的级联更新。
触发器可以是 BEFORE 触发器,它在指定的操作执行之前触发,或者 AFTER 触发器,它在操作执行之后触发。此外,还可以有 INSTEAD OF 触发器,它在执行操作时取代了原始的操作。
如何解决大表变更锁表的问题

pt-osc 安装

二进制安装

在官网 https://www.percona.com/downloads 下载最新二进制版本即可
https://downloads.percona.com/downloads/percona-toolkit/3.5.7/binary/tarball/percona-toolkit-3.5.7_x86_64.tar.gz
解压后,找到并执行 ./pt-online-schema-change --help 可查看帮助,该文件实际是一个perl脚本
直接使用二进制,可能会提示缺少某些依赖,按照提示安装即可,类似
yum install perl-DBI perl-DBD-MySQL -y

YUM 安装

参考 https://docs.percona.com/percona-toolkit/installation.html
pt-osc 使用
要执行的命令很长,尤其是里边还包含修改语句的SQL,建议放在脚本里,看仔细后,再执行,参考脚本如下

#!/bin/bash
binname=/usr/local/percona-toolkit-3.5.7/bin/pt-online-schema-change

action='--dry-run'
# action='--execute'

str="
$binname \
    --alter=\" 
        ADD field1 varchar(64),
        ADD field2 varchar(64),
        ADD field3 varchar(64),
        ADD INDEX table1_index1 (field1),
        ADD INDEX table1_index2 (field2),
        ADD INDEX table1_index3 (field3)
    \" \
    --print \
    --critical-load='Threads_running=200' \
    $action \
    D=mydb,t=mytable,P=3306,S='/var/lib/mysql/mysql3306.sock',u=root,p='test_pwd_xxx'
"

echo $str
# eval $str

脚本使用细节,解释如下:

  1. alter
    这里边是放入要修改的SQL,根据前边的讲述,对同一个表的多个修改,显然应该合并执行。注意,原始SQL里的 ALTER TABLE table1,是省略掉的,否则会报错
  2. echo and eval
    echo 显然是把拼凑的命令字符串给打出来,人工逐单词详细确认是否有问题
    eval 接命令字符串,就是直接执行命令了,这都是shell的使用技巧
  3. dry-run and --execute
    这两个参数只能选择一个,实际使用肯定是先确认拼凑的字符串没有问题,然后执行 --dry-run 模拟执行,不会实际修改原始表,会创建临时表,修改临时表,表结构,创建触发器等等一些内部原理都暴露出来
    --execute 当一切都准备完成,使用 --execute 实际修改生产表,建议放到 tmux 等后台执行,命令执行根据情况持续数分钟,数小时都是可能的
  4. critical-load
    这个参数是调整对server负载压力的,我在实际执行的时候,报过下面这个错误
    (in cleanup) 2024-03-08T11:04:21 Error copying rows from db1.table1 to db1.table1: Threads_running=53 exceeds its critical threshold 50
    这个报错就可以调整该参数,提高限制,来解决。更多细节见官方文档,这么一句话
    The tool pauses or aborts its operation if it detects too much load on the server. See --max-load and --critical-load for details.
  5. DSN (DATA SOURCE NAME)
    最后这一大坨
    D=mydb,t=mytable,P=3306,S='/var/lib/mysql/mysql3306.sock',u=root,p='test_pwd_xxx'
    是用来连接上具体的MySQL的,显然你需要指定主库的地址
    除了DSN这种连接MySQL的方式,官方还支持
    --user
    --password
    这种参数的形式,我的建议是 不要用 ,我混用过两种方式,有奇怪的报错,而且是
    --dry-run 不报连接错误, --execute 报连接错误
    按照官方文档的说明,使用--xxx这种参数形式连接MySQL,pt-osc工具内部会自动转换成DSN连接方式,既然如此,我们干脆只使用DSN方式

第三方工具2 gh-ost(GitHub Open Source Tool for Online Schema Table)

gh-ost 的工作原理简要介绍如下:

  1. 创建镜像表:在主库上创建一个与原表结构相同的镜像表(通常以原表名后缀 _gho 命名)。
  2. 心跳表:同时创建一个心跳表(通常以原表名后缀 _ghc 命名),用于记录 Online DDL 的进度和时间。
  3. 数据同步:gh-ost 伪装成从库连接到主库或从库,读取 binlog 日志,并将变更应用到主库上的镜像表。同时,它从原表中拷贝数据到镜像表。
  4. 增量数据应用:gh-ost 会根据 binlog 信息完成增量数据的变更,确保镜像表与原表的数据保持一致。
  5. 原子性切换:在数据同步完成后,gh-ost 会执行一个原子性的切换操作,将原表重命名为一个临时名称(例如 _tablename_del),然后将镜像表重命名为原表的名称,完成表结构变更。
  6. 清理:最后,gh-ost 会删除心跳表和临时表(如果需要)。

如果说 pt-osc 核心是利用触发器,gh-ost 核心则是利用 binlog

MySQL 自带的能力

MySQL 5.7 以后,尤其是 MySQL 8.x,自带一些能力可以不锁表进行大表变更

非技术手段

MySQL大表变更锁表是服务自带的问题,有时可能并一定要用技术手段解决,诸如:

  1. 说服、告知业务,变更将锁表,业务短暂不可用。
  2. 业务低峰,如凌晨、清晨,进行变更。
  3. 想办法减少数据量,再进行变更。
  4. 甚至于更彻底,让业务短暂,暂停使用数据库,再进行大表变更。

最后

MySQL 大表变更是一个高危、重大变更,本文仅仅作为入门指引。确要选用pt-osc执行大表变更,建议详细阅读官方文档后再操作。

标签:table1,pt,--,大表丝,MySQL,ADD,online,变更
From: https://www.cnblogs.com/jietang64/p/18084788

相关文章

  • PHP无法连接MySQL8.0数据库问题处理 报错如下: SQLSTATE[HY000]
    PHP无法连接MySQL8.0数据库问题处理报错如下:SQLSTATE[HY000][2054]Theserverrequestedauthenticationmethodunknowntotheclient发生这种错误,是由于MySQL8默认使用了新的密码验证插件:caching_sha2_password,而之前的PHP版本中所带的mysqlnd无法支持这种验证。解决这个问......
  • 在Linux中,MySQL数据库日常运维中涉及哪些关键任务?
    在Linux环境下,MySQL数据库的日常运维涉及到一系列关键任务,旨在保证数据库的稳定性、性能和数据完整性。以下是一些核心运维任务:性能监控与调优使用MySQL自身的SHOWSTATUS、SHOWVARIABLES、EXPLAIN等命令,或结合第三方工具(如PerconaToolkit、MySQLEnterpriseMonitor、Prom......
  • 040_Windows下MySQL定时备份
    目录定时备份脚本计划任务定时执行定时备份脚本remauther:zhyqremdate:20220929rem******BackupMySQLStart******@echooff::设置时间变量set"Ymd=%date:~0,4%%date:~5,2%%date:~8,2%"::创建存储的文件夹ifnotexist"C:\mysql_backup"md"C:\mysql_backup"......
  • MySQL8设置允许简单密码
    [https://blog.51cto.com/u_16175454/9981004#:~:text=MySQL8设置允许简单密码1登录MySQL数据库首先,使用root用户登录到MySQL数据库。mysql-u,5刷新权限在修改后,需要刷新权限使更改生效。...6验证设置最后,验证设置是否生效。](https://blog.51cto.com/u_16175454/99......
  • MySQL——数据库备份上传到阿里云OSS存储
    前言基于阿里云的OSS存储对数据库进行备份,阿里云ossutil安装文档还是比较详细的,直街参考阿里云文档操作就好了ossutil:https://help.aliyun.com/zh/oss/developer-reference/overview-59内容根据ossutil安装配置好命令行工具,然后直接写相应的脚本就好了,如果存在大表建议单独导......
  • MySQL 视图、事件、函数、储存过程
    正文视图https://blog.csdn.net/moxigandashu/article/details/63254901事件(类似定时任务)https://zhuanlan.zhihu.com/p/450454992函数https://www.cnblogs.com/zhangminghui/p/4113160.html储存过程(处理复杂逻辑)https://blog.csdn.net/whf_a/article/details/114871866......
  • 虚拟机部署centos系统部署docker和mysql的安装过程
    作者本人使用的是vmware17Pro虚拟机,大家可以去网上找相关教程下载安装,此总结后边有多次安装遇到的bug,要是有地方不妥,欢迎相互交流在刚开始时,我们先部署的是Linux虚拟机,在设置Linux系统基础环境时,系统就基本具有一些网络服务功能,差不多类似于现实中大型的服务器,还有设置网络这一块......
  • 基于SSM框架的商城的设计与实现(JSP+java+springmvc+mysql+MyBatis)
    本项目包含程序+源码+数据库+LW+调试部署环境,文末可获取一份本项目的java源码和数据库参考。项目文件图 项目介绍随着电子商务的迅猛发展,网上购物已成为人们日常生活的一部分。基于SSM(Spring+SpringMVC+MyBatis)框架的商城系统因其轻量化、高效和易于维护等特点,成为......
  • 在线选课系统(JSP+java+springmvc+mysql+MyBatis)
    本项目包含程序+源码+数据库+LW+调试部署环境,文末可获取一份本项目的java源码和数据库参考。项目文件图 项目介绍在线选课系统作为现代教育体系中重要的信息化工具,它允许学生通过互联网进行课程选择,提高了教育管理的灵活性和效率。随着教学模式的多样化和个性化学习需求......
  • 基于携程旅行平台自由行的旅游线路管理信息系统(JSP+java+springmvc+mysql+MyBatis)
    本项目包含程序+源码+数据库+LW+调试部署环境,文末可获取一份本项目的java源码和数据库参考。项目文件图项目介绍随着个性化旅游需求的增加,自由行成为越来越多旅行者的选择。基于携程旅行平台的自由行旅游线路管理信息系统,旨在为用户提供更加灵活、个性化的旅游规划服务。系......