Your First Question
why does a OPTIMIZE query block the replication catching up ?
The SQL thread in MySQL Replication processes SQL commands from the Relay Logs as a FIFO queue (i.e. first-come, first-server basis). Once the SQL thread see a command, it processes it to completion. Meanwhile, the Seconds_Behind_Master just keeps creeping up.
While the SQL thread on the Slave is running OPTIMIZE TABLE
, once you run STOP SLAVE;
it SQL thread has complete the running OPTIMIZE TABLE
before the SQL thread can terminate. That's why STOP SLAVE;
hangs. To verify this, open another mysql session and run SHOW PROCESSLIST;
, You should see a line that has OPTIMIZE TABLE
with the status Killing slave...
.
Your Second Question
can I prevent those OPTIMIZE queries ? I didn't put any cron to do that, and as far as I can see, nothing in /etc/cron.{d,daily,hourly,weekly} does this.
Someone or something is running the OPTIMIZE TABLE
. You have to hunt it down in all your jobs or PHP apps. Use the mysqlbinlog utility to dumps all the binary logs into a text file. Then, grep the text file for OPTIMIZE TABLE
or optimize table
. The timestamp of when it was submitted into the binlogs will be a few lines about the command.
When you do find that OPTIMIZE TABLE
command in your jobs or PHP code, simply run this:
SET SQL_LOG_BIN=0; OPTIMIZE TABLE tblname; SET SQL_LOG_BIN=1;
This will not register the OPTIMIZE TABLE
in the binlogs, thus preventing a Slave from replicating it.
As was just pointed out in the comments below, You can also replace
OPTIMIZE TABLE tblname;
with one of the following:
OPTIMIZE NO_WRITE_TO_BINLOG TABLE tblname;
OPTIMIZE LOCAL TABLE tblname;
to restrict the OPTIMIZE TABLE command from landing in the binlogs and thus prevent replication of it.
Best Answer
Maybe none of these matter, but here are some guesses:
ORDER BY
. (Other constructs could be affected, too.)There are probably more things, but I can't think of any 'dangerous' ones.