MySQL多服务器批量执行SQL脚本
本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/program/mysql_bat_sql_script_mybatsql.html
主要应用场景是,假设我们有一个库DB进行了水平拆分,DB1~10都需要更改表结构,如果手动到各个服务器去执行,效率太低,写了个脚本来做这个事情,叫mybatsql。
用法很简单,需要两个文件,server.list和sql.list,跟脚本放在同一目录下。
server.list中放服务器的主机名/IP,用户名,密码;sql.list中放需要批量执行的SQL。
例如:
server.list
127.0.0.1,root,111
127.0.0.2,root,111
sql.list
show status;
show variables;
这两个文件表示,我要在127.0.0.1和127.0.0.2上执行show status;show variables;语句。
也可以通过参数-l/-s指定这两个文件的地址:perl mybatsql.pl -l server_server_file -s sql_file
mybatsql.pl (4.1 KiB, 266 hits)
#!/usr/bin/perl -w ####################################################### # Create: P.Linux # Function: Run DDL On Server List # Usage: Run on any computer with Perl # License: GPL v2 # Site: PengLiXun.COM # Modify: # P.Linux 2010-03-10 # -Create 1.0 Release ######################################################## use strict; use DBI; use DBD::mysql; use Getopt::Std; use vars qw($opt_l $opt_s); ######################################################## # Global Status Var # 全局状态变量 my @server_list; my $sql; # Connect to database via DBI # 通过DBI连接数据库 my @dbconn; # CmdLine Option vars # 命令行参数变量 my($server_file, $sql_file); # Version my $version='1.0 Release'; ####################################################### # Main Program # 主程序 ####################################################### # Get CmdLine Options # 获取命令行参数 &get_option(); # Read Server List From File # 从文件中读取服务器列表 &read_file(); # Crate MySQL Database Connect # 创建MySQL数据库连接 &create_conn(); # Run SQL # 执行SQL &run(); # Disconnect from MySQL # 从数据库断开连接 &close_conn(); ####################################################### # Print Usage # 打印使用方法 ####################################################### sub print_usage () { printf <<EOF NAME: mybatsql SYNTAX: mybatsql -l server_server_file -s sql_file FUNCTION: Run SQL on Server List PARAMETER: -l Database Server List File DEFAULT:server.list -s SQL File DEFAULT:sql.list EOF } ####################################################### # Get Options # 获取命令行参数 ####################################################### sub get_option(){ my $rtn = getopts('l:s'); unless ( "$rtn" eq "1" ) { print_usage(); exit 1;} $server_file=$opt_l?$opt_l:'server.list'; $sql_file=$opt_s?$opt_s:'sql.list'; if($ARGV[0]){ $server_file=$ARGV[0]; } if($ARGV[1]){ $sql_file=$ARGV[1]; } $server_file = lc($server_file); $sql_file = lc($sql_file); } ####################################################### # Read Server List & SQL From File # 从文件中读取服务器列表和SQL。 ####################################################### sub read_file{ my $i; # Read Server List File open(FILE,"$server_file"); $i = 0; while(<FILE>){ chomp; $server_list[$i] = [split(/,/,$_)]; $i++; } close(FILE); # Read SQL List File open(FILE,"$sql_file"); $i = 0; $sql = ''; while(<FILE>){ chomp; $sql .= $_; $i++; } close(FILE); } ####################################################### # Create MySQL Database Connect # 创建MySQL数据库连接 ####################################################### sub create_conn{ my $i = 0; foreach my $server (@server_list){ my @srv = @{$server}; my $host = $srv[0]; my $user = $srv[1]; my $pwd = $srv[2]; #print "$host.$user.$pwd\n"; eval{ local $SIG{ALRM} = sub { die "连接数据库超时\n" }; alarm 20; $dbconn[$i] = DBI->connect("DBI:mysql:host=$host", $user, $pwd, {'RaiseError' => 1}) or die "Connect to $host error:". DBI->errstr; alarm 0; }; if($@){ printf "Connect to $host database error:".$@."\n"; exit; } $i++; } } ####################################################### # Main Program to Run SQL on Server List # 在服务器列表上执行一组SQL ####################################################### sub run{ foreach my $conn (@dbconn) { #print $sql; $conn->do($sql); $conn->commit(); } } ####################################################### # Disconnect from MySQL # 从数据库断开连接 ####################################################### sub close_conn(){ foreach my $conn (@dbconn) { $conn->disconnect; } } |
不错.我也写了一个,就是把sql文件通过信任关系scp到目标主机上,然后执行,执行完毕后删除,返回确认后再操作下一台.
[回复]