Я недавно обновил одно из своих приложений до Rails 2.2.2. Сделав это, я столкнулся со странной ошибкой производительности, которая приводила к тому, что рендеринг, который раньше выполнялся за доли секунды, занимал до 10 секунд.
Я профилировал проблему, а вот результаты, которые я придумала . Похоже, проблема в методе real_connect
класса Mysql. Насколько я понимаю, метод Ruby real_connect
является оболочкой для функции C mysql_real_connect()
. Это привело бы меня к мысли, что проблема должна быть связана с базой данных, поскольку я столкнулся с той же проблемой при запуске кода в Windows и Linux (сервер базы данных является отдельной системой). Однако я не верю, что это так, потому что, когда я возвращаюсь к предыдущей версии (до Rails 2.2.2) из моего хранилища subversion, проблема производительности исчезает. Это может показывать, что в ActiveRecord есть какая-то ошибка.
Как мне найти и исправить эту ошибку? У кого-нибудь есть понимание? Я что-то упускаю?
Обновление: я только что создал небольшой скрипт профилировщика для тестирования метода Mysql.real_connect, и похоже, что проблема не в Rails, а в геме MySQL или самом сервере баз данных.
После запуска следующий код:
result = RubyProf.profile do
5.times do
begin
# connect to the MySQL server
dbh = Mysql.real_connect(ip, user, pass, db)
# get server version string and display it
puts "Server version: " + dbh.get_server_info
rescue Mysql::Error => e
puts "Error code: #{e.errno}"
puts "Error message: #{e.error}"
puts "Error SQLSTATE: #{e.sqlstate}" if e.respond_to?("sqlstate")
ensure
# disconnect from server
dbh.close if dbh
end
end
end
printer = RubyProf::FlatPrinter.new(result)
printer.print(STDOUT, 0)
Я придумал такой результат:
Server version: 5.0.32-Debian_7etch3-log
Server version: 5.0.32-Debian_7etch3-log
Server version: 5.0.32-Debian_7etch3-log
Server version: 5.0.32-Debian_7etch3-log
Server version: 5.0.32-Debian_7etch3-log
Thread ID: 18998180
Total: 50.402000
%self total self wait child calls name
99.99 50.40 50.40 0.00 0.00 5 <Class::Mysql>#real_connect (ruby_runtime:0}
0.00 0.00 0.00 0.00 0.00 10 IO#write (ruby_runtime:0}
0.00 0.00 0.00 0.00 0.00 5 Mysql#get_server_info (ruby_runtime:0}
0.00 0.00 0.00 0.00 0.00 5 Kernel#puts (ruby_runtime: 0}
0.00 0.00 0.00 0.00 0.00 5 String#+ (ruby_runtime:0}
0.00 0.00 0.00 0.00 0.00 5 Mysql#initialize (ruby_runtime:0}
0.00 50.40 0.00 0.00 50.40 1 Integer#times (ruby_runtime:0}
0.00 50.40 0.00 0.00 50.40 1 Global#[No method] (tmp/mysql_test/test.rb:12}
0.00 0.00 0.00 0.00 0.00 5 Mysql#close (ruby_runtime: 0}
Кажется, что проблема не в ActiveRecord, а в геме MySQL или в базе данных. Куда мне идти отсюда?