Mysql的主从复制详解
一、MYSQL主从复制工作原理主从同步机制:
1、外部数据更新,可以是web服务器,也可以是其他的更新语句。
2、数据增加,删除,更改一系列变化会记录到mysql的binlog中。
3、从服务器上的I/O线程读取主数据库上的binlog日志。
4、拷贝主数据库上的binlog日志到从数据库上的中继日志(relay log)。
5、从数据库上的SQL线程读取中继日志。
6、通过replay中继日志,在从数据库上再执行一遍。
这就是整个主从同步的一个过程。
二、实验步骤
系统:Centos6.4-x86_64
主服务器:node1:172.16.2.1
从服务器:node2:172.16.2.16
Mysql版本:mysql-5.5.33
Mysql的主从复制:
操作思路:
主服务器:
1.创建具有复制权限的用户帐号
2.设置server-id
3.启动二进制日志
从服务器:
1.启动中继日志
2.设置server-id
3.启动复制线程
同步主从服务器时间:用yum安装ansible的rpm包
# vim /etc/ansible/hosts
172.16.2.1
172.16.2.16
# ansible all -a 'ntpdate 172.16.0.1'
172.16.2.16 | success | rc=0 >>
22 Sep 20:40:50 ntpdate: step time server 172.16.0.1 offset 2676.843737 sec
172.16.2.1 | success | rc=0 >>
22 Sep 20:40:50 ntpdate: step time server 172.16.0.1 offset 2675.977884 sec
# ansible all -a 'date'
172.16.2.16 | success | rc=0 >>
Sun Sep 22 20:41:15 CST 2013
172.16.2.1 | success | rc=0 >>
Sun Sep 22 20:41:15 CST 2013
在主从服务器上安装Mysql过程不在介绍,请参考http://pangge.blog.51cto.com/6013757/1059896
安装过程注意文件权限要设置正确
配置主服务器:
1.编译配置文件:
# vim /etc/my.cnf
datadir = /mydata/data/ //数据存放目录
innodb_file_per_table = 1//设置每表单个表空间
log-bin=/mydata/data/mysql-bin //二进制日志存放位置,写绝对路径避免主从复制出现错误
server-id = 1 //server-id的值一定要和从服务器的server-id号区分开来
启动mysql服务
# service mysqld start
Starting MySQL..
2.创建具有复制权限的用户帐号
# mysql
mysql> grant replication client,replication slave on *.* to hailian@'172.16.%.%'>
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
配置从服务器:
1.编辑配置文件
# vim /etc/my.cnf
datadir = /mydata/data/ //数据存放目录
innodb_file_per_table = 1//设置每表单个表空间
log-bin=/mydata/data/mysql-bin //二进制日志存放位置,写绝对路径避免主从复制出现错误
server-id = 20 //server-id的值一定要和从服务器的server-id号区分开来
relay-log=/mydata/data/relay-bin //中继日志
read-only=1 //从服务器设置为只读服务器
2.登录Mysql查看启动线程
# mysql
mysql> show processlist;
+----+------+-----------+------+---------+------+-------+------------------+
|>
+----+------+-----------+------+---------+------+-------+------------------+
|1 | root | localhost | NULL | Query | 0 | NULL| show processlist |
+----+------+-----------+------+---------+------+-------+------------------+
1 row in set (0.00 sec)
mysql> show slave status\G
Empty set (0.00 sec) //说明从服务器还没有开始启用
mysql> help change master to
Name: 'CHANGE MASTER TO'
Description:
Syntax:
CHANGE MASTER TO option [, option] ...
option:
MASTER_BIND = 'interface_name' #将控制绑定到哪个接口上
| MASTER_HOST = 'host_name' #主服务器地址
| MASTER_USER = 'user_name' #具有复制权限的用户
| MASTER_PASSWORD = 'password' #具有复制权限用户的密码
| MASTER_PORT = port_num
| MASTER_CONNECT_RETRY = interval
| MASTER_HEARTBEAT_PERIOD = interval
| MASTER_LOG_FILE = 'master_log_name' #指定从哪一个二进制日志文件开始复制
| MASTER_LOG_POS = master_log_pos #二进制日志事件的位置
|>
|> | MASTER_SSL = {0|1}#是否使用ssl功能
| MASTER_SSL_CA = 'ca_file_name'
| MASTER_SSL_CAPATH = 'ca_directory_name'
| MASTER_SSL_CERT = 'cert_file_name'
| MASTER_SSL_KEY = 'key_file_name'
| MASTER_SSL_CIPHER = 'cipher_list'
| MASTER_SSL_VERIFY_SERVER_CERT = {0|1}
| IGNORE_SERVER_IDS = (server_id_list)
配置从服务器连接主服务器
mysql> change master to master_host='172.16.2.1', -> master_user='hailian',
-> master_password='hailian',
-> master_log_file='mysql-bin.000004',
-> master_log_pos=354;
Query OK, 0 rows affected (0.02 sec)
启动从服务器线程
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.16.2.1
Master_User: hailian
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 354
Relay_Log_File:> Relay_Log_Pos: 253
Relay_Master_Log_File: mysql-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: 354
Relay_Log_Space: 403
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
1 row in set (0.00 sec)
测试
在主服务器上创建数据库testdb
mysql> create database testdb;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
| testdb |
+--------------------+
5 rows in set (0.00 sec)
从服务器上进行查看
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
| testdb |
+--------------------+
5 rows in set (0.00 sec)
验证成功,实现了主从复制
三、如何在主服务器运行了一段时间后,实现主从复制
对从服务器从新进行初始化,其他配置不变
# service mysqld stop
Shutting down MySQL.
# ./scripts/mysql_install_db --user=mysql --datadir=/mydata/data/
# chown -R mysql.mysql ./*
# service mysqld start
Starting MySQL..
首先在主服务器上完全备份数据,然后将数据导入到从服务器上
在主服务器上进行完全备份
# mysqldump -uroot --lock-all-tables --master-data=2 --events --all-databases > /root/all.sql
将备份好的数据复制到从服务器上
# scp /root/all.sql node2:/tmp
all.sql
将数据导入到从服务器的mysql中
mysql> source /tmp/all.sql;
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
| testdb |
+--------------------+
5 rows in set (0.00 sec)
此时查看主服务器上二进制日志文件及其事件位置
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000005 | 182 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
mysql> show grants for hailian@'172.16.%.%';
+-------------------------------------------------------------------------------------------------------------------------------------------------+
| Grants for hailian@172.16.%.% |
+-------------------------------------------------------------------------------------------------------------------------------------------------+
| GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'hailian'@'172.16.%.%'>
+-------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
在从服务器上配置连接主服务器
mysql> show slave status;
Empty set (0.00 sec)
mysql> change master to master_host='172.16.2.1',
-> master_user='hailian',
-> master_password='hailian',
-> master_log_file='mysql-bin.000005',
-> master_log_pos=182;
Query OK, 0 rows affected (0.01 sec)
启动从服务器
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
查看从服务器状态
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.16.2.1
Master_User: hailian
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000005
Read_Master_Log_Pos: 182
Relay_Log_File:> Relay_Log_Pos: 253
Relay_Master_Log_File: mysql-bin.000005
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: 182
Relay_Log_Space: 403
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
1 row in set (0.00 sec)
测试
在主服务上做一下修改
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
| testdb |
+--------------------+
5 rows in set (0.00 sec)
mysql> use testdb;
Database changed
mysql> create table tb1(id int);
Query OK, 0 rows affected (0.03 sec)
mysql> insert into tb1 values (1),(2);
Query OK, 2 rows affected (0.00 sec)
Records: 2Duplicates: 0Warnings: 0
mysql> select * from tb1;
+------+
|>
+------+
| 1 |
| 2 |
+------+
2 rows in set (0.04 sec)
查看从服务器
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
| testdb |
+--------------------+
5 rows in set (0.00 sec)
mysql> use testdb;
Database changed
mysql> show tables
-> ;
+------------------+
| Tables_in_testdb |
+------------------+
| tb1 |
+------------------+
1 row in set (0.00 sec)
mysql> select * from tb1;
+------+
|>
+------+
| 1 |
| 2 |
+------+
2 rows in set (0.03 sec)
验证成功,实现了主从复制
四、如何实现半同步复制
1、分别在主从节点上安装相关的插件
主节点上:
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
Query OK, 0 rows affected (0.02 sec)
mysql> show global variables like '%semi%';
+------------------------------------+-------+
| Variable_name | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled | OFF |
| rpl_semi_sync_master_timeout | 10000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_no_slave | ON |
+------------------------------------+-------+
4 rows in set (0.00 sec)
从节点上:
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Query OK, 0 rows affected (0.06 sec)
mysql> show global variables like '%semi%';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | OFF |
| rpl_semi_sync_slave_trace_level | 32 |
+---------------------------------+-------+
2 rows in set (0.00 sec)
2、启用半同步复制
在主服务上
mysql> SET GLOBAL rpl_semi_sync_master_enabled = ON;
Query OK, 0 rows affected (0.00 sec)
在从服务器上
mysql> SET GLOBAL rpl_semi_sync_slave_enabled = ON;
Query OK, 0 rows affected (0.00 sec)
mysql> stop slave;
Query OK, 0 rows affected (0.02 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
3、确认半同步功能已经启用
在主服务上
mysql> show global status like '%semi%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 1 |
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_net_wait_time | 0 |
| Rpl_semi_sync_master_net_waits | 0 |
| Rpl_semi_sync_master_no_times | 0 |
| Rpl_semi_sync_master_no_tx | 0 |
| Rpl_semi_sync_master_status | ON |
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 0 |
| Rpl_semi_sync_master_tx_wait_time | 0 |
| Rpl_semi_sync_master_tx_waits | 0 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 0 |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)
在从服务上
mysql> show global status like '%semi%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON |
+----------------------------+-------+
1 row in set (0.00 sec)
测试
在主服务上
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
| testdb |
+--------------------+
5 rows in set (0.00 sec)
mysql> use testdb;
Database changed
mysql> create table tb2(name char(10));
Query OK, 0 rows affected (0.07 sec)
在从服务器上查看
mysql> use testdb;
Database changed
mysql> show tables;
+------------------+
| Tables_in_testdb |
+------------------+
| tb1 |
| tb2 |
+------------------+
2 rows in set (0.00 sec)
mysql> desc tb2;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| name| char(10) | YES| | NULL | |
+-------+----------+------+-----+---------+-------+
1 row in set (0.00 sec)
在主服务器上
mysql> show global status like '%semi%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 1 |
| Rpl_semi_sync_master_net_avg_wait_time | 398 |
| Rpl_semi_sync_master_net_wait_time | 398 |
| Rpl_semi_sync_master_net_waits | 1 |
| Rpl_semi_sync_master_no_times | 0 |
| Rpl_semi_sync_master_no_tx | 0 |
| Rpl_semi_sync_master_status | ON |
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 293 |
| Rpl_semi_sync_master_tx_wait_time | 293 |
| Rpl_semi_sync_master_tx_waits | 1 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 1 |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)
mysql> insert into tb2 values ('hailian');
Query OK, 1 row affected (0.00 sec)
mysql> show global status like '%semi%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 1 |
| Rpl_semi_sync_master_net_avg_wait_time | 439 |
| Rpl_semi_sync_master_net_wait_time | 879 |
| Rpl_semi_sync_master_net_waits | 2 |
| Rpl_semi_sync_master_no_times | 0 |
| Rpl_semi_sync_master_no_tx | 0 |
| Rpl_semi_sync_master_status | ON |
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 293 |
| Rpl_semi_sync_master_tx_wait_time | 293 |
| Rpl_semi_sync_master_tx_waits | 1 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 2 |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)
操作完成
注意要想实现半同步复制的永久有效,需要编辑配置文件,将设置的参数放到配置文件/etc/my.cnf中
五、基于ssl的mysql主从复制
在主服务器上自建CA,然后分为为主从服务器颁发证书,详细操作过程请参考http://lanlian.blog.51cto.com/6790106/1281720在这里就不再介绍
讲解配置过程
在主服务器上开启ssl功能
在字段中添加如下内容
ssl
ssl_ca = /etc/pki/CA/cacert.pem
ssl_cert = /usr/local/mysql/ssl/master.crt
ssl_key = /usr/local/mysql/ssl/master.key
重启服务后验证ssl是否开启成功
mysql> show global variables like '%ssl%';
+---------------+---------------------------------+
| Variable_name | Value |
+---------------+---------------------------------+
| have_openssl| YES |
| have_ssl | YES |
| ssl_ca | /etc/pki/CA/cacert.pem |
| ssl_capath | |
| ssl_cert | /usr/local/mysql/ssl/master.crt |
| ssl_cipher | |
| ssl_key | /usr/local/mysql/ssl/master.key |
+---------------+---------------------------------+
7 rows in set (0.00 sec)
注意无论在master服务器还是在slave服务器上一定要修改ssl目录及其文件的属主属组为mysql
在主服务器上创建允许ssl连接的用户
mysql> grant replication client,replication slave on *.* to lanlian@172.16.2.16> Query OK, 0 rows affected (0.03 sec)
从服务器上开启ssl功能
port = 3306
socket = /tmp/mysql.sock
skip-external-locking
key_buffer_size = 256M
max_allowed_packet = 1M
table_open_cache = 256
sort_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 4M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size= 16M
# Try number of CPU's*2 for thread_concurrency
thread_concurrency = 8
datadir = /mydata/data
innodb_file_per_table = 1
ssl
验证ssl是否开启成功
mysql> show global variables like '%ssl%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| have_openssl| YES |
| have_ssl | YES |
| ssl_ca | |
| ssl_capath | |
| ssl_cert | |
| ssl_cipher | |
| ssl_key | |
+---------------+-------+
7 rows in set (0.01 sec)
从服务器连接主服务器
mysql> change master tomaster_host='172.16.2.1', -> master_user='lanlian',
-> master_password='redhat',
-> master_log_file='mysql-bin.000004',
-> master_ssl=1,
->master_ssl_ca='/usr/local/mysql/ssl/cacert.pem',
->master_ssl_cert='/usr/local/mysql/ssl/slave.crt',
-> master_ssl_key='/usr/local/mysql/ssl/slave.key';
mysql> show slave status\G
*************************** 1.row ***************************
Slave_IO_State:
Master_Host: 172.16.18.7
Master_User: rpssl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 4
Relay_Log_File:relay-mysql.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: mysql-bin.000004
Slave_IO_Running: No
Slave_SQL_Running: No
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: 4
Relay_Log_Space: 107
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: Yes
Master_SSL_CA_File:/usr/local/mysql/ssl/cacert.pem
Master_SSL_CA_Path:
Master_SSL_Cert:/usr/local/mysql/ssl/slave.crt
Master_SSL_Cipher:
Master_SSL_Key:/usr/local/mysql/ssl/slave.key
Seconds_Behind_Master: NULL
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: 0
8、启动从服务器线程:
mysql> start slave;
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.16.2.1
Master_User: lanlian
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 362
Relay_Log_File:> Relay_Log_Pos: 508
Relay_Master_Log_File: mysql-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: 362
Relay_Log_Space: 660
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: Yes
Master_SSL_CA_File: /usr/local/mysql/ssl/cacert.pem
Master_SSL_CA_Path:
Master_SSL_Cert:/usr/local/mysql/ssl/slave.crt
Master_SSL_Cipher:
Master_SSL_Key: /usr/local/mysql/ssl/slave.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
#mysql --ssl-ca=/usr/local/mysql/ssl/cacert.pem--ssl-cert=/usr/local/mysql/ssl/slave.crt--ssl-key=/usr/local/mysql/ssl/slave.key-urpssl -h172.16.2.1 –predhat
mysql> \s
--------------
mysqlVer 14.14 Distrib5.5.33, for linux2.6 (x86_64) using readline 5.1
Connection>
Current database:
Current user: lanlian@node2.magedu.com
SSL: Cipher inuse is DHE-RSA-AES256-SHA #基于ssl已可用
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server version: 5.5.33-logMySQL Community Server (GPL)
Protocol version: 10
Connection: 172.16.2.1via TCP/IP
Server characterset: latin1
Db characterset: latin1
Client characterset: utf8
Conn.characterset: utf8
TCP port: 3306
Uptime: 29 min 24sec
Threads: 3Questions:14Slow queries: 0Opens: 33 Flush tables: 1Open tables:26Queries per second avg: 0.007
操作完成!
总结:以上是Mysql主从复制操作过程,深刻理解,熟练操作是非常必要的,不足之处多多指点!
页:
[1]