昨天在处理一个日常运维工单的时候,出现了一个问题,大概是这样的:快到双十一了,公司需要拓展业务,开发的同事想要在一个数据库里面的所有表中添加几个字段,给的SQL原型如下,其中的数据库名称、表名称、字段名称以及注释我简单进行了修改:
ALTER TABLE `db_name`.`tbl_name1` ADD COLUMN `new_col1` int(11) NOT NULL DEFAULT 0 COMMENT '*****';ALTER TABLE `db_name`.`tbl_name1` ADD COLUMN `new_col2` int(11) NOT NULL DEFAULT 0 COMMENT '*****';ALTER TABLE `db_name`.`tbl_name1` ADD COLUMN `new_col3` int(11) NOT NULL DEFAULT 0 COMMENT '*****';ALTER TABLE `db_name`.`tbl_name1` ADD COLUMN `new_col4` int(11) NOT NULL DEFAULT 0 COMMENT '*****';ALTER TABLE `db_name`.`tbl_name1` ADD COLUMN `new_col5` int(11) NOT NULL DEFAULT 0 COMMENT '*****';ALTER TABLE `db_name`.`tbl_name1` ADD COLUMN `new_col6` int(11) NOT NULL DEFAULT 0 COMMENT '*****';ALTER TABLE `db_name`.`tbl_name1` ADD COLUMN `new_col7` int(11) NOT NULL DEFAULT 0 COMMENT '*****'; |
---|
因为这些操作是需要对指定数据库中所有的表都进行处理,接到这个需求,我首先连上了指定服务器上对应的数据库看了看这个数据库中存在多少个,结果如下:
...
每张表都需要添加上面的7个字段,一共需要的语句是204*7=1428条。这么大的数据量,肯定是不可能通过人工去实现的,观察这些表的名称结构,只有后缀名是不一样的,而且是按照自然日顺序排列的日表。看到这里,想起了一个以前同事写的脚本,恰好能解决这个问题,这个脚本的思路是这样的:将上面的7个SQL语句执行204遍,每一遍只对数据表的名称进行更换。
这样,问题就被定位成了怎样在每次循环的时候去更改表名称。这里不卖关子了,直接给出脚本的内容:
:
startdate=`date -d "20181028" +%Y%m%d`enddate=`date -d "20181101" +%Y%m%d`function main(){while [[ ${startdate} < ${enddate} ]] do echo ${startdate}cat /home/yeyz/create_sql.sql >> /home/yeyz/alter_table.sqlsed -i "s/20181028/${startdate}/g" /home/yeyz/alter_table.sql echo "" >> /home/yeyz/alter_table.sql echo startdate=`date -d "+1 day ${startdate}" +%Y%m%d`done}main |
---|
用vim打开就是这样的:
简单说明一下,create_sql.sql里面是那7个添加字段的SQL,alter_table.sql是最终的结果。需要注意的是,SQL语句中需要添加一个时间后缀,仅仅是为了替换,没有别的意义。create_sql.sql的内容如下:
首先,定义两个时间类型的变量,一个起始时间,一个终止时间,然后进行循环,对那7个SQL语句中的时间进行替换,然后将起始时间+1,再去参与到下一轮的循环当中。
在这个过程中,我们对每一轮循环时候的起始时间进行了echo打印,为了实验效果好,我们把时间设定为2018.10.28---2018.11.01,只有4天,跑这个脚本,在Linux的控制终端 我们会看到如下的结果:
可以看出,时间已经开始叠加了。再打开alter_create.sql,可以看到它里面的SQL已经变成这样:
后面每一天的alter语句都出现了,而且时间也已经发生了相应的改变。这样我们就能复制这些SQL直接去线上环境执行了,问题也就解决了。
回过头来再看这个脚本,这个脚本中最重要的一句是:
sed -i "s/20181028/${startdate}/g" /home/yeyz/alter_table.sql |
---|
这句话的linux里面的sed命令,它的目的是在文件中的每一行去匹配20181028,然后用startdate去替换它,它的语法是:
sed -i "s/旧名称/新名称/g" file |
---|
是不是感觉这个命令的功能很强大?这个命令还有很多其他的功能,明天把sed这个命令详细讲一讲吧。