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

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

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

脚本1
脚本2
脚本3
脚本4
脚本5

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

脚本1
脚本2
脚本3
脚本4
脚本5

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

脚本1
脚本2
脚本3
脚本4
脚本5

假设我们已经对上述三类需求很熟悉,很清楚自己在做什么。在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)

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

时间: 2024-09-19 02:18:42

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

三个按钮背后由小见大的交互思考

  初入交互设计工作,最常见的需求就是--放按钮.放按钮看起来是超级简单的事,无非就是设计按钮的样式.摆放按钮的位置.确定按钮的状态与反馈等,但殊不知其『麻雀虽小,五脏俱全』,小小的按钮设计中也蕴含了很多交互设计的思维,当然除了设计本身之外,还能看到如何平衡开发.产品以及用户各方的需求. 所以,本文章会通过三个真实但抽象的例子说明工作中『放按钮』是怎么做的.真实说的是案例来源于实战,抽象就是提炼出思维但讲的场景都是虚拟的,免得透露机密.有趣的是,三个按理都和时间.时效有关. 案例一 虚拟场景:某

图片-求教大神在myeclipse中java项目部署不到tomcat是什么原因

问题描述 求教大神在myeclipse中java项目部署不到tomcat是什么原因 解决方案 MyEclipse中的java项目,部署到tomcat失败MyEclipse中无法部署tomcat的原因MyEclipse中无法部署tomcat的原因 解决方案二: 你这个tomcat安装配置的有问题啊, 在本地先单独起一下服务器看行不 之后如果行,就是myeclipse里的配置问题 如果不行,你就重装吧 解决方案三: 你建的项目是web项目吗 解决方案四: 不是我建的是java项目,web项目是可以部

请教大神,android中我需要在自定义控件中绘制一个透明的小三角行?

问题描述 请教大神,android中我需要在自定义控件中绘制一个透明的小三角行? 请教大神,android中我需要在自定义控件中绘制一个透明的小三角行,比如我需要在LinearLayout的底部绘制一个透明背景小三角,该怎么绘制呢? 我在绘制的时候将设置成透明背景,绘制小三角不显示,必须要给他设置一个背景才会显示,纠结啊 解决方案 可以定义一个path吧,连接成一个三角形,然后画出来 解决方案二: 让UI给你做一个三角形的透明图 设为背景 解决方案三: path连接成个三角形的话,如果这个自定义

求大神帮忙 MySQL 去掉数据库中重复的数据,保留一条

问题描述 求大神帮忙 MySQL 去掉数据库中重复的数据,保留一条 解决方案 mysql中删除两条重复的数据,只保留一条mysql 删除重复数据只保留一条mysql删除重复数据只保留一条 解决方案二: 菜鸟的答复: ** 删除前先备份一下,万一错了,我不管 ** /* 假设你的表叫table_car */ DELETE FROM table_car WHERE car_id NOT IN (SELECT MIN(car_id) FROM table_car GROUP BY car_line_i

Powershell小技巧之查找脚本中的函数_PowerShell

要快速获取你PS脚本库中所有文件的函数名,你可以这样做: 复制代码 代码如下: filter Find-Function {    $path = $_.FullName    $lastwrite = $_.LastWriteTime    $text = Get-Content -Path $path        if ($text.Length -gt 0)    {              $token = $null       $errors = $null       $ast

Docker 在 Uber 服务部署中的应用

本文讲的是Docker 在 Uber 服务部署中的应用,[编者的话]快速创新的迫切要求,使得 Uber 开始在服务部署中应用 Docker .这篇文章讲述了部署方式的转变过程,强调在全面容器化之前,必须做充足的准备. 无论你对 Uber 的看法如何, Uber 无疑是创新的同义词,因为它在颠覆交通行业的同时引领了共享经济.像Uber 这样的最快创新者,就像 Microsoft, Apple 和 Amazon 公司一样,都面临一个问题:一旦你开始创新并且取得成功,你不得不一直保持这样快的创新速度,

《MySQL DBA修炼之道》——第2章 MySQL安装部署和入门 2.1如何选择MySQL版本

第2章 MySQL安装部署和入门 2.1 如何选择MySQL版本 在选择MySQL的版本时,要根据生产情况来决定,是对现有生产环境中的数据库进行版本升级呢?还是部署新的数据库呢?如果已经在生产环境中部署了MySQL,那么我们不需要急着将其升级到最新版本,旧的版本已经在生产环境中长期稳定地运行,而新版本刚出来时,往往并不是那么稳定,通常都会有一些Bug需要修复.不稳定版本将导致生产系统的不稳定,所以,如果不是急需新版本的某种特性,或者旧版本有严重的安全隐患,建议继续使用旧的MySQL版本即可.如果

由一条create语句的问题对比mysql和oracle中的date差别

今天开发的同事提交过来一个sql变更,在部署的时候发现了一个问题. 语句是一个简单的create语句 CREATE TABLE `test_user` (   `openid` varchar(64) NOT NULL,   `amount` varchar(11) DEFAULT 0,   `create_time` datetime DEFAULT CURRENT_TIMESTAMP,   `update_time` datetime DEFAULT CURRENT_TIMESTAMP,  

演讲实录:MySQL 8.0 中的复制技术

01定义 02 MySQL复制技术的简单框架 首先在复制环境中,有两个server,在第一个server中产生binary log,通常将这一个server成为master,另外一台server会将master上的binary log复制过去,然后通过日志的应用,产生和master一样的数据库,这就是复制的基本理论.其基本流程如下: 当应用在master数据库上执行SQL语句,这些操作会被数据库捕捉并以event的形式写到binary log里面,并以文件的形式存储.通过通讯模块,这些event