8

我正在编写一个厨师脚本来自动设置开发环境。我可以创建一个数据库并授予权限,但我试图找到一种将 mysql 转储文件导入刚刚创建的数据库的方法。

我授予访问权限的代码是

ruby_block "Execute grants" do
  block do

    require 'rubygems'
    Gem.clear_paths
    require 'mysql'

    m = Mysql.new('localhost', "root", node[:mysql][:server_root_password])
    m.query("GRANT ALL ON *.* TO 'root'@'10.0.0.1' IDENTIFIED BY '#{node[:mysql][:server_root_password]}'")
    m.query('FLUSH PRIVILEGES')
end
end

我希望我能够进行以下查询 #m.query("-u root -p root db_name < /project/db/import.sql")

但只是给了我一个错误。

我没有做太多的Ruby,所以很难弄清楚。有人知道我该怎么做吗?

4

3 回答 3

5

如果是文件路径错误,并且您正在使用 chef solo,请尝试使用solo.rb中指定的路径,例如:

/tmp/chef-solo/site-cookbooks/path_to_file.sql

作为一般说明,请考虑将数据库说明书用于 mysql 用户和数据库管理任务。设置必要的说明书依赖项后,您可以将这样的代码放入主配方的default.rb中:

# externalize conection info in a ruby hash
mysql_connection_info = {
  :host => "localhost",
  :username => 'root',
  :password => node['mysql']['server_root_password']
}

# drop if exists, then create a mysql database named DB_NAME
mysql_database 'DB_NAME' do
  connection mysql_connection_info
  action [:drop, :create]
end

# query a database from a sql script on disk
mysql_database "DB_NAME" do
  connection mysql_connection_info
  sql { ::File.open("/tmp/chef-solo/site-cookbooks/main/path/to/sql_script.sql").read }
  action :query
end

#or import from a dump file
mysql_database "DB_NAME" do
  connection mysql_connection_info
  sql "source /tmp/chef-solo/site-cookbooks/main/path/to/sql_dump.sql;"
end

没有测试最后一个,因为在 chef 目录中存储数据库文件确实会减慢速度。

另请参阅:将 SQL 文件导入 mysql

于 2013-07-07T23:09:25.710 回答
3

您可以从 MySQL 命令行客户端创建备份,但不能从 SQL 查询中创建。您需要从 shell 执行命令。我相信该execute资源可能会为您解决问题:

http://wiki.opscode.com/display/chef/Resources#Resources-Execute

于 2011-05-20T04:09:46.433 回答
1

我不是真正的 Ruby 人,但我设法让 Chef.sql通过利用mysql命令行工具导入一个大文件。我需要解决的挑战:

  • 导入.sql100 MB 范围内的文件(如果您需要 GB 或 TB,则为 YMMV)
  • 幂等性.sql— 仅在文件已更改时才运行导入
  • 不将凭据作为命令参数传递给 MySQL(安全问题)

首先,我创建了一个.my.cnf文件模板来传递凭据:

模板/默认/.my.cnf.erb

[client]
host=<%= @host %>
user=<%= @user %>
password="<%= @password %>"

然后我在我的食谱中添加了一个资源来填充模板:

食谱/import-db.rb

template '/root/.my.cnf' do
  mode 0600
  variables({
    :host => 'localhost',
    :user => 'root',
    :password => node[:your_cookbook][:db][:root_password],
  })
end

node[:your_cookbook][:db][:root_password](包含 MySQL root 密码的属性在哪里)

安全说明:为简单起见,我以root用户身份进行导入。如果.sql要导入的文件不是来自受信任的来源,您将希望以受限用户身份运行mysql并使用只能访问相关数据库的受限 db 用户连接到 MySQL。

最后,我在实际执行导入的配方中添加了另一个资源:

backup_sql = '/path/to/the/db-backup.sql'
db_last_modified = "/etc/db-#{node[:your_cookbook][:db][:name]}.lastmodified"

execute 'restore backup' do
  command "mysql #{node[:your_cookbook][:db][:name]} <'#{backup_sql}' && touch '#{db_last_modified}'"
  not_if { FileUtils.uptodate?(db_last_modified, [backup_sql]) }
end

node[:your_cookbook][:db][:name](要恢复的 MySQL 数据库的名称在哪里。)

于 2015-07-20T23:49:05.350 回答