Mysql 主从复制优点

Mysql数据支持数据库的主从复制功能,使用主数据库进行数据的插入,删除与更新操作,

而从数据库则专门来进行数据查询操作,这样可以将更新操作和查询操作分担到不同的数据库上,从而提高了查询效率。

3.Mysql 主从复制原理



The general query log is a general record of what mysqld is doing. The server writes information to this log when clients connect or disconnect,

常规的查询日志是常规的记录,服务器记录客户端的连接和断开信息

 and it logs each SQL statement received from clients.

和从客户端收到的每个语句


 The general query log can be very useful when you suspect an error in a client and want to know exactly what the client sent to mysqld .

通常的查询日志可能是很有用的
当你质疑客户端的错误,想知道确切的客户端发送到mysqld的信息

The binary log contains all statements that update data or potentially could have updated it (for example, aDELETE which matched no rows). 

binary log 包含里所有语句 包括更新数据或者潜在的已经更新的 (比如 delete
匹配了0条记录)

Statements are stored in the form of "events"  that describe the modifications.

语句被存放在events的形式 来描述修改

 The binary log also contains information about how long each statement took that updated data.

 The binary log 也包含了 每个语句消耗用于更新数据的时间



配置binlog:
Mysql BInlog日志格式可以通过mysql的my.cnf文件的属性binlog_format指定。如以下:

binlog_format           = MIXED                 //binlog日志格式

log_bin                  =目录/mysql-bin.log    //binlog日志名

expire_logs_days    = 7                //binlog过期清理时间

max_binlog_size    100m                    //binlog每个日志文件大小

binlog-do-db=需要备份的数据库名,如果备份多个数据库,重复设置这个选项即可
binlog-ignore-db=不需要备份的数据库苦命,如果备份多个数据库,重复设置这个选项即可



  主服务器上面的任何修改会保存在二进制日志文件Binary
log里,从服务器上启动一个I/O thread
进程与主服务器的I/O联系,并请求从指定日志文件的位置之后的内容。当主服务器接收到Slave服务器I/O线程请求后,

通过I/O线程请求信息读取指定日志指定位置之后的日志信息,返回给Slave服务器的I/O线程。在返回的信息中除了日志所包含的信息之外,


还有master端的binary log文件的名称和binary
log中的位置。然后把读取到的二进制日志内容写到本地的一个Realy

log里面,将读取到的master端的bin-log文件名和位置记录到master-info文件中。从服务器上面开启一个SQL

thread 定时检查Realy
log,如果发现有更改立即把更改的内容在本机上面执行一遍。这样就实现了在主服务器上操作,从服务器上实时也跟着操作。


打开主机master的my.cnf,输入

server-id               = 1    #主机标示,整数
log_bin                 = /var/log/mysql/mysql-bin.log   #binlog目录 确保此文件可写
read-only              =0  #主机,读写都可以
binlog-do-db         =test   #需要备份数据,多个写多行
binlog-ignore-db    =mysql #不需要备份的数据库,多个写多行


[root@master etc]# mkdir /var/log/mysql
[root@master etc]# chown -R mysql:mysql /var/log/mysql/

重启Mysql就产生binlog

[root@master etc]# cd /var/log/mysql
[root@master mysql]# ls
mysql-bin.000001  mysql-bin.index


缺省配置:
# read_rnd_buffer_size = 2M 

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES 

server-id               = 1    #主机标示,整数
log_bin                 = /var/log/mysql/mysql-bin.log   #binlog目录 确保此文件可写


mysql> show variables  like 'binlog_format';
+---------------+-----------+
| Variable_name | Value     |
+---------------+-----------+
| binlog_format | STATEMENT |
+---------------+-----------+
1 row in set (0.00 sec)

[mysql@master ~]$ sh viewP.sh | grep log_bin
log_bin	ON
log_bin_basename	/var/log/mysql/mysql-bin
log_bin_index	/var/log/mysql/mysql-bin.index
log_bin_trust_function_creators	OFF
log_bin_use_v1_row_events	OFF
sql_log_bin	ON

1.Statement:每一条会修改数据的sql都会记录在binlog中。

优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO,提高性能。(相比row能节约多少性能与日志量,这个取决于应用的SQL情况,正常同一条记录修改或者插入row格式所产生的日志量还小于Statement产生的日志量,但是考虑到如果带条件的update操作,以及整表删除,alter表等操作,ROW格式会产生大量日志,因此在考虑是否使用ROW格式日志时应该跟据应用的实际情况,其所产生的日志量会增加多少,以及带来的IO性能问题。)

缺点:由于记录的只是执行语句,为了这些语句能在slave上正确运行,因此还必须记录每条语句在执行的时候的一些相关信息,以保证所有语句能在slave得到和在master端执行时候相同 的结果。另外mysql 的复制,像一些特定函数功能,slave可与master上要保持一致会有很多相关问题(如sleep()函数, last_insert_id(),以及user-defined functions(udf)会出现问题).

mysql> SELECT DISTINCT CONCAT('User: ''',user,'''@''',host,''';') AS query FROM mysql.user;
+---------------------------+
| query                     |
+---------------------------+
| User: 'plms'@'%';         |
| User: 'test'@'%';         |
| User: 'root'@'127.0.0.1'; |
| User: 'root'@'::1';       |
| User: ''@'localhost';     |
| User: 'plms'@'localhost'; |
| User: 'root'@'localhost'; |
| User: 'test'@'localhost'; |
| User: ''@'mysql';         |
| User: 'root'@'mysql';     |
+---------------------------+
10 rows in set (0.01 sec)

 创建backup用户:

GRANT REPLICATION SLAVE ON *.* TO 'backup'@'10.10.17.%' IDENTIFIED BY '123456';

mysql> SELECT DISTINCT CONCAT('User: ''',user,'''@''',host,''';') AS query FROM mysql.user;
+------------------------------+
| query                        |
+------------------------------+
| User: 'plms'@'%';            |
| User: 'test'@'%';            |
| User: 'backup'@'10.10.17.%'; |
| User: 'root'@'127.0.0.1';    |
| User: 'root'@'::1';          |
| User: ''@'localhost';        |
| User: 'plms'@'localhost';    |
| User: 'root'@'localhost';    |
| User: 'test'@'localhost';    |
| User: ''@'mysql';            |
| User: 'root'@'mysql';        |
+------------------------------+
11 rows in set (0.00 sec)

[mysql@master ~]$ mysql -ubackup -p123456 -h
Warning: Using a password on the command line interface can be insecure.
mysql: option '-h' requires an argument
[mysql@master ~]$ mysql -ubackup -p123456 -hmaster

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

[mysql@master ~]$ /etc/init.d/mysql restart
Shutting down MySQL....                                    [  OK  ]
rm: cannot remove `/var/lock/subsys/mysql': Permission denied
Starting MySQL.                                            [  OK  ]

查看file 和Position日志点:
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      120 | test,plmsdb  |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)


注意:如果在做主从同步之前数据库有数据,那么这时需要锁表,避免再有新的数据写入。这时就需要备份数据

mysql 从服务器设置:

server-id               = 2    #主机标示,整数
#log_bin                 = /var/log/mysql/mysql-bin.log
#如果该服务器还作为其他从服务器时需要使用



sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES 
server-id               = 2    #主机标示,整数
log_bin                 = /var/log/mysql/mysql-bin.log   #binlog目录 确保此文件可写



克隆的虚拟机删除相应的用户和数据库

mysql> drop database plmsdb;
Query OK, 2 rows affected (0.09 sec)

删除用户:
删除账户及权限:>drop user 用户名@'%';

        >drop user 用户名@ localhost;

mysql> drop user plms@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> drop user plms@slave1;
ERROR 1396 (HY000): Operation DROP USER failed for 'plms'@'slave1'
mysql> drop user plms@localhost;
Query OK, 0 rows affected (0.00 sec)


mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000005 |      120 | test,plmsdb  |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

change master to master_host='10.10.17.5',master_user='backup',master_password='123456',master_log_file='mysql-bin.000005',master_log_pos=120;

start slave; 


Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work.

show slave status\G;

使用rsync配置了大量mysql,省去了大量编译和配置的时间,随逐个修改master和slave服务器的my.cnf,后,发现数据不能同步,
在slave服务器show slave status:

Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work.

首先检查:
mysql> show variables like ‘server_id';
+—————+——-+
| Variable_name | Value |
+—————+——-+
| server_id | 3 |
+—————+——-+

主从并不一样,排除该问题。

继续排查,找到原因在于,拷贝整个data目录,把auto.cnf文件也拷贝过来了,里面记录了数据库的uuid,每个库的uuid应该是不一样的。

[auto]
server-uuid=6dcee5be-8cdb-11e2-9408-90e2ba2e2ea6

解决办法,按照这个16进制格式,随便改下,重启mysql即可。

1、什么是relay log

The relay log, like the binary log, consists of a set of numbered files containing events that describe database changes,

relay log 像binary log ,包含了改变数据库的事件的文件

and an index file that contains the names of all used relay log files.

index 文件包含所有使用的relay log文件的名字

[mysql@slave1 data]$ cat slave1-relay-bin.index 
./slave1-relay-bin.000001
./slave1-relay-bin.000002



The term "relay log file" generally denotes an individual numbered file containing database events. 

术语 relay log 文件一般是指单独的编号包含数据库文件事件。



The term"relay log" collectively denotes the set of numbered relay log files plus the index file

术语 relay log  共同的表示 relay log file 加上index file

[mysql@slave1 data]$ ls -ltr slave1*
-rw-rw---- 1 mysql mysql      6 Mar  7 23:13 slave1.pid
-rw-rw---- 1 mysql mysql    174 Mar  7 23:24 slave1-relay-bin.000001
-rw-r----- 1 mysql root  123907 Mar  7 23:24 slave1.err
-rw-rw---- 1 mysql mysql    283 Mar  7 23:24 slave1-relay-bin.000002
-rw-rw---- 1 mysql mysql     52 Mar  7 23:24 slave1-relay-bin.index

change master to
master_host='10.10.17.5',master_user='backup',master_password='123456',master_log_file='mysql-bin.000008',master_log_pos=211;