如何避免 MySQL 修改表结构时导致表无法使用的问题

作者&投稿:夏颜 (若有异议请与网页底部的电邮联系)
如何避免 MySQL 修改表结构时导致表无法使用的问题~

这个无法避免,修改表结构的时候,整个表都会独占锁定,修改完毕其它人才可以使用表。

修改表结构的时候,整个表都会独占锁定,修改完毕其它人才可以使用表

  来源:oschina.net  作者:whats_java 

  MySQL 在修改表结构的时候可能会中断产品的正常运行影响用户体验,甚至更坏的结果,丢失数据。不是所有的数据库管理员、程序员、系统管理员都非常了解MySQL能避免这种情况。DBA会经常碰到这种生产中断的情况,当升级脚本修改了应用层和数据库层,或者缺乏经验的管理员、开发在不是很了解Mysql内部工作机制的情况下修改了规范文件。


  真相是:


  直接修改表结构的过程中会锁表(在5.6版本之前)


  在线的数据定义语言在5.6版本不总是在线的而且也会锁表


  就算使用Percona工具包(在线修改定义文件)也会有若干个步骤会锁表


  Percona MySQL  服务器开发团队鼓励用户在计划或者执行数据库迁移的时候先和我们沟通。我们的目标是基于用户给出的各种情况给出最佳的方案。旨在避免锁表当用户对非常大的表执行DDL,以确保应用能像平常一样正常运行,同时也在努力改善响应时间或增加系统功能。最差的情况是确保那些经不起当机的系统在黄金交易时间正常运行。


  我们使用的大多数安装包仍然小于MySQL5.6,这需要我们不停尝试新的安装环境来把数据库迁移造成的损失降到最低。这可能需要一个能“在线修改规范定义文件”的工具来升级或者修改规范文件。MySQL5.6解决这一问题的做法是通过减少重建表和锁表的场景,但这个方法不能覆盖所有的可能的操作,例如当修改一列的数据类型时必然需要全表重构。Przemysław和 Malkowski在去年尽可能详尽的讨论了Mysql5.6运行中修改定义。


  随着 MySQL 5.7的新功能, 我们寻求不会锁表的DDL操作 例如; 表优化 和 索引重命名. (More info)


  对于Mysql5.6的用户,最好的建议是回顾一下数矩阵来熟悉在MYSQL之外执行定义的更改,好消息是我们很擅长解决这一问题。


  说实话,锁表操作会经常被忽视,在操作30M大小的表时我们更倾向于直接修改,但是30G,300G的表就要考虑一下了。当使用率不高或者对锁定时间要求不是很高的的系统来说直接操作也许更好。可是,我们常常会遇到一个需要立即执行的SQL,或者因为性能问题需要紧急增加一个索引来减少加载时间。


  是否需要在系统在线期修改表定义


  上面提到,在线修改表定义是工作流中的一个模块。通常是不错的解决方案,但也会遇到不能使用的场合,例如:当某个表使用了触发器。了解pt-osc在我们项目中的工作过程很重要,让我们来看一下源代码:


  [moore@localhost]$ egrep 'Step' pt-online-schema-change

  # 步骤 1: 创建一个新表


  # 步骤 2: 修改清空表. 这应该比较快,

  # Step 3: 创建触发器来捕获原始表的改变 <--(锁定元数据)


  # Step 4: 复制数据.

  # Step 5: 重命名表: <--(锁定元数据


  # Step 6: 更新外键 如果是子表.


  # Step 7: 删除旧表.


  我把上面第三步到第五步高亮出来,这是锁表可能引起系统停机的时间。但步骤六设计外键更新是一个循环的操作,是避免在更新关系的时候隐含地重建表。有很多方法可以确保表的完整性约束,在pt-osc的说明文档中详细说明了,在开始之前预览你的表结构包括约束,并知道怎样把修改表定义所造成的影响降到最低。


  最近,我们通知了一个拥有高并发高事务量系统的用户运行pt-osc在大型数据表上。这件事对于他们来说很平常,几小时后我们的客服被告知该客户遇到了最大连接数超过的问题。这个问题是如何产生的呢?当pt-osc运行到步骤五的时候会尝试去锁定数据并重命名原表和隐藏表,然而这不会在开启事务的时候立即执行,因此这条线程会被排在重命名后面。这表现在用户应用上就是系统停机。数据库无法开启新的连接并且所有的线程都被阻塞在重命名命令之后。


  数据被锁


  5.5.3版本的说明,当开启一个事务时会锁定它会用到的所有表的数据(不依赖于存储引擎),并在事务提交的时候释放锁。这样做确保了在开启事务期间不能修改表的定义。


  长远来看我们可以采用一些新的技术来避免这种情况,例如non-default pt-osc的选项,换言之就是不会删除原表把数据换到新表。这种联合脱离了隐藏表和触发器,我们应该鼓励将重命名操作变得原子化。


  校订:2.2版本的percona工具新增了一个变量–tries  和变量–set-vars 共同被部署,解决了各种pt-osc操作可能会锁表的情况。pt-osc (–set-vars)默认会设置如下的会话变量当连接到数据库服务器的时候。


  wait_timeout=10000

  innodb_lock_wait_timeout=1

  lock_wait_timeout=60


  当使用 –tries 我们可以颗粒化地鉴别操作,尝试次数、在尝试的间隔等待。这种组合可以确保pt-osc在合适的时机杀掉自己的等待会话进程,确保线程堆栈的空闲,并提供给我们循环操作来获取管理因触发器、重命名、修改外键而造成的锁。


  –tries swap_tables:5:0.5,drop_triggers:5:0.5




  它阐述了即便使用了诸如pt-osc之类的工具,充分了解你想解决的问题是很重要。下面的流程图会帮助你当你了解修改了MYSQL数据库的结构的注意事项。请仔细阅读建议尽管有些图上未标出,例如磁盘空间,IO加载等。


  选择合适的DDL操作


  确保能清楚了解在修改表结构对你的系统会产生何种影响,并选择合适的方法来使这种影响降到最低。有时这意味着需要将改动延期直到系统到了不常使用的时候或者使用能在操作期间不锁表的工具。当你表中有触发器的时候一般直接修改表结构。


  -大多数情况下pt-osc正是我们所需要的


  -在很多案例中pt-osc是需要的,但是用法需要稍作调整


  -在少数情况下pt-osc不是很合适,我们需要考虑本地阻塞修改,或者采用转移的操作改成在副本集中复制。





布拖县18536558596: 如何避免 MySQL 修改表结构时导致表无法使用的问题 -
驷军复锐: 来源:oschina.net 作者:whats_java MySQL 在修改表结构的时候可能会中断产品的正常运行影响用户体验,甚至更坏的结果,丢失数据.不是所有的数据库管理员、程序员、系统管理员都非常了解MySQL能避免这种情况.DBA会经常碰到这...

布拖县18536558596: 为什么说数据库表的结构不能随意修改 -
驷军复锐: 怕修改后导致数据丢失,比如你有个vchar类型的,你把它改成int,里面的数据什么字母ABCD啊它就转换不过去,不支持互相转换的数据就会全部清空....另外如果你写程序调用了数据库,结构一改很可能程序会出错,比如int a=1;int b=select b from table1 where...int c=a+b如果你把b对应的数据库列改成char类型了它运行就会出错,提示字符不能相+

布拖县18536558596: 怎么防止sql2000表被人修改 -
驷军复锐: 黑客攻击篡改东西的话,无外乎sql注入了 防止sql注入一般常见的就是限制权限,给提供程序可以运行的最小访问数据库权限,一般DDL权限全部禁止(特殊业务具体考虑) 然后就是页面的防护,在页面程序中,对sql语句尽量不拼接使用,对页面传来的参数要进行关键字过滤,一些可以在数据库执行的比如exec,update,insert,drop等都筛选过滤,这样即便被注入也不会有有效异常代码被执行

布拖县18536558596: 如何解决SqlServer2008修改表结构后无法保存的问题 -
驷军复锐: 装了SqlServer2008很久了,今天是第一次使用,结果在修改一张表的结构保存时,提示您对无法重新创建的标进行了更改或者启用了 阻止保存要求重新创建表的更改 选项.,试了几次一直是这个错误,删除表后重建,然后还是发生了这个错误...

布拖县18536558596: 优化MYSQL数据库的方法
驷军复锐: (1).选取最适用的字段属性,应该尽量把字段设置为NOT NULL,这样在将来执行查询的时候,数据库不用去比较NULL值. (2).使用连接(JOIN)来代替子查询(Sub-Queries) (3).使用联合(UNION)来代替手动创建的临时表 (4).尽量少使用 ...

布拖县18536558596: linux里的mysql中修改table数据时显示table readonly -
驷军复锐: 1. 看看你的表文件的权限是多少2. 表是否上锁3. 检查你的数据库用户对该数据库的那些表是否有单独的访问权限控制 最有可能是表文件的权限是多少 你所在LINUX用户组是否有这个权限.改成这个试试:-rwxrwx---

布拖县18536558596: SQL 2012如何更改“阻止保存要求重新创建表的更改”选项 -
驷军复锐: 当用户在在SQL Server 2008企业管理器中更改表结构时,必须要先删除原来的表,然后重新创建新表,才能完成表的更改,如果强行更改会出现以下提示:不允许保存更改.您所做的更改要求删除并重新创建以下表.您对无法重新创建的标进行了更改或者启用了“阻止保存要求重新创建表的更改”选项.如果要去掉此提示,可从“工具”菜单中选择“选项”,在“选项”对话框中,选择Designers,选择“表设计器和数据库设计器”,清除“ 阻止保存要求重新创建表的更改”复选框. 2012应该差不多

布拖县18536558596: 如果使用MySQL数据库,别人登录后修改mysql库的user表的用户数据怎么办.改怎么防止. -
驷军复锐: 不要给root用户的权限,给用户单独授权,可以指定用户只能访问某个数据库,或者只能在某个库中执行select这样的操作,具体内容自己查下很容易找到,比如这个网页链接

布拖县18536558596: 修改表结构会造成整个数据库假死,怎么办 -
驷军复锐: 如果确实不是因为使用的人多造成服务器崩溃的话,你需要检查具体连接信息,很可能是程序连接数据库,没有释放连接,造成一个程序多次连接数据库,把数据库给拖死了.那就需要改程序了.否则你需要买个更强大的服务器来支撑这么庞大的访问需求.

布拖县18536558596: MySQL数据库表很大,直接修改表结构非常慢,有没有有效的办法先把数据导出,然后清空表,再alte -
驷军复锐: 那还不如建立个新表,然后用insert把旧表的数据复制过去,再删除旧表.

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网