MySQL之使用pt-online-schema-change在线修改大表结构
原因: 最近公司上一个功能, 需要为其中某个表中新增字段,但是考虑到线上数据已经达到300w+的级别,同时使用的mysql的版本是5.7而非8.0,这会导致新增字段的时候,对全表进行加锁,直到添加完毕这个过程中可能会消耗至少几十秒钟的时间,极大的影响线上业务
解决方案:
1.升级MySQL版本到8.0版本,支持行级锁
2.使用pt-online-schema-change工具
这里使用pt-online-schema-change, 由于MySQL的升级会导致不稳定的情况
大表执行DDL可能导致的问题:
在线修改大表的表结构执行时间往往不可预估,一般时间较长
由于修改表结构是表级锁,因此在修改表结构时,影响表写入操作
如果长时间的修改表结构,中途修改失败,由于修改表结构是一个事务,因此失败后会还原表结构,在这个过程中表都是锁着不可写入
修改大表结构容易导致数据库CPU、IO等性能消耗,使MySQL服务器性能降低
在线修改大表结构容易导致主从延时,从而影响业务读取
[介绍]
pt-online-schema-change是percona公司开发的一个工具,在percona-toolkit包里面可以找到这个功能,它可以在线修改表结构
原理
1.创建一个和要执行 alter 操作的表一样的新的空表结构(是alter之前的结构)
2.在新表执行alter table 语句(速度应该很快)
3.在原表中创建触发器3个触发器分别对应insert,update,delete操作
4.以一定块大小从原表拷贝数据到临时表,拷贝过程中通过原表上的触发器在原表进行的写操作都会更新到新建的临时表
5.Rename 原表到old表中,在把临时表Rename为原表
6.如果有参考该表的外键,根据alter-foreign-keys-method参数的值,检测外键相关的表,做相应设置的处理
7. 默认最后将旧原表删除
如果执行失败了,或手动停止了,需要手动删除下划线开头的表(_表名)及三个触发器
[安装]
ubuntu)
1.下载percona存储库文件
sudo apt update
sudo apt -y install gnupg2 wget
wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb
2.安装percona存储库包
sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb
输出如下:
Selecting previously unselected package percona-release.
(Reading database ... 194365 files and directories currently installed.)
Preparing to unpack percona-release_latest.focal_all.deb ...
Unpacking percona-release (1.0-17.generic) ...
Setting up percona-release (1.0-17.generic) ...
* Enabling the Percona Original repository
<*> All done!
==> Please run "apt-get update" to apply changes
The percona-release package now contains a percona-release script that can enable additional repositories for our newer products.
For example, to enable the Percona Server 8.0 repository use:
percona-release setup ps80
Note: To avoid conflicts with older product versions, the percona-release setup command Jan disable our original repository for some products.
For more information, please visit:
https://www.percona.com/doc/percona-repo-config/percona-release.html
3.安装Percona Toolkit
sudo apt update
sudo apt install percona-toolkit
同意软件安装:
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
geoip-database gsfonts libapt-pkg5.90 libbind9-161 libcroco3
libdns-export1107 libdns1107 libdns1109 libgeoip1 libicu65 libirs161
libisc-export1104 libisc1104 libisc1105 libisccc161 libisccfg163 liblwres161
libmozjs-60-0 liboauth0 libpoppler95 linux-modules-extra-5.4.0-14-generic
ubuntu-system-service
Use 'sudo apt autoremove' to remove them.
The following additional packages will be installed:
libdbd-mysql-perl libdbi-perl libterm-readkey-perl
Suggested packages:
libclone-perl libmldbm-perl libnet-daemon-perl libsql-statement-perl
The following NEW packages will be installed:
libdbd-mysql-perl libdbi-perl libterm-readkey-perl percona-toolkit
0 upgraded, 4 newly installed, 0 to remove and 0 not upgraded.
Need to get 1,732 kB of archives.
After this operation, 10.3 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
[使用]
1.查看MySQL性能摘要
pt-mysql-summary --host localhost --user root --ask-pass
2.修改表结构
pt-online-schema-change --alter "add column t8 int(11) not null default 0" D=test,t=log,h=192.168.16.48,P=3306,u=root,p=123456 --print --execute --charset=utf8
注意:
--charset=utf8,有的时候修改后的表注释出现乱码,或者如下报错,就必须要加上这个参数
参数 说明
–user/u 连接mysql的用户名
–password/p 连接mysql的密码
–host/h 连接mysql的地址
P=3306 连接mysql的端口号
D= 连接mysql的库名
t= 连接mysql的表名
–alter 修改表结构的语句
–execute 执行修改表结构
–charset=uft8 使用utf8编码,避免中文乱码
–no-version-check 不检查版本,在阿里云服务器中一般加入此参数,否则会报错
--user: -u,连接的用户名
--password: -p,连接的密码
--database: -D,连接的数据库
--port -P,连接数据库的端口
--host: -h,连接的主机地址
--socket: -S,连接mysql套接字文件
--statistics 打印出内部事件的数目,可以看到复制数据插入的数目。
--dry-run 创建和修改新表,但不会创建触发器、复制数据、和替换原表。并不真正执行,可以看到生成的执行语句,了解其执行步骤与细节。--dry-run与--execute必须指定一个,二者相互排斥。和--print配合最佳。
--execute 确定修改表,则指定该参数。真正执行。--dry-run与--execute必须指定一个,二者相互排斥。
--print 打印SQL语句到标准输出。指定此选项可以让你看到该工具所执行的语句,和--dry-run配合最佳。 --progress 复制数据的时候打印进度报告,二部分组成:第一部分是百分比,第二部分是时间。
--quiet -q,不把信息标准输出。
性能分析:
4.1 使用存储过程
首先使用存储过程做测试,为防止锁表,每次只更新200行。整个变更从开始到完成,需要耗费90分钟。其实,存储过程在执行过程中,如果恰好用户也在DDL操作存储过程正在变更的数据行,还有可能会锁住用户的数据,导致用户不能变更成功。
4.2 使用pt-osc工具
pt-osc从开始执行到变更完成,耗时7分钟左右,速度非常快。在执行的过程中,测试环境的服务连接到该数据库,并执行多个会操作该表的任务,整个过程中,任务能够正常执行,未出现异常情况。
- 500万的数据,新增一个int字段,花费大概30s时间
参考:
https://www.cnblogs.com/keme/p/10237590.html#auto_id_0
https://juejin.cn/post/6918908595778093070
MySQL之使用pt-online-schema-change在线修改大表结构的更多相关文章
- pt-online-schema-change工具使用教程(在线修改大表结构)
percona-toolkit中pt-online-schema-change工具安装和使用 pt-online-schema-change介绍 使用场景:在线修改大表结构 在线数据库的维护中,总会涉 ...
- 在线修改大表结构pt-online-schema-change
使用场景 在线数据库的维护中,总会涉及到研发修改表结构的情况,修改一些小表影响很小,而修改大表时,往往影响业务的正常运转,如表数据量超过500W,1000W,甚至过亿时 在线修改大表的可能影响 在线修 ...
- MySQL innodb引擎下根据.frm和.ibd文件恢复表结构和数据
记录通过.frm和.ibd文件恢复数据到本地 .frm文件:保存了每个表的元数据,包括表结构的定义等: .ibd文件:InnoDB引擎开启了独立表空间(my.ini中配置innodb_file_per ...
- dbms_redefinition在线重定义表结构 可以在表分区的时候使用
dbms_redefinition在线重定义表结构 (2013-08-29 22:52:58) 转载▼ 标签: dbms_redefinition 非分区表转换成分区表 王显伟 在线重定义表结构 在线 ...
- dbms_redefinition在线重定义表结构
dbms_redefinition在线重定义表结构 (2013-08-29 22:52:58) 转载▼ 标签: dbms_redefinition 非分区表转换成分区表 王显伟 在线重定义表结构 在线 ...
- mysql数据库连接状态,不要做修改数据库表结构的操作;数据库迁移操作;
在开发过程中,python的flask框架使用sqlalmysql连接mysql数据库. 在程序连接数据量过程中,不要修改数据表的结构.比如在连接状态中使用下面的软件修改数据表结构,这个软件立即就会卡 ...
- MySQL基础(二)(约束以及修改数据表)
一,约束以及修改数据表 约束的作用?1.约束保证数据的完整性.一致性:2.约束分为表级约束.列级约束:3.约束类型包括:NOT NULL(非空约束).PRIMARY KEY(主键约束).UNIQUE ...
- Mysql学习(慕课学习笔记7)修改数据表(下)
添加主键约束 ALTER TABLE tb1_name ADD [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,…….) ...
- MySQL数据操作与查询笔记 • 【第2章 表结构管理】
全部章节 >>>> 本章目录 2.1 关系模型与数据表 2.1.1 关系模型 2.1.2 数据表 2.2 MySQL 数据类型 2.2.1 MySQL 常见数据类型 2.2 ...
- linux mysql修改数据表结构语法
MySQL修改表的语法=========================增加列[add 列名]=========================①alter table 表名 add 列名 列类型 列 ...
随机推荐
- 线性dp:LeetCode516 .最长回文子序列
LeetCode516 .最长回文子序列 题目叙述: 力扣题目链接(opens new window) 给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度. 子序列定义为:不改变剩余字 ...
- tarjan—算法的神(一)
本篇包含 tarjan 求强连通分量.边双连通分量.割点 部分, tarjan 求点双连通分量.桥(割边)在下一篇. 伟大的 Robert Tarjan 创造了众多被人们所熟知的算法及数据结构,最著名 ...
- Go 编程-mysql数据库操作
一.环境准备 在Go语言中连接MySQL数据库通常使用database/sql包配合一个MySQL驱动,比如github.com/go-sql-driver/mysql 安装github.com/go ...
- Angular 学习笔记 (Typescript 高级篇)
由于 typescript 越来越复杂. 所以特意开多一个篇幅来记入一些比较难的, 和一些到了一定程度需要知道的基础. 主要参考 https://basarat.gitbook.io/typescri ...
- 揭秘JWT:从CTF实战到Web开发,使用JWT令牌验证
揭秘JWT:从CTF实战到Web开发,使用JWT令牌验证 介绍 JWT(JSON Web Tokens)是一种开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在网络上安全地传输信息. ...
- MyBatisPlus——DQL编程控制——条件查询
DQL编程控制 条件查询--设置查询条件 格式一:常规格式 //方式一:按条件查询 QueryWrapper qw = new QueryWrapper(); // 10岁到30岁之间的用户 qw.g ...
- [OI] 模拟退火
模拟退火是一种适合求样本点较大的多峰函数极值的方法. 模拟退火有几个参数:初始温度(\(T_{0}\)),终止温度(\(T_{e}\))和降温参数 \(d\),具体地,模拟退火是让每次的当前温度 \( ...
- 【赵渝强老师】MongoDB的inMemory存储引擎
一.MongoDB的存储引擎概述 存储引擎(Storage Engine)是MongoDB的核心组件,负责管理数据如何存储在硬盘(Disk)和内存(Memory)上.从MongoDB 3.2 版本开始 ...
- debian 12 编译 vlc/libvlc 支持 rtsp
debian 官方从11开始,不再提供支持 rtsp 的 VLC deb 包,通过 libvlc 播放 rtsp 也无法实现,因此需要自己编译. # 安装编译环境,编译依赖库以及 contrib 第三 ...
- Android应用启动流程一次看透
1.1.冷启动和热启动 冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,然后再根据启动的参数,启动对应的进程组件,这个启动方式就是冷启动. 热启动:当启动应用时 ...