原因: 最近公司上一个功能, 需要为其中某个表中新增字段,但是考虑到线上数据已经达到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在线修改大表结构的更多相关文章

  1. pt-online-schema-change工具使用教程(在线修改大表结构)

    percona-toolkit中pt-online-schema-change工具安装和使用 pt-online-schema-change介绍 使用场景:在线修改大表结构 在线数据库的维护中,总会涉 ...

  2. 在线修改大表结构pt-online-schema-change

    使用场景 在线数据库的维护中,总会涉及到研发修改表结构的情况,修改一些小表影响很小,而修改大表时,往往影响业务的正常运转,如表数据量超过500W,1000W,甚至过亿时 在线修改大表的可能影响 在线修 ...

  3. MySQL innodb引擎下根据.frm和.ibd文件恢复表结构和数据

    记录通过.frm和.ibd文件恢复数据到本地 .frm文件:保存了每个表的元数据,包括表结构的定义等: .ibd文件:InnoDB引擎开启了独立表空间(my.ini中配置innodb_file_per ...

  4. dbms_redefinition在线重定义表结构 可以在表分区的时候使用

    dbms_redefinition在线重定义表结构 (2013-08-29 22:52:58) 转载▼ 标签: dbms_redefinition 非分区表转换成分区表 王显伟 在线重定义表结构 在线 ...

  5. dbms_redefinition在线重定义表结构

    dbms_redefinition在线重定义表结构 (2013-08-29 22:52:58) 转载▼ 标签: dbms_redefinition 非分区表转换成分区表 王显伟 在线重定义表结构 在线 ...

  6. mysql数据库连接状态,不要做修改数据库表结构的操作;数据库迁移操作;

    在开发过程中,python的flask框架使用sqlalmysql连接mysql数据库. 在程序连接数据量过程中,不要修改数据表的结构.比如在连接状态中使用下面的软件修改数据表结构,这个软件立即就会卡 ...

  7. MySQL基础(二)(约束以及修改数据表)

    一,约束以及修改数据表 约束的作用?1.约束保证数据的完整性.一致性:2.约束分为表级约束.列级约束:3.约束类型包括:NOT NULL(非空约束).PRIMARY KEY(主键约束).UNIQUE ...

  8. Mysql学习(慕课学习笔记7)修改数据表(下)

    添加主键约束 ALTER TABLE tb1_name ADD [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,…….) ...

  9. MySQL数据操作与查询笔记 • 【第2章 表结构管理】

    全部章节   >>>> 本章目录 2.1 关系模型与数据表 2.1.1 关系模型 2.1.2 数据表 2.2 MySQL 数据类型 2.2.1 MySQL 常见数据类型 2.2 ...

  10. linux mysql修改数据表结构语法

    MySQL修改表的语法=========================增加列[add 列名]=========================①alter table 表名 add 列名 列类型 列 ...

随机推荐

  1. airflow 学习

    入门 Get started developing workflows with Apache Airflow Getting started with Apache Airflow  

  2. fluent python-chap2

    1. 内置序列类型 容器序列: list tuple collections.deque 可以存放不同类型的数据. 存放的是它们所包含的任意类型的对象的引用. 扁平序列: str bytes byte ...

  3. 中国信通院高质量数字化转型产品及服务全景图发布,合合信息多项AI产品入选

    随着5G.人工智能.大数据等新一代技术的发展,企业在商业竞争中正面临更多不确定性.中国信通院高度关注企业数字化转型中遇到的痛点,发起"铸基计划-高质量数字化转型行动",链接企业数字 ...

  4. RTPS代理与转发服务

    Proxy介绍 利用libevent实现网络连接和线程池.通过tcp连接的方式实现rtsp消息转发,再通过udp连接进行rtp与rtcp转发.报文解析使用到了Qt库.请尽量使用qmake进行编译.源码 ...

  5. CentOS开放端口的方法(转载)

    CentOS开放端口的方法 转载:https://www.itfeichai.com/centos-open-porter/ Centos升级到7之后,内置的防火墙已经从iptables变成了fire ...

  6. UEFI原理与编程(二)

    系统表 对UEFI应用程序和驱动程序开发人员来讲,系统表是最重要的数据结构之一,它是用户空间通往内核空间的通道.有了它,UEFI应用程序和驱动才可以访问UEFI内核.硬件资源和I/O设备. 1 在应用 ...

  7. iOS通知使用小结

    最近在项目开发中遇到了一个问题,首页底部菜单和底部子菜单的互动.需求是这样的,编辑状态下点击红色删除按钮,首页底部菜单移除该项,子菜单中对应项选中状态设置为未选中,典型的一对多方式.刚开始的方案是想通 ...

  8. 形参和实参的区别 and 联系

    联系:形参和实参是赋值关系,是按照值传递的,简单数据直接传递值,形参和实参的改变互不影响,因为形参和实参是两个变量,是两个数据(栈内存): 引用数据传递的是地址,结果就是一个数据,两个地址同时指向一个 ...

  9. Linux中ln 链接命令的用法

    ln的语法 Usage: ln [OPTION]... [-T] TARGET LINK_NAME (1st form) or: ln [OPTION]... TARGET (2nd form) or ...

  10. 如果读完这几百 Python 的书籍,能成编程大佬吗? #Python 入门 #编程 #编程学习 #知识分享