使用 Ruby/Chef Recipe for Vagrant 导入 Mysql 数据库

发布于 2024-11-07 16:29:49 字数 621 浏览 0 评论 0原文

我正在编写一个厨师脚本来自动设置开发环境。我可以创建一个数据库并授予权限,但我试图找到一种方法将 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 的了解不多,所以很难弄清楚。有人知道我该怎么做吗?

I am writing a chef script to automate setting dev environments. I can get a database created and grant privileges but I am trying to find out a way to import a mysql dump file into the database that has just been created.

My code for granting the access is

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

and I was hoping I would be able to do the following query
#m.query("-u root -p root db_name < /project/db/import.sql")

but is just gives me an error.

I haven't done much Ruby so finding it hard to figure out. Anybody know how I can do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

只等公子 2024-11-14 16:29:49

如果是文件路径错误,并且您使用的是 Chef alone,请尝试使用 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

If it's a file path error, and you're using chef solo, try using the path specified within solo.rb, like:

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

As a general note, consider using the database cookbook for mysql user and database management tasks. Once you setup the necessary cookbook dependencies, you can put code like this into your main recipe's 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

Haven't tested that last one because storing a database file within the chef directory really slows things down.

See also: Import SQL file into mysql

双手揣兜 2024-11-14 16:29:49

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

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

You can create a backup from the MySQL command line client, but not from within a SQL query. You need to execute the command from the shell. I believe the execute resource might do the trick for you:

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

离鸿 2024-11-14 16:29:49

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

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

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

templates/default/。 my.cnf.erb

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

然后我向我的食谱添加了一个资源,该资源将填充模板:

recipes/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 并使用受限数据库用户连接到 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 数据库的名称。)

I'm not really a Ruby guy, but I managed to get Chef to import a large .sql file by leveraging the mysql command line tool. Challenges I needed to solve:

  • Import a .sql file in the 100's of MB range (YMMV if you need GBs or TBs)
  • Idempotentcy — only run the import if the .sql file has changed
  • Not pass credentials to MySQL as command parameters (a security concern)

First I created a .my.cnf file template to pass the credentials:

templates/default/.my.cnf.erb

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

Then I added a resource to my recipe that would populate the template:

recipes/import-db.rb

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

(Where node[:your_cookbook][:db][:root_password] is an attribute that contains the MySQL root password)

Security Note: for simplicity I'm doing the import as the root user. If the .sql file to be imported is not from a trusted source, you will want to run mysql as a limited user and connect to MySQL with a limited db user that only has access to the database in question.

Finally, I added another resource to the recipe that actually executes the import:

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

(Where node[:your_cookbook][:db][:name] is the name of the MySQL database that will be restored.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文