mysql的复制特性_MySQL学习笔记十七:复制特性

一、MySQL的复制是将主数据库(master)的数据复制到从(slave)数据库上,专业一点讲就是将主数据库DDL和DML操作的二进制日志传到从库上,然后从库对这些二进制日志进行重做,使得主数据库与从数据库的数据保持同步。

二、MySQL复制的一些优点:

可以将大部分的查询任务放在从库上进行,降低主库的负载,提高性能,但要注意实时性要求高的数据仍需在主库上读取。

如果主库出现了宕机,可以快速切换到从库上,提高了可用性。

可以在从库上进行数据备份,降低在备份期间对主库的影响。

将数据挖掘和分析等工作放在从库上进行,可以降低对主库的性能影响。

三、MySQL复制处理数据的三种模式:

基于语句复制:也称为SBR(Statement Based Replication),基于实际执行的SQL语句来进行复制的方案,BINLOG_FORMAT=STATEMENT。

基于行的复制:也叫RBR(Row Bases Replication),BINLOG_FORMAT=ROW。

混合复制模式:也成MBR,基于SQL语句复制和行的复制,BINLOG_FORMAT=MIXED。

查看二进制日志的格式:

mysql> show global variables like 'binlog_format';+---------------+-----------+

| Variable_name | Value | ---value的值有三种:statement,row,mixed

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

| binlog_format | STATEMENT |

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

1 row in set (0.00 sec)

设置二进制日志的格式:

mysql> set global binlog_format='row'; --设置全局binlog_format,可以使用set session binlog_format='row'来设置当前会话的binlog_format

Query OK,0 rows affected (0.00sec)

mysql> show GLOBAL variables like 'binlog_format';+---------------+-------+

| Variable_name | Value |

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

| binlog_format | ROW |

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

1 row in set (0.00 sec)

在SQL中查看日志文件中的事件:

mysql> show binlog events in 'mysql-bin.000027' from 107; --from指定从日志哪个位置开始

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

| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |

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

| mysql-bin.000027 | 107 | Query | 3306 | 175 | BEGIN |

| mysql-bin.000027 | 175 | Query | 3306 | 264 | use `test`; insert into t1 values (10) |

| mysql-bin.000027 | 264 | Query | 3306 | 333 | COMMIT |

| mysql-bin.000027 | 333 | Query | 3306 | 401 | BEGIN |

| mysql-bin.000027 | 401 | Query | 3306 | 495 | use `test`; update t1 set id=70 where id=60 |

| mysql-bin.000027 | 495 | Query | 3306 | 564 | COMMIT |

| mysql-bin.000027 | 564 | Stop | 3306 | 583 | |

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

7 rows in set (0.00 sec)

基于SQL语句的二进制日志记录原始SQL操作,而基于ROW格式的二进制日志记录的是每行数据的变更,采用64位编码,使用mysqlbinlog查看时须搭配--base64-output='decode-rows' --vv参数来解码查看。

四、MySQL复制流程

MySQL复制基于二进制日志,开启二进制日志功能是必须的。当从库启动复制时(start slave),首先创建一个I/O线程连接主库,主库接着创建Binlog Dump线程读取二进制日志事件发送给从库的I/O线程,I/O线程获取数据后更新从库的中继日志Relay Log,然后从库的SQL线程读取中继日志中更新的数据库事件并应用,如下图所示:

60b6a5dd80631dd8e8f8b923fc49fe7b.png

可以使用SHOW PROCESSLIST命令在主库和从库上分别执行,查看主库BINLOG DUMP线程和从库SQL线程状态:

----------------------在主库上-------------

mysql>show processlist\G*************************** 3. row ***************************Id:18

User: repl

Host: localhost:2275db:NULLCommand: BinlogDumpTime:76State: Master has sentall binlog to slave; waiting for binlog tobe updated

Info:NULL

3 rows in set (0.00sec)--------------------在从库上---------------

*************************** 2. row ***************************Id:27

User: system userHost:

db:NULLCommand: Connect

Time:301State: Waitingfor master tosend event

Info:NULL

*************************** 3. row ***************************Id:28

User: system userHost:

db:NULLCommand: Connect

Time:246703State: Slave hasread all relay log; waiting for the slave I/O thread to updateit

Info:NULL

五、搭建复制环境

由于本人苦逼学生一枚,只有一台电脑,所以只能在一台电脑上开启多个MySQL服务,开启过程如下所示:

1.停止mysql服务

2.copymysql安装目录到指定目录E:\,这里随意,不要和原目录重叠即可

3.copy mysql data数据文件到E:\data

4.copy一份my.ini文件到上面指定的目录下

5.修改复制后的配置文件my.ini,内容如下:

[client]

port=3307 #第一个数据库的默认端口是3306 这里需要另外启用一个端口

# The TCP/IP Port the MySQL Server will listen on

port=3307

# Path to installation directory. All paths are usually resolved relative to this.

basedir="E:\MySQL\MySQL Server 5.5\"         #第二个数据库basedir

# Path to the database root

datadir="E:\MySQL\MySQL Server 5.5\data\"    #第二个数据库datadir

6.创建新的mysql服务

mysqld install MySQLSLAVE  --defaults-file="E:\MySQL\MySQL Server 5.5\my.ini"

7.修改注册表,如下:

KEY_LOCAL_MACHINE-->SYSTEM-->CurrentControlSet-->Services

找到刚才创建的MySQLSLAVE,将ImagePath修改成如下":

"E:\MySQL\MySQL Server 5.5\bin\mysqld" --defaults-file="E:\MySQL\data\my.ini" mysqlsalve

复制环境搭建过程如下:

1.修改主数据库的配置文件my.ini,修改内容如下:

server-id=3306#主从复制是通过二进制文件来进行,所以要开启日志功能log-bin=mysql-bin

#主机,读写都可以read-only=0#需要备份数据,多个写多行

binlog-do-db=test

#不需要备份的数据库,多个写多行

binlog-ignore-db=mysql

2.修改从数据库的配置文件my.ini,修改内容如下:

#主从配置

server-id=3307

log-bin=mysql-bin

#如果从服务器发现主服务器断掉,重新连接的时间差(秒)

#master-connect-retry=60#只复制某个库replicate-do-db=test

#不复制某个库replicate-ignore-db=mysql

3.保持主从的test库初始状态一致

mysql> flush tables with readlock;

Query OK,0 rows affected (0.05sec)---首先锁定表为读有效,防止数据库有更新操作,然后利用COPY/CP命令将数据文件目录复制到从库数据目录下---或者直接关闭mysql服务,手动复制数据文件目录到指定目录下

---拷贝完后,恢复写操作

mysql> unlock tables;

Query OK, 0 rows affected (0.00 sec)

4.在主库上创建一个专门用来复制的用户repl

mysql> GRANT REPLICATION SLAVE ON *.* TO 'REPL'@'127.0.0.1' IDENTIFIED BY '1234567';

Query OK,0 rows affected (0.31 sec)

5.重启主库,然后执行show master status,记下file和position字段对应的参数

mysql>show master status;+------------------+----------+--------------+------------------+

| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |

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

| mysql-bin.000031 | 262 | test | mysql |

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

1 row in set (0.00 sec)

6、在从库设置它的master:

mysql> change master to master_host='127.0.0.1',master_port=3306,master_user='repl',master_password='asdf',master_log_file='mysql-bin.000031',master_log_pos=262;

Query OK,0 rows affected (0.19sec)----这里的master_log_file和master_log_pos对应刚才show master status记下的参数。

7.在从库上开启复制start slave

mysql>start slave;

Query OK,0 rows affected, 1 warning (0.00 sec) --这里有个warning,是因为我已经开启了slave

8.验证复制搭建是否成功

mysql>show processlist\G;*************************** 2. row ***************************Id:27

User: system userHost:

db:NULLCommand: Connect

Time:6349State: Waitingfor master tosend event

Info:NULL

*************************** 3. row ***************************Id:28

User: system userHost:

db:NULLCommand: Connect

Time:580State: Slave hasread all relay log; waiting for the slave I/O thread to updateit

Info:NULL

3 rows in set (0.00sec)----以上信息表名slave已经连上了master,并开始接收和执行日志---

9.使用show slave status来查看slave信息

mysql>show slave status\G*************************** 1. row ***************************Slave_IO_State: Waitingfor master tosend event

Master_Host:127.0.0.1Master_User: repl

Master_Port:3306Connect_Retry:60Master_Log_File: mysql-bin.000031Read_Master_Log_Pos:262Relay_Log_File: Lenovo-PC-relay-bin.000059Relay_Log_Pos:408Relay_Master_Log_File: mysql-bin.000031Slave_IO_Running: Yes --I/O线程已开启

Slave_SQL_Running: Yes --SQL线程也开启

Replicate_Do_DB: test

Replicate_Ignore_DB: mysql

Replicate_Do_Table:

Replicate_Ignore_Table:

Replicate_Wild_Do_Table:

Replicate_Wild_Ignore_Table:

Last_Errno:0Last_Error:

Skip_Counter:0Exec_Master_Log_Pos:262Relay_Log_Space:714Until_Condition: None

Until_Log_File:

Until_Log_Pos:0Master_SSL_Allowed: No

Master_SSL_CA_File:

Master_SSL_CA_Path:

Master_SSL_Cert:

Master_SSL_Cipher:

Master_SSL_Key:

Seconds_Behind_Master:0Master_SSL_Verify_Server_Cert: No

Last_IO_Errno:0 --I/O没有错误Last_IO_Error:

Last_SQL_Errno:0 --sql应用也没有错误Last_SQL_Error:

Replicate_Ignore_Server_Ids:

Master_Server_Id:3306

1 row in set (0.00 sec)

10.验证复制的正确性

-------在主库上的test库创建表cc------

mysql> create table cc (id int not null);

Query OK,0 rows affected (0.10sec)

mysql> insert into cc values (10),(20);

Query OK,2 rows affected (0.00sec)

Records:2 Duplicates: 0 Warnings: 0

-------在从库上查看是否存在表cc-----

mysql> show tables like 'cc';+---------------------+

| Tables_in_test (cc) |

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

| cc |

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

1 row in set (0.00sec)

mysql> select * fromcc;+----+

| id |

+----+

| 10 |

| 20 |

+----+

2 rows in set (0.00sec)------------说明复制搭建已经成功------

六、半同步复制

MySQL复制默认采用异步的同步机制,主库和从库的数据之间存在一定的延时,不能保证数据的一致性和及时性。因此有必要开启半同步复制,而半同步复制模式是由mysql插件来实现,主从库使用不同的插件(semisync_master.so/semisync_slave.so),安装插件如下所示。

检查mysql服务是否支持动态加载插件

mysql> show variables like '%dynamic_loading%';+----------------------+-------+

| Variable_name | Value |

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

| have_dynamic_loading | YES |

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

1 row in set (0.00sec)----也可以直接执行select @@have_dynamic_loading

安装插件

mysql> install plugin rpl_semi_sync_master soname 'semisync_master.dll';

ERROR1125 (HY000): Function 'rpl_semi_sync_master' already exists --我已经安装了该插件

查看插件安装是否成功

mysql> select * frommysql.plugin;+----------------------+---------------------+

| name | dl |

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

| rpl_semi_sync_master | semisync_master.dll |

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

1 row in set (0.03 sec)

从库也使用同样的方法安装semisync_slave插件

mysql> select * frommysql.plugin;+---------------------+--------------------+

| name | dl |

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

| rpl_semi_sync_slave | semisync_slave.dll |

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

1 row in set (0.00 sec)

打开半同步复制,因为mysql默认是关闭的

mysql> show variables like '%semi_sync%';+------------------------------------+-------+

| 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 |

+------------------------------------+-------+---------主库------

mysql> set global rpl_semi_sync_master_enabled=on;

Query OK,0 rows affected (0.01sec)---------从库-------------

mysql> set global rpl_semi_sync_slave_enabled=on;

Query OK,0 rows affected (0.00sec)----重启I/O线程

mysql>stop slave io_thread;

Query OK,0 rows affected (0.01sec)

mysql>start slave io_thread;

Query OK,0 rows affected (0.00 sec)

半同步复制配置完毕后,查看半同步复制的状态信息,在主库上执行show global status like '%semi_sync%';

mysql> show global status like '%semi_sync%';+--------------------------------------------+-------+

| 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 variables like '%semi%time%';+------------------------------+-------+

| Variable_name | Value |

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

| rpl_semi_sync_master_timeout | 10000 | --10s

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

1 row in set (0.00 sec)

七、MySQL复制主要启动参数

1.master_host,master_port,master_user,master_password这些参数主要用来记录需要复制的主库的地址,端口,用户,密码等信息,就不具体介绍了。

2.log_slave_updates:用来指定从库的更新操作是否记录到二进制日志中去,如果要搭建的是主-主复制,则该参数必须指定为ON(set global log_slave_updates=on或在配置文件中永久启动)

3.read-only:用来限制普通用户对从库的更新操作,只接收超级用户的更新操作。

4.master_connect_retry:指定当和主库丢失连接时重试的时间间隔,默认为60。

5.replicate_do_db,replicate_ignore_db,replicate_do_table,replicate_ignore_table:这些参数用来指定复制的数据库或表,比如指定复制的表为replicate_do_table=test.cc,其他的表则不会复制。

6.slave_skip_errors:用来指定从库复制中可以跳过的错误号或跳过全部错误,slave_skip_errors=[err_code1,err_code2...|all]

7.master_delay:用来指定延时复制的时间隔间

八、复制的管理维护

1.查看从库状态

mysql>show slave status\G*************************** 1. row ***************************Slave_IO_State: Waitingfor master tosend event

Master_Host:127.0.0.1Master_User: repl

Master_Port:3306Connect_Retry:60Master_Log_File: mysql-bin.000031Read_Master_Log_Pos:736Relay_Log_File: Lenovo-PC-relay-bin.000060Relay_Log_Pos:442Relay_Master_Log_File: mysql-bin.000031Slave_IO_Running: Yes

Slave_SQL_Running: Yes

Replicate_Do_DB: test

Replicate_Ignore_DB: mysql

Replicate_Do_Table:

Replicate_Ignore_Table:

Replicate_Wild_Do_Table:

Replicate_Wild_Ignore_Table:

----截取部分信息

2.主库和从库同步

-----在主库上执行-----

mysql> flush tables with readlock;

Query OK,0 rows affected (0.00sec)-----在从库上执行-----

mysql> select master_pos_wait('mysql-bin.000031','736');+--------------------------------------------+

| master_pos_wait('mysql-bin.000031','736') |

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

| 0 |

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

1 row in set (0.03sec)--master_pos_wait的参数值可以在主库执行show master status得到--该select语句会阻塞到从库达到指定的日志文件的偏移量后,返回0,表示与主库同步了--完了之后在主库上执行unlock tables

3.从库复制出现错误

在从库应用中继日志时,可能会出现一些错误,例如表结构不对,函数不存在等,如果是不太重要的错误,则可使用sql_slave_skip_counter变量来忽略更新失败的语句。示例如下:

mysql>stop slave;

Query OK,0 rows affected (0.02sec)

mysql> set global sql_slave_skip_counter=1;----如果是autoincrement或last_insert_id()则为2

mysql>start slave;

Query OK,0 rows affected (0.00 sec)

4.主-主复制时自增变量冲突的问题

主-主复制需要定制auto_increment_increnment和auto_increment_offset的值来避免重复冲突,这两个变量的值默认为1,这也是重复冲突的源头

mysql> show variables like 'auto_increment_%';+--------------------------+-------+

| Variable_name | Value |

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

| auto_increment_increment | 1 |

| auto_increment_offset | 1 |

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

2 rows in set (0.00 sec)

采用以下的设置可以避免重复

master1:auto_increment_increment=2,auto_increment_offset=1master1:auto_increment_increment=2,auto_increment_offset=0

5.提高复制性能

方案一:采用一主多从的复制架构,利用replicate_do_db,replicate_ignore_db等参数使得不同的从库复制不同的库/表,降低每个从库的写入压力。

方案二:利用5.6版本的多线程并发复制,通过设置变量slave_parallel_workers来实现。

stop slaveset global slave_parallel_works=2;

start slave;---或者在my.ini中天加slave_parallel_workers=2

6.主从切换

1.在每个从库上执行stop slave io_thread,停止接收日志,接着执行show processlist,如果state字段值为Has read all relay log,表示更新都应用完毕。

2.在需要提升为主库的从库上执行stop slave,reset slave和reset master,将从库重置成主库。

3.其他的从库执行都执行stop slave,然后执行change master to master_host=新的主库地址。

4.所有应用指向新的主库。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值