MySQL5.6主从复制(读写分离)教程

1、MySQL5.6开始主从复制有两种方式:

基于日志(binlog);

基于GTID(全局事务标示符)。

需要注意的是:GTID方式不支持临时表!所以如果你的业务系统要用到临时表的话就不要考虑这种方式了,至少目前最新版本MySQL5.6.12的GTID复制还是不支持临时表的。

所以本教程主要是告诉大家如何通过日志(binlog)方式做主从复制!

2、MySQL官方提供的MySQL Replication教程:

 http://dev.mysql.com/doc/refman/5.6/en/replication.html

第一步:准备工作

主服务器: 192.168.1.100

从服务器: 192.168.1.101

MySQL软件版本

MySQL-server-advanced-5.6.18-1.el6.x86_64.rpm

MySQL-cient-advanced-5.6.18-1.el6.x86_64.rpm

第二步:在主服务器和从服务器上安装MySQL数据库软件

安装方法,请参见 

RedHat6.5下MySQL5.6集群配置完整版  http://www.linuxidc.com/Linux/2014-06/103748.htm 


MySQL数据库软件安装完成后,不要急着做mysql启动操作。建议把mysql初始化生成的/usr/my.cnf

(如果是从源文件编译安装时,路径应该是在/usr/local/mysql/mysql.cnf)删除,然后把优化好的mysql

配置文件my.cnf放到/etc下。 

第三步:修改主数据库的配置文件/usr/my.cnf 

[mysqld]

server-id=1

log-bin=mysqlmaster-bin.log

sync_binlog=1

 


innodb_buffer_pool_size=512M

innodb_flush_log_at_trx_commit=1

 


sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

 


lower_case_table_names=1

log_bin_trust_function_creators=1

第四步:修改从数据库配置文件/usr/my.cnf

 


server-id=2

log-bin=mysqlslave-bin.log

sync_binlog=1

innodb_buffer_pool_size=512M

innodb_flush_log_at_trx_commit=1

 


sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

lower_case_table_names=1

log_bin_trust_function_creators=1

第五步:在主数据库和从数据库服务器上分别执行以下命令重新启动主数据库和从数据库

[root@master ~]# service mysql restart

[root@slave ~]# service mysql restart

 


第六步:在主数据库上创建用于主从复制的账户

[root@master ~]# mysql -uroot -p

mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.101' IDENTIFIED BY '111111';

Query OK, 0 rows affected (0.00 sec)

 


注意:以上命令中的IP地址,是从数据库服务器的IP地址。

第七步:主数据库锁表(禁止再插入数据以获取主数据库的的二进制日志坐标)

mysql> flush tables with read lock;

Query OK, 0 rows affected (0.00 sec)

 


第八步:查看主数据库的状态(并记录下File字段和Position字段的值,在配置从服务器时有用到)

mysql> show master status;

+------------------------+----------+--------------+------------------+-------------------+

| File                  | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+------------------------+----------+--------------+------------------+-------------------+

| mysqlmaster-bin.000004 |      327 |              |                  |                  |

+------------------------+----------+--------------+------------------+-------------------+

1 row in set (0.00 sec)

第九步:创建主数据库的快照文件

[root@master ~]# cd /usr/bin/

# ./mysqldump -uroot -p -h127.0.0.1 -P3306 --all-databases --triggers --routines --events >>/mnt/windows/all.sql

上面命令中的红色部分,是一个共享目录,这个目录可以同时被主数据库服务器和从数据库服务器访问到。

如果没有这样的共享目录,可以将all.sql放在其它任何目录下,然后使用scp命令复制到远程从数据库服务器的某个目录中

这条命令的执行时间根据数据量的不同,会有所不同,如果主数据库的数据量很大,可能需要很长时间,那么在这种情况下,就最好在晚上没有业务的时候进行这个操作,否则第七步中的锁表操作会对业务系统造成很大的影响

第十步:解锁主数据库的锁表操作

[root@master ~]# mysql -uroot -p    (本命令在主数据库服务器上执行)

mysql> unlock tables;

Query OK, 0 rows affected (0.00 sec)

第十一步:在从数据库服务器上导入第七步创建的快照文件到从数据库中

[root@slave ~]# mysql -uroot -p -h127.0.0.1 -P3306 < /mnt/windows/all.sql

第十二步:在从数据库服务器上设置主数据库服务器向从数据库服务器同步

[root@slave ~]# mysql -uroot -p

mysql> change master to master_host = '192.168.1.100',master_user='repl',master_password='111111',master_log_file='mysqlmaster-bin.000004',master_log_pos=327;

注意:红色部分的值,是在第八步中查出来的,这里不能弄错了

第十三步:启动从数据库复制线程

mysql> start slave;

Query OK, 0 rows affected (0.01 sec)

第十四步:查询从数据库的复制线程状态

mysql> show slave status \G

*************************** 1. row ***************************

              Slave_IO_State: Waiting for master to send event

                  Master_Host: 192.168.1.100

                  Master_User: repl

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: mysqlmaster-bin.000004

          Read_Master_Log_Pos: 327

  Relay_Log_File: slave-relay-bin.000002

                Relay_Log_Pos: 289

        Relay_Master_Log_File: mysqlmaster-bin.000004

          Slave_IO_Running: Yes

        Slave_SQL_Running: Yes

              Replicate_Do_DB:

          Replicate_Ignore_DB:

          Replicate_Do_Table:

      Replicate_Ignore_Table:

      Replicate_Wild_Do_Table:

  Replicate_Wild_Ignore_Table:

                  Last_Errno: 0

                  Last_Error:

                Skip_Counter: 0

  Exec_Master_Log_Pos: 327

              Relay_Log_Space: 462

              Until_Condition: None

              Until_Log_File:

                Until_Log_Pos: 0

          Master_SSL_Allowed: No

          Master_SSL_CA_File:

          Master_SSL_CA_Path:

              Master_SSL_Cert:

            Master_SSL_Cipher:

              Master_SSL_Key:

        Seconds_Behind_Master: 0

Master_SSL_Verify_Server_Cert: No

                Last_IO_Errno: 0

                Last_IO_Error:

              Last_SQL_Errno: 0

              Last_SQL_Error:

  Replicate_Ignore_Server_Ids:

            Master_Server_Id: 1

                  Master_UUID: 2e5e1b22-f0a9-11e3-bbac-000c297799e0

            Master_Info_File: /var/lib/mysql/master.info

                    SQL_Delay: 0

          SQL_Remaining_Delay: NULL

      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it

          Master_Retry_Count: 86400

                  Master_Bind:

      Last_IO_Error_Timestamp:

    Last_SQL_Error_Timestamp:

              Master_SSL_Crl:

          Master_SSL_Crlpath:

          Retrieved_Gtid_Set:

            Executed_Gtid_Set:

                Auto_Position: 0

1 row in set (0.00 sec)

如果Slave_IO_Running和Slave_SQL_Running两项都为yes,就表示主从复制配置成功了.

下面可以开始测试配置是否成功了,首先在主数据库的test数据库中新建一张表,然后插入几条数据,然后到从数据库看看是否同步过来了。

注意:当从数据库有大量的查询时,可以暂时将从数据库的复制线程关闭掉,等查询量降下来了,再打开,这样也不会丢失数据。

附:一个优化好后的主数据库配置文件和从数据配置文件内容如下:

# For advice on how to change settings please see

# http://dev.mysql.com/doc/refman/5.6/en/server-configuration-defaults.html

[client]

port=3306

socket=/usr/local/mysql/mysql.sock

default-character-set=utf8

[mysqld]

sync_binlog=1

server-id=1

port=3306

socket=/usr/local/mysql/mysql.sock

pid-file=/home/mysql/temp/my3306.pid

user=mysql

datadir=/home/mysql/data

tmpdir=/home/mysql/temp/

log-bin=/home/mysql/data/mysqlmaster-bin

log-error=/home/mysql/logs/error.log

slow_query_log_file=/home/mysql/logs/slow.log

binlog_format=mixed

slow_query_log

long_query_time=10

wait_timeout=31536000

interactive_timeout=31536000

max_connections=500

max_user_connections=490

max_connect_errors=2

character_set_server=utf8

skip-external-locking

key_buffer_size = 128M

max_allowed_packet = 5M

table_open_cache = 512

sort_buffer_size = 2M

read_buffer_size = 2M

read_rnd_buffer_size = 8M

myisam_sort_buffer_size = 64M

thread_cache_size = 8

query_cache_size = 32M

# Try number of CPU's*2 for thread_concurrency

thread_concurrency = 4

binlog-ignore-db=mysql

binlog-ignore-db=information_schema

replicate_ignore_db=mysql

replicate_ignore_db=information_schema

expire-logs-days=10

skip-slave-start

skip-name-resolve

lower_case_table_names=1

log_bin_trust_function_creators=1

# InnoDB

innodb_data_home_dir=/home/mysql/data

innodb_log_group_home_dir=/home/mysql/logs

innodb_data_file_path=ibdata1:128M:autoextend

innodb_buffer_pool_size=2G

innodb_log_file_size=10M

innodb_log_buffer_size=8M

innodb_lock_wait_timeout=50

innodb_file_per_table

innodb_flush_log_at_trx_commit=1

#sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

 

 

 

 


一个优化好的从数据库的配置文件如下:

# For advice on how to change settings please see

# http://dev.mysql.com/doc/refman/5.6/en/server-configuration-defaults.html

[client]

port=3306

socket=/usr/local/mysql/mysql.sock

default-character-set=utf8

 

[mysqld]

sync_binlog=1

server-id=2

port=3306

socket=/usr/local/mysql/mysql.sock

pid-file=/home/mysql/temp/my3306.pid

user=mysql

datadir=/home/mysql/data

tmpdir=/home/mysql/temp/

log-bin=/home/mysql/data/mysqlslave-bin

log-error=/home/mysql/logs/error.log

slow_query_log_file=/home/mysql/logs/slow.log

binlog_format=mixed

slow_query_log

long_query_time=10

wait_timeout=31536000

interactive_timeout=31536000

max_connections=500

max_user_connections=490

max_connect_errors=2

character_set_server=utf8

skip-external-locking

key_buffer_size = 128M

max_allowed_packet = 5M

table_open_cache = 512

sort_buffer_size = 2M

read_buffer_size = 2M

read_rnd_buffer_size = 8M

myisam_sort_buffer_size = 64M

thread_cache_size = 8

query_cache_size = 32M

# Try number of CPU's*2 for thread_concurrency

thread_concurrency = 4

binlog-ignore-db=mysql

binlog-ignore-db=information_schema

replicate_ignore_db=mysql

replicate_ignore_db=information_schema

expire-logs-days=10

#skip-slave-start

skip-name-resolve

lower_case_table_names=1

log_bin_trust_function_creators=1

# InnoDB

innodb_data_home_dir=/home/mysql/data

innodb_log_group_home_dir=/home/mysql/logs

innodb_data_file_path=ibdata1:128M:autoextend

innodb_buffer_pool_size=2G

innodb_log_file_size=10M

innodb_log_buffer_size=8M

innodb_lock_wait_timeout=50

innodb_file_per_table

innodb_flush_log_at_trx_commit=1

 


#sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

sql_mode=STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_AUTO_VALUE_ON_ZERO

[mysqldump]

quick

max_allowed_packet = 16M

 


[mysql]

no-auto-rehash

 


[myisamchk]

key_buffer_size = 256K

sort_buffer_size = 256K

read_buffer = 256K

write_buffer = 256K

[mysqlhotcopy]

interactive-timeout

 

 

 

 


sql_mode=STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_AUTO_VALUE_ON_ZERO

 


[mysqldump]

quick

max_allowed_packet = 16M

 

[mysql]

no-auto-rehash

 


[myisamchk]

key_buffer_size = 256K

sort_buffer_size = 256K

read_buffer = 256K

write_buffer = 256K

 


[mysqlhotcopy]

interactive-timeout