Here is an explanation of what is supported and what is not:
Replication will be done correctly with AUTO_INCREMENT, LAST_INSERT_ID(), and TIMESTAMP values.
The USER() and LOAD_FILE() functions are replicated without changes and will thus not work reliably on the slave. This is also true for CONNECTION_ID() in slave versions older than 4.1.1. The new PASSWORD() function in MySQL 4.1, is well replicated since 4.1.1 masters; your slaves must be 4.1.0 or above to replicate it. If you have older slaves and need to replicate PASSWORD() from your 4.1.x master, you must start your master with option --old-password.
The SQL_MODE, UNIQUE_CHECKS, SQL_AUTO_IS_NULL variables are replicated only starting from 5.0.0. SQL_SELECT_LIMIT and TABLE_TYPE variables are not replicated yet. FOREIGN_KEY_CHECKS is replicated since version 4.0.14.
You must use the same character set (--default-character-set) on the master and the slave. Otherwise, you may get duplicate key errors on the slave, because a key that is regarded as unique in the master character set may not be unique in the slave character set. Character sets will be replicated in 5.0.x.
If you are using transactional tables on the master and non-transactional tables (for the same tables) on the slave, you will get problems if the slave is stopped in the middle of a BEGIN/COMMIT block, as the slave will later start at the beginning of the BEGIN block. This issue is on our TODO and will be fixed in the near future.
Update queries that use user variables are badly replicated in 3.23 and 4.0. This is fixed in 4.1. Note that user variable names are case insensitive starting from version 5.0, so you should take this into account when setting up replication between 5.0 and a previous version.
The slave can connect to the master using SSL, if the master and slave are both 4.1.1 or newer.
Though we have never heard of it actually occurring, it is theoretically possible for the data on the master and slave to become different if a query is designed in such a way that the data modification is non-deterministic, that is, left to the will of the query optimizer (which generally is not a good practice, even outside of replication!). For a detailed explanation, see Open bugs.
Before MySQL 4.1.1, FLUSH, ANALYZE, OPTIMIZE, REPAIR commands are not stored in the binary log and thus are not replicated to the slaves. This is not normally a problem as these commands don't change anything. However, it does mean that if you update the MySQL privilege tables directly without using the GRANT statement and you replicate the mysql privilege database, you must do a FLUSH PRIVILEGES on your slaves to put the new privileges into effect. Also if you use FLUSH TABLES when renaming a MyISAM table involved in a MERGE table, you will have to issue FLUSH TABLES manually on the slave. Since MySQL 4.1.1, these commands are written to the binary log (except FLUSH LOGS, FLUSH MASTER, FLUSH SLAVE, FLUSH TABLES WITH READ LOCK) unless you specify NO_WRITE_TO_BINLOG (or its alias LOCAL). For a syntax example, see FLUSH.
MySQL only supports one master and many slaves. Later we will add a voting algorithm to automatically change master if something goes wrong with the current master. We will also introduce ``agent'' processes to help do load balancing by sending SELECT queries to different slaves.
Starting from MySQL 4.0.18, the master notifies the slave of a HEAP table having been emptied by master's shutdown/restart by writing a DELETE FROM to its binary log the first time it uses the table since startup. See HEAP for more details.
Temporary tables are replicated with the exception of the case that you shut down slave server (not just slave thread) and you have some replicated temporary tables that are used in update statements that have not yet been executed on the slave. (If you shut down the slave, the temporary tables needed by those updates no longer are available when the slave starts again.) To avoid this problem, do not shut down the slave while it has temporary tables open. Instead, use this procedure:
Issue a STOP SLAVE statement.
Use SHOW STATUS to check the value of the Slave_open_temp_tables variable.
If the value is 0, issue a mysqladmin shutdown command to shut down the slave.
If the value is not 0, restart the slave threads with START SLAVE.
Repeat the procedure later to see if you have better luck next time.
We have plans to fix this problem in the near future.
It is safe to connect servers in a circular master/slave relationship with log-slave-updates enabled. Note, however, that many queries will not work correctly in this kind of setup unless your client code is written to take care of the potential problems that can happen from updates that occur in different sequence on different servers.
This means that you can do a setup like the following:
A -> B -> C -> A
Server IDs are encoded in the binary log events. A will know when an event it reads had originally been created by A, so A will not execute it and there will be no infinite loop. But this circular setup will work only if you only if you perform no conflicting updates between the tables. In other words, if you insert data in A and C, you should never insert a row in A that may have a conflicting key with a row insert in C. You should also not update the same rows on two servers if the order in which the updates are applied matters.
If a query on the slave gets an error, the slave SQL thread will terminate, and a message will appear in the slave error log. You should then connect to the slave manually, fix the cause of the error (for example, non-existent table), and then run START SLAVE.
If the connection to the master is lost, the slave will try to reconnect immediately. If that fails, the slave will retry every master-connect-retry seconds (default 60). Because of this, it is safe to shut down the master, and then restart it after a while. The slave will also be able to deal with network connectivity outages. However, the slave will notice the network outage only after receiving no data from the master for slave_net_timeout seconds. So if your outages are short, you may want to decrease slave_net_timeout. See SHOW VARIABLES.
Shutting down the slave (cleanly) is also safe, as it keeps track of where it left off. Unclean shutdowns might produce problems, especially if disk cache was not synced before the system died. Your system fault tolerance will be greatly increased if you have a good UPS.
Due to the non-transactional nature of MyISAM tables, it is possible to have a query that will only partially update a table and return an error code. This can happen, for example, on a multi-row insert that has one row violating a key constraint, or if a long update query is killed after updating some of the rows. If that happens on the master, the slave thread will exit and wait for the DBA to decide what to do about it unless the error code is legitimate and the query execution results in the same error code. If this error code validation behavior is not desirable, some (or all) errors can be masked out (ignored) with the --slave-skip-errors option. This option is available starting with MySQL Version 3.23.47.
If you update transactional tables from non-transactional tables inside a BEGIN/COMMIT segment, updates to the binary log may be out of sync if some thread changes the non-transactional table before the transaction commits. This is because the transaction is written to the binary log only when it's commited.
Before version 4.0.15, any update to a non-transactional table is written to the binary log at once when the update is made while transactional updates are written on COMMIT or not written at all if you use ROLLBACK; you have to take this into account when updating both transactional tables and non-transactional tables in the same transaction if you are using binary logging for backups or replication. In version 4.0.15, we changed the logging behavior for transactions that mix updates to transactional and non-transactional tables, which solves the problems (order of queries is good in binlog, and all needed queries are written to the binlog even in case of ROLLBACK). The problem which remains is when a second connection updates the non-transactional table while the first connection's transaction is not finished yet (wrong order can still occur, because the second connection's update will be written immediately after it is done).
The following table lists problems in MySQL 3.23 that are fixed in MySQL 4.0:
LOAD DATA INFILE is handled properly, as long as the data file still resides on the master server at the time of update propagation.
LOAD LOCAL DATA INFILE will be skipped.
In 3.23 RAND() in updates does not replicate properly. Use RAND(some_non_rand_expr) if you are replicating updates with RAND(). You can, for example, use UNIX_TIMESTAMP() for the argument to RAND(). This is fixed in 4.0.