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, 2,985 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(){
chomp;
$server_list[$i] = [split(/,/,$_)];
$i++;
}
close(FILE);
# Read SQL List File
open(FILE,"$sql_file");
$i = 0;
$sql = '';
while(){
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到目标主机上,然后执行,执行完毕后删除,返回确认后再操作下一台.
[回复]