专栏首页杨建荣的学习笔记由小见大-MySQL脚本部署中的一些策略

由小见大-MySQL脚本部署中的一些策略

在线上环境中部署脚本,可谓是常在河边走,哪有不湿鞋,所以大大小小的案例总结下来,还是会发现一些有趣的地方,这些可以作为操作时的一些参考,仅供参考而已。

第一类脚本是修复脚本,比如提供的数据修复功能,数据补丁等,这类脚本的特点是后续的数据变更很可能会依赖于之前的操作,环环相扣。所以一旦执行过程中出现问题,就需要保证这个操作可回退,否则会是雪上加霜。

第二类的脚本是彼此之间没有直接联系。哪怕是中间执行出一点问题也不会直接影响其他业务。

第三类的脚本介于两者之间,有互相的依赖,也有彼此独立的部分。

假设我们已经对上述三类需求很熟悉,很清楚自己在做什么。在MySQL的场景中是否可以都一一满足呢。

我们可以做一个简单的测试来说明。首先我们创建一个表test_abc,然后插入3条数,其中第2条是有问题的,插入可能会报错。

create table test_abc (id int primary key,name varchar(20)); insert into test_abc values(1,'aa'); insert into test_abc values('aa','bb'); insert into test_abc values(3,'cc');

那现在就有几种实现方式,

1)执行第2条报错,直接忽略,继续执行

2)执行第2条报错,直接在这里定格,然后退出

3)执行第2条报错,然后回滚退出

所以说这样一个看起来极其简单的语句其实可能有下面三种执行的结果,这就和我刚开始所说的场景很类似了。

我们来看看具体怎么实现。

方法1:首先使用source的方式执行脚本,发现执行在第2条insert出失败,但是从执行日志可以看出,是继续执行了。

mysql> source test1.sql
Query OK, 0 rows affected (0.04 sec)
Query OK, 1 row affected (0.00 sec)
ERROR 1366 (HY000): Incorrect integer value: 'aa' for column 'id' at row 1
Query OK, 1 row affected (0.01 sec)

查看执行后的表数据,确实id为1和3的记录都插入了。

mysql> select *from test_abc;
+----+------+
| id | name |
+----+------+
|  1 | aa   |
|  3 | cc   |
+----+------+
2 rows in set (0.00 sec)

方法2:方法2看起来很简洁,就是通过重定向的方式来执行,可以从错误日志看出是执行到了第2条语句失败了。

# mysql  test < test1.sql 
ERROR 1366 (HY000) at line 5: Incorrect integer value: 'aa' for column 'id' at row 1

查看数据的情况,会发现前面的执行是成功了,后面都没执行,直接退出了。

mysql> select *from test_abc;
+----+------+
| id | name |
+----+------+
|  1 | aa   |
+----+------+
1 row in set (0.09 sec)

方法3:我们开启事务,看看能否达到我们的预期结果,可以顺利回滚。

mysql>begin;

mysql> source test1.sql
Query OK, 0 rows affected (0.03 sec)
Query OK, 1 row affected (0.00 sec)
ERROR 1366 (HY000): Incorrect integer value: 'aa' for column 'id' at row 1
Query OK, 1 row affected (0.01 sec)

这个时候查看数据结果,会发现id为1和3都已经插入了。

mysql> select*from test_abc;
+----+------+
| id | name |
+----+------+
|  1 | aa   |
|  3 | cc   |
+----+------+
2 rows in set (0.00 sec)

我们来尝试回滚

mysql> rollback;
Query OK, 0 rows affected (0.00 sec)

但是很不幸,没有任何反应

mysql> select*from test_abc;
+----+------+
| id | name |
+----+------+
|  1 | aa   |
|  3 | cc   |
+----+------+
2 rows in set (0.00 sec)

这个问题的主要原因是什么呢,其实是第一句是一个create语句,是DDL,会自动提交事务。所以后续的操作就直接无法回滚了。由此我们需要注意的就是在脚本中是否有DDL,如果有还是需要特别 注意的。

方法4:

所以我们剔除脚本里面的DDL,分开单独执行,脚本只保留了那3条insert.

然后我们手工开启事务。

mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> source test1.sql
Query OK, 1 row affected (0.00 sec)
ERROR 1366 (HY000): Incorrect integer value: 'aa' for column 'id' at row 1
Query OK, 1 row affected (0.01 sec)

这个时候查看数据,id为1和3的结果都在。

mysql> select *from test_abc;
+----+------+
| id | name |
+----+------+
|  1 | aa   |
|  3 | cc   |
+----+------+
2 rows in set (0.00 sec)
果断回滚,会发现数据可以达到我们的预期了。
mysql> rollback;
Query OK, 0 rows affected (0.09 sec)
mysql> select *from test_abc;
Empty set (0.00 sec)

所以针对上面三种情况,我们可以得到一很明确的结果。

而如果可以尽可能还是在事务里来控制吧,毕竟MySQL是默认自动提交的。后悔了都来不及。

对于事务的完整性,还有两点需要说一下,第一个是事务正常退出,事务是回滚还是提交。另外一个则是杀掉执行的会话,事务会默认提交还是回滚。

我们一个一个来测试,先来看kill会话的部分。

mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test_abc values(5,'ee');
Query OK, 1 row affected (0.00 sec)

然后打开另外一个窗口 kill掉当前执行的会话。然后继续观察。 查询的时候,会发现原来的会话其实已经杀掉了,会自动开启一个新的会话。很明显,事务做了回滚。

mysql> select *from test_abc;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    639
Current database: test
+----+------+
| id | name |
+----+------+
|  1 | aa   |
+----+------+
1 row in set (0.09 sec)

另外一个则是正常退出情况下的

mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test_abc values(1,'ff');
Query OK, 1 row affected, 0 warning (0.00 sec)
mysql> select *from t1;
+------+------+
| col1 | col2 | 
+------+------+
|    1 | ff| 
+------+------+
1 row in set (0.00 sec)
mysql> exit   --正常退出
Bye
重新登录来验证,会发现事务已经回滚了。
mysql> select *from t1;
Empty set (0.00 sec)

所以通过上面的测试我们可以很清晰的知道这些可能的场景和具体的应对策略,如果明白了这些,在具体业务的操作中至少会长个心。

本文分享自微信公众号 - 杨建荣的学习笔记(jianrong-notes),作者:r14笔记第26天

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-10-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • MySQL 5.6, 5.7并行复制测试(二)(r12笔记第10天)

    昨天花了点时间整理了下并行复制在5.6,5.7中的一些差别和测试,MySQL 5.6, 5.7并行复制测试(r12笔记第9天),当然只是一个开始,因为里面还...

    jeanron100
  • 关于CPU使用率高的awr分析(r8笔记第46天)

    今天看到一个报警信息,大体是CPU使用异常。 ZABBIX-监控系统: ------------------------------------ 报警内容: ...

    jeanron100
  • CPU 100%负载的性能优化分析(r7笔记第40天)

    今天收到报警邮件,提示在短时间内DB time有了很大的抖动。报警邮件如下: ZABBIX-监控系统: ------------------------...

    jeanron100
  • alpine安装sshd/ssh server

    sunsky
  • Nature Climate Change | 现在的极端气候将成为北极“新常态”

    北极是对于气候变化最为敏感的地区,也是全球增暖最显著的地区。近几十年来,北极地区的大气、海洋、海冰以及陆地都发生了很大的变化,特别是近十年来,北极海冰迅速减少,...

    气象学家
  • 携程为何“记住上一次”?只因OTA的未来是个性化服务引擎

    最近打开携程App预定机票,选中机票进入订单确认页面后,发现部分附加增值产品,如接送机优惠券被勾选,虽然在下方的费用明细栏有清晰的说明,但还是让人意外。在去年国...

    罗超频道
  • #define sec(x) __attribute__((section(#x),used))

    #define sec(x) __attribute__((section(#x),used))

    心跳包
  • CMDB开发

    TIL即IT基础架构库(Information Technology Infrastructure Library, ITIL,信息技术基础架构库)由英国政府部...

    菲宇
  • websocket+Django+python+paramiko实现web页面执行命令并实时输出

    WebSocket的工作流程:浏览器通过JavaScript向服务端发出建立WebSocket连接的请求,在WebSocket连接建立成功后,客户端和服务端就可...

    py3study
  • 直播平台开发前要做的准备及注意事项

    1、产品定位:无论是开发什么样的直播APP,前期的市场分析是必不可少的。市场调研点就是要发现直播要给到企业的主要作用是什么,然后对功能的细化演绎。其次,就是发现...

    布谷安妮

扫码关注云+社区

领取腾讯云代金券