In commit 9051da90e4da2ab0db16530a7f7568e24a0ccaed the following line
was added to MysqlAdapter#connect:
@connection.reconnect = true if @connection.respond_to?
(:reconnect=)
There are couple of problems with this:
1. It doesn't stick. A look at the sources of the mysql gem tells that
the
real_connect method sets reconnect to 0 (false). Since real_connect
is called
after the line given about, it'll reset the value of reconnect to
0. A simple
test for that will be:
This test fails. And it's easy to fix, we'll just move the line
above to
somewhere after the real_connect() call. (Unless, I'm missing
something,
of course.)
2. Even after I fixed #1, I couldn't make reconnect work in my tests.
I did a simple
test without AR (directly with mysql gem), and it works OK (you can
see that
reconnection happened because the thread_id of the connection is
modified).
However, with AR I keep getting the "MySQL server has gone away"
errors. Here's
my test (should be in connection_test_mysql.rb):
# this shouldn't raise Mysql::Error if reconnect is true
assert_equal ["42"], @connection.select_values('SELECT 42')
new_thread_id = mysql_connection.thread_id
assert_not_equal original_thread_id, new_thread_id
end
3. Do we want the reconnection at all? According to Mysql docs
( http://dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html )
the auto-reconnect does not save any session variables. This
includes these
two settings that AR sets after connection is established:
SET NAMES 'utf8'
SET SQL_AUTO_IS_NULL=0
Which means, if the server was gone, auto-reconnect takes place on
the next
query, but the variables are back to the server default (use
SHOW VARIABLES LIKE 'character_set_client' to view the variable
value before
and after the reconnection). On my machine it's back to 'latin1'.
Just a quick note that we experienced similar difficulties with
reconnection and mysqlplus.
Found sending a mysql_ping down the wire to assert that the thread
identifier changed works best.
libmysqld also reuses previously opened file descriptors for
reconnection attempts.
Reconnect behavior is especially important for an async interface as
simply setting mysql.reconnect = true essentially
invalidates an existing operation when sent down the wire, but pending
a result.
> In commit 9051da90e4da2ab0db16530a7f7568e24a0ccaed the following line
> was added to MysqlAdapter#connect:
> @connection.reconnect = true if @connection.respond_to?
> (:reconnect=)
> There are couple of problems with this:
> 1. It doesn't stick. A look at the sources of the mysql gem tells that
> the
> real_connect method sets reconnect to 0 (false). Since real_connect
> is called
> after the line given about, it'll reset the value of reconnect to
> 0. A simple
> test for that will be:
> This test fails. And it's easy to fix, we'll just move the line
> above to
> somewhere after the real_connect() call. (Unless, I'm missing
> something,
> of course.)
> 2. Even after I fixed #1, I couldn't make reconnect work in my tests.
> I did a simple
> test without AR (directly with mysql gem), and it works OK (you can
> see that
> reconnection happened because the thread_id of the connection is
> modified).
> However, with AR I keep getting the "MySQL server has gone away"
> errors. Here's
> my test (should be in connection_test_mysql.rb):
> # this shouldn't raise Mysql::Error if reconnect is true
> assert_equal ["42"], @connection.select_values('SELECT 42')
> new_thread_id = mysql_connection.thread_id
> assert_not_equal original_thread_id, new_thread_id
> end
> 3. Do we want the reconnection at all? According to Mysql docs
> ( http://dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html )
> the auto-reconnect does not save any session variables. This
> includes these
> two settings that AR sets after connection is established:
> SET NAMES 'utf8'
> SET SQL_AUTO_IS_NULL=0
> Which means, if the server was gone, auto-reconnect takes place on
> the next
> query, but the variables are back to the server default (use
> SHOW VARIABLES LIKE 'character_set_client' to view the variable
> value before
> and after the reconnection). On my machine it's back to 'latin1'.
On Jan 22, 4:50 pm, Mislav Marohnić <mislav.maroh...@gmail.com> wrote:
> How can the test fail if the `reconnect` property is 0? Zero is true in
> Ruby.
The reconnect accessor method of the mysql gem returns 'true' or
'false'. In the C implementation of real_connect it sets the reconnect
flag to 0 in each connect.
> 1. It doesn't stick. A look at the sources of the mysql gem tells that > the > real_connect method sets reconnect to 0 (false). Since real_connect > is called > after the line given about, it'll reset the value of reconnect to > 0. A simple > test for that will be:
> This test fails. And it's easy to fix, we'll just move the line > above to > somewhere after the real_connect() call. (Unless, I'm missing > something, > of course.)
Send us a patch with test for this one, nice find!
> 2. Even after I fixed #1, I couldn't make reconnect work in my tests. > I did a simple > test without AR (directly with mysql gem), and it works OK (you can > see that > reconnection happened because the thread_id of the connection is > modified). > However, with AR I keep getting the "MySQL server has gone away" > errors. Here's > my test (should be in connection_test_mysql.rb):
> # this shouldn't raise Mysql::Error if reconnect is true > assert_equal ["42"], @connection.select_values('SELECT 42') > new_thread_id = mysql_connection.thread_id > assert_not_equal original_thread_id, new_thread_id > end
> 3. Do we want the reconnection at all? According to Mysql docs > ( http://dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html ) > the auto-reconnect does not save any session variables. This > includes these > two settings that AR sets after connection is established:
> SET NAMES 'utf8' > SET SQL_AUTO_IS_NULL=0
> Which means, if the server was gone, auto-reconnect takes place on > the next > query, but the variables are back to the server default (use > SHOW VARIABLES LIKE 'character_set_client' to view the variable > value before > and after the reconnection). On my machine it's back to 'latin1'.
I think we should probably push reconnect into an option in database.yml so users can make their own decisions. In my case the character_set values are set in my.cnf so those queries don't actually change anything for me.
A patch to fix this up and test that the value is actually set would be greatly appreciated. Failing that, a lighthouse ticket assigned to jeremy would be a good start.
Thanks again for spending the time to look into this.
> Send us a patch with test for this one, nice find!
...
> I think we should probably push reconnect into an option in > database.yml so users can make their own decisions. In my case the > character_set values are set in my.cnf so those queries don't actually > change anything for me.
> A patch to fix this up and test that the value is actually set would > be greatly appreciated. Failing that, a lighthouse ticket assigned to > jeremy would be a good start.
Sounds good. I will send a patch later today. Should I also open a lighthouse ticket, or just post the patch here?