欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

马哥 42_02 _MySQL主从复制——MySQL-5.5异步、半同步配置及其注意事项 有大用

一个master: 多个slave  可以的

        1-->N

一个slave:多个master 不可以的

        1-->N  :如果一个从服务器从多个主服务器那里复制数据,有些数据是重复的,有些数据会交叉,而且它们有可能属于不同的数据库,最终结果是混乱了,

一个从只能属于一个主服务器


MySQL 5.5之前复制功能实现起来很简单,

MySQL 5.6之后在复制上引入了gtid新机制,(gtid: 全局事务号  全局事务标示符 global transaction identifier ),gtid使得mysql的复制更加安全,不会在多事务并行的时候,产生数据混乱,,,引入了 multi-thread-replication (multi-thread replication: 多线程复制)


配置MySQL复制的基本步骤:

    一) master 如何配置,  

    1,启用二进制日志,(默认是启用的吧)        

            log-bin = master-bin          # 如果不定义,默认就是 mysql-bin  后面就是.000001

            log-bin-index = master-bin.index                  # 二进制日志文件的索引文件名称,通常是二进制日志文件名加上.index

    2,选择一个唯一的server-id

            server-id = {0-2^32}        #0到2的32次方

    3,创建具有复制权限的用户

            REPLICATION SLAVE     #这是复制的权限,复制的从节点,从主服务器的二进制日志文件中复制事件的权限

            REPLICATION CLINET    #偶尔会用到,具有连接主服务器获取相关信息的权限

    二) slave 如何配置,  

    1, 启用中继日志,默认是不会启用的

            relay-log = relay-log    #等于号后面的是中继日志的名称

            relay-log-index  =           # relay-log的索引文件

            #如果从服务器不打算做其它从服务器的主,是不用启用二进制日志的,所以可以关闭二进制日志

    2,选择一个唯一的server-id

            server-id = {0-2^32}        #0到2的32次方

    3,连接至主服务器,并开始复制数据           

       mysql>  CHANGER MASTER TO  MASTER_HOST='',MASTER_PORT='',MASTER_LOG_FILE='',MASTER_LOG_FILE_POS='',MASTER_USER='',MASTER_PASSWORD='';

       mysql> START SLAVE;   #通过这个命令启动mysql的从服务器的线程,它会启动IO线程和SQL线程        因为设定完成后不会立即启动mysql的从服务器的,         

       mysql> START SLAVE IO_Thread ;     #仅启动IO线程

       mysql> START SLAVE SQL_Thread;     #仅启动SQL线程

      复制线程:   

            master: dump

            slave: IO_Thread,SQL_Thread


            

从服务器一定是复制主服务器的二进制日志的某个事件,应该从主服务器的哪一个二进制日志中的哪一个位置开始复制,

见下图图一,左边主服务器是刚新建的,里面没有建任何数据,此时从服务器连上来复制数据的话,直接启动就可以了,指向第一个日志文件mysql-bin.00001的position 107 (开始都是107) 或者不指定位置,从最首部开始,,,,,,,假如主服务器已经运行半年了,业务太繁忙,想读写分离,想找个从服务器分担读操作,此时从服务器从头开始会复制好久好久的,,,,此时,我们可以在主服务器执行一次备份,备份那一刻记录下来二进制日志的文件名和事件位置,而后将备份出来的数据在从服务器上还原回来,再告诉从服务器连接主服务器的哪个二进制文件的位置的开始位置,

mysql的复制架构当中,主服务器写操作的时候,数据既保存在数据库中一份,又写在二进制中一份,,,,,,一旦有了从服务器,我们还应该把二进制的信息发给从,为每一个从启动一个线程,通过这个线程将信息发送给从服务器, 见下图图二,dump线程,从服务器有个线程来接入dump线程发送的信息

图一

image.png

图二

image.png

见下图,binarylog 通过dump线程,发送给slave,(服务器端只需要提供dump线程就可以了,这是根据有复制的话,会自动启动的),,,而从服务器端有两个关键性的线程,第一个是IO线程,这个线程到主服务器的dump那里去读取二进制日志,如果主服务器的二进制日志中有些事件从服务器没有,需要读过来的话,这时候我们的主服务器就会启动dump线程,将数据发给从服务器的IO线程,从服务器的IO线程在接收下来之后,保存在中继日志中,,,,,,,,,而后在从服务器中再启动一个 SQL 线程,这个SQL线程从中继日志中读一个事件后,就重放一个事件(在从服务器本地应用一次),实现了在从服务器本地应用数据更新,,,,,,,,,,,mysql5.6支持多线程复制,也就是SQL线程可以启动多个,多个SQL线程同时从relay log读数据,同时并行应用,会大大提高从服务器的速度,但是多SQL线程仍然是一个数据库只支持一个线程(此时即使启用了多SQL线程,也没有意义),,,,(复制的时候主服务器上有n个库,从服务器的SQL线程为多线程才有作用)

image.png

IO线程: IO Thread

SQL线程: SQL Thread

见下图如果主服务器的dump线程不在线了,从服务器上的IO线程也就不能工作了,就停了??,(因为IO线程连到dump上去获取数据的),,,,,当IO线程不能工作的时候,SQL线程还在工作(就是从从服务器的中继日志中读数据进行重放的,假如中继日志没内容的话,SQL线程还是不会停掉的(只不过它是空闲的,没有读数据罢了,),SQL线程只是等着中继日志更新就应用了,,,,,中继日志不更新,可能有多种原因:可能主服务器没有更新,主服务器不在线了(IO线程不工作了,连不上了),,,,,,,我们的主服务器上有些功能重新配置了,我们需要重启一下从服务器的时候,我们只需要重启IO线程即可

image.png

mysql的主从复制,mysql的客户端服务端连接的时候,mysql协议本身是明文,是加密的话,ssl,,,,,,,,,,如果不使用ssl的话,如果数据跨越互联网复制,公司的数据会被别人拿走一份的,(远程复制,跨越不安全网络的时候,应该要求客户端的IO线程使用某个用户的帐号连接主服务器的dump的时候,应该基于ssl的方式来复制,需要提供证书,密钥,,,,一般来说是客户端验证服务器端,服务器端验证客户端也可以,,甚至支持双向验证,,我们甚至可以不用帐号密码,帐号密码简单点都无所谓,因为只要客户端没有证书,就连不上来),,,,,,,,,,mysql5.5之后还支持半同步复制(从服务器多台的时候,只要一台响应其复制成功或者超时,这叫半同步),假如我们的从服务器不在线了,等待任何从服务器都没有答理我,我们主服务器该咋办?..................服务器还得继续工作,我们配置半同步复制模型的时候,需要指定一个超时时间间隔,一旦超出这样一个指定时间了,我们的主从可以断开,而后降级为异步模式继续工作,

image.png

    


两台主机 

192.168.0.46  node1 主服务器

192.168.0.56  node2 从服务器


在第一个节点node1 192.168.0.46 上

[root@node1 ~]# mkdir -pv /mydata/data

mkdir: 已创建目录 “/mydata”

mkdir: 已创建目录 “/mydata/data”

[root@node1 ~]#

[root@node1 ~]# useradd -r mysql        #自己直接建用户管不了太多了,正常情况下,是不是应该保证用户应该是系统用户,-r就表示系统帐户吧, id小于500的???

[root@node1 ~]# chown -R mysql:mysql /mydata/data/

[root@node1 ~]#

image.png

下载 5.5.28的二进制格式

image.png


在第一个节点node1 192.168.0.46 上 主服务器

我先卸载原来的mysql吧

[root@node1 cdrom]# yum remove mysql

image.png


https://downloads.mysql.com/archives/      mysql历史版本下载

https://downloads.mysql.com/archives/community/      mysql历史版本下载


在第一个节点node1 192.168.0.46 上 主服务器

下载mysql5.5.28的二进制包

[root@node1 ~]# wget https://cdn.mysql.com/archives/mysql-5.5/mysql-5.5.28-linux2.6-i686.tar.gz

--2021-03-12 14:35:40--  https://cdn.mysql.com/archives/mysql-5.5/mysql-5.5.28-linux2.6-i686.tar.gz

正在解析主机 cdn.mysql.com... 23.54.201.4

Connecting to cdn.mysql.com|23.54.201.4|:443... 已连接。

已发出 HTTP 请求,正在等待回应... 200 OK

长度:179907710 (172M) [application/x-tar-gz]

Saving to: `mysql-5.5.28-linux2.6-i686.tar.gz'


100%[======================================>] 179,907,710 3.05M/s   in 66s


2021-03-12 14:36:47 (2.61 MB/s) - `mysql-5.5.28-linux2.6-i686.tar.gz' saved [179907710/179907710]


[root@node1 ~]#

[root@node1 ~]# tar xf mysql-5.5.28-linux2.6-i686.tar.gz -C /usr/local

[root@node1 ~]# cd /usr/local

[root@node1 local]# ls

bin  games    lib      mysql-5.5.28-linux2.6-i686  share

etc  include  libexec  sbin                        src

[root@node1 local]#

[root@node1 local]# ln -sv mysql-5.5.28-linux2.6-i686 mysql

创建指向“mysql-5.5.28-linux2.6-i686”的符号链接“mysql”

[root@node1 local]# cd mysql

[root@node1 mysql]# pwd    

/usr/local/mysql

[root@node1 mysql]# chown -R root.mysql ./*    #改属主属组

[root@node1 mysql]#

[root@node1 mysql]# scripts/mysql_install_db --user=mysql --datadir=/mydata/data/    #初始化

Installing MySQL system tables...

OK

Filling help tables...

OK


To start mysqld at boot time you have to copy

support-files/mysql.server to the right place for your system


PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !

To do so, start the server, then issue the following commands:


./bin/mysqladmin -u root password 'new-password'

./bin/mysqladmin -u root -h node1.magedu.com password 'new-password'


Alternatively you can run:

./bin/mysql_secure_installation


which will also give you the option of removing the test

databases and anonymous user created by default.  This is

strongly recommended for production servers.


See the manual for more instructions.


You can start the MySQL daemon with:

cd . ; ./bin/mysqld_safe &


You can test the MySQL daemon with mysql-test-run.pl

cd ./mysql-test ; perl mysql-test-run.pl


Please report any problems with the ./bin/mysqlbug script!


[root@node1 mysql]#


[root@node1 mysql]# cp support-files/my-large.cnf /etc/my.cnf    # 复制配置文件

[root@node1 mysql]# cp support-files/mysql.server /etc/rc.d/init.d/mysqld        #复制脚本

[root@node1 mysql]#

[root@node1 mysql]# chkconfig --add mysqld        #chkconfig 加入 一下

[root@node1 mysql]# chkconfig --list mysqld

mysqld          0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭

[root@node1 mysql]#

[root@node1 mysql]# vim /etc/my.cnf

.....................................

# The MySQL server        #所有与复制相关的配置都在mysqld这里

[mysqld]

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

data_dir = /mydata/data  #数据目录

# Don't listen on a TCP/IP port at all. This can be a security enhancement,

# if all processes that need to connect to mysqld run on the same host.

# All interaction with mysqld must be made via Unix sockets or named pipes.

# Note that using this option without enabling named pipes on Windows

# (via the "enable-named-pipe" option) will render mysqld useless!

#

#skip-networking


# Replication Master Server (default)

# binary logging is required for replication

# log-bin=mysql-bin    

log-bin=master-bin    

 #启用二进制日志   其实默认是不会启用二进制日志的,因为默认的我们复制过来的配置文件my-large.cnf已经默认有了

log-bin-index=master-bin.index    #log-bin-index文件,这里如果不定义也没关系,就叫做master-bin.index 


# binary logging format - mixed recommended

binlog_format=mixed        #一般是row,或mixed了,不建议使用statement了

innodb_file_per_table= 1        #这一项很有用

# required unique id between 1 and 2^32 - 1

# defaults to 1 if master-host is not set

# but will not function as a master if omitted

server-id       = 1    # 最大数是 2^32 - 1 ,就是2的32次方减1,,,server-id都不能一样



# Replication Slave (comment out master section to use this)

#

# To configure this host as a replication slave, you can choose between

# two methods :

#

# 1) Use the CHANGE MASTER TO command (fully described in our manual) -

#    the syntax is:

#

#    CHANGE MASTER TO MASTER_HOST=<host>, MASTER_PORT=<port>,

#    MASTER_USER=<user>, MASTER_PASSWORD=<password> ;

#

#    where you replace <host>, <user>, <password> by quoted strings and

#    <port> by the master's port number (3306 by default).

#

#    Example:

#

#    CHANGE MASTER TO MASTER_HOST='125.564.12.1', MASTER_PORT=3306,

#    MASTER_USER='joe', MASTER_PASSWORD='secret';

#

# OR

#

# 2) Set the variables below. However, in case you choose this method, then

#    start replication for the first time (even unsuccessfully, for example

#    if you mistyped the password in master-password and the slave fails to

#    connect), the slave will create a master.info file, and any later

#    change in this file to the variables' values below will be ignored and

#    overridden by the content of the master.info file, unless you shutdown

#    the slave server, delete master.info and restart the slaver server.

#    For that reason, you may want to leave the lines below untouched

#    (commented) and instead use CHANGE MASTER TO (see above)

#

# required unique id between 2 and 2^32 - 1

# (and different from the master)

# defaults to 2 if master-host is set

# but will not function as a slave if omitted

#server-id       = 2

#

# The replication master for this slave - required

#master-host     =   <hostname>

#

# The username the slave will use for authentication when connecting

# to the master - required

#master-user     =   <username>

#

# The password the slave will authenticate with when connecting to

# the master - required

#master-password =   <password>

#

# The port the master is listening on.

# optional - defaults to 3306

#master-port     =  <port>

#

# binary logging - not required for slaves, but recommended

#log-bin=mysql-bin   


# Uncomment the following if you are using InnoDB tables

#innodb_data_home_dir = /usr/local/mysql/data

#innodb_data_file_path = ibdata1:10M:autoextend

#innodb_log_group_home_dir = /usr/local/mysql/data

# You can set .._buffer_pool_size up to 50 - 80 %

# of RAM but beware of setting memory usage too high

#innodb_buffer_pool_size = 256M

#innodb_additional_mem_pool_size = 20M

# Set .._log_file_size to 25 % of buffer pool size

#innodb_log_file_size = 64M

#innodb_log_buffer_size = 8M

#innodb_flush_log_at_trx_commit = 1

#innodb_lock_wait_timeout = 50


[root@node1 mysql]# service mysqld status

MySQL is not running                                       [失败]

[root@node1 mysql]# service mysqld start

Starting MySQL.The server quit without updating PID file (/usr/local/mysql/data/node1.magedu.com.pid).                                     [失败]

[root@node1 mysql]# vim /etc/my.cnf

...............................................................

datadir = /mydata/data

...............................................................



[root@node1 mysql]# service mysqld start        #可以启动了

Starting MySQL.

.                                                          [确定]

[root@node1 mysql]#

[root@node1 ~]# mysql

-bash: mysql: command not found

[root@node1 ~]# 

[root@node1 ~]# vim /etc/profile.d/mysql.sh        #添加环境变量

export PATH=$PATH:/usr/local/mysql/bin

[root@node1 ~]# . /etc/profile.d/mysql.sh        #读一下并且执行一下这个配置文件

[root@node1 ~]#

[root@node1 ~]# mysql    #正常了

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 1

Server version: 5.5.28-log MySQL Community Server (GPL)


Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.


Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.


Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.


mysql>



[root@node1 ~]# scp mysql-5.5.28-linux2.6-i686.tar.gz node2:/root        #复制到node2

mysql-5.5.28-linux2.6-i686.tar.gz             100%  172MB  24.5MB/s   00:07

[root@node1 ~]#



在第一个节点node1 192.168.0.46 上 主服务器

[root@node1 ~]# mysql

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 2

Server version: 5.5.28-log MySQL Community Server (GPL)


Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.


Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.


Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.


mysql> grant replication slave on *.* to 'repluser'@'192.168.%.%' identified by 'replpass';    #授权从复制权限

Query OK, 0 rows affected (0.00 sec)


mysql>

mysql> flush privileges;    #刷新权限

Query OK, 0 rows affected (0.00 sec)


mysql>

mysql> \q

Bye

[root@node1 ~]#

主服务器上三配置:二进制日志,server-id,用户帐号 都弄好了


在第二个节点node2 192.168.0.56 上 从服务器


[root@node2 ~]# mkdir -pv /mydata/data

mkdir: 已创建目录 “/mydata”

mkdir: 已创建目录 “/mydata/data”

[root@node2 ~]# useradd -r mysql            #-r表示系统帐户

[root@node2 ~]# chown -R mysql.mysql /mydata/data

[root@node2 ~]#

[root@node2 ~]# tar xf mysql-5.5.28-linux2.6-i686.tar.gz -C /usr/local/

[root@node2 ~]#


在第一个节点node1 192.168.0.46 上 主服务器

[root@node1 ~]# scp /etc/my.cnf node2:/etc/        #复制mysql的配置文件过去

my.cnf                                        100% 4763     4.7KB/s   00:00

[root@node1 ~]#


在第二个节点node2 192.168.0.56 上 从服务器

[root@node2 ~]# cd /usr/local/

[root@node2 local]# ln -sv mysql-5.5.28-linux2.6-i686 mysql

创建指向“mysql-5.5.28-linux2.6-i686”的符号链接“mysql”

[root@node2 local]#

[root@node2 local]# cd mysql

[root@node2 mysql]# pwd

/usr/local/mysql

[root@node2 mysql]# chown -R root.mysql ./*        #改属主属组

[root@node2 mysql]# ll

总计 132

drwxr-xr-x  2 root mysql  4096 03-13 12:54 bin

-rw-r--r--  1 root mysql 17987 2012-08-29 COPYING

drwxr-xr-x  4 root mysql  4096 03-13 12:54 data

drwxr-xr-x  2 root mysql  4096 03-13 12:54 docs

drwxr-xr-x  3 root mysql  4096 03-13 12:54 include

-rw-r--r--  1 root mysql  7604 2012-08-29 INSTALL-BINARY

drwxr-xr-x  3 root mysql  4096 03-13 12:54 lib

drwxr-xr-x  4 root mysql  4096 03-13 12:54 man

drwxr-xr-x 10 root mysql  4096 03-13 12:54 mysql-test

-rw-r--r--  1 root mysql  2552 2012-08-29 README

drwxr-xr-x  2 root mysql  4096 03-13 12:54 scripts

drwxr-xr-x 27 root mysql  4096 03-13 12:54 share

drwxr-xr-x  4 root mysql  4096 03-13 12:54 sql-bench

drwxr-xr-x  2 root mysql  4096 03-13 12:54 support-files


     #不初始没法启动,所以必须初始化

[root@node2 mysql]# scripts/mysql_install_db --user=mysql --datadir=/mydata/data

Installing MySQL system tables...

OK

Filling help tables...

OK


To start mysqld at boot time you have to copy

support-files/mysql.server to the right place for your system


PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !

To do so, start the server, then issue the following commands:


./bin/mysqladmin -u root password 'new-password'

./bin/mysqladmin -u root -h node2.magedu.com password 'new-password'


Alternatively you can run:

./bin/mysql_secure_installation


which will also give you the option of removing the test

databases and anonymous user created by default.  This is

strongly recommended for production servers.


See the manual for more instructions.


You can start the MySQL daemon with:

cd . ; ./bin/mysqld_safe &


You can test the MySQL daemon with mysql-test-run.pl

cd ./mysql-test ; perl mysql-test-run.pl


Please report any problems with the ./bin/mysqlbug script!


[root@node2 mysql]#

[root@node2 mysql]# cp support-files/mysql.server /etc/init.d/mysqld    #复制服务脚本

[root@node2 mysql]# chkconfig --add mysqld        #服务加到服务列表中去

[root@node2 mysql]# chkconfig --list mysqld

mysqld          0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭

[root@node2 mysql]#


[root@node2 mysql]# vim /etc/my.cnf        #这是从主服务器上复制过来的,做点修改

.....................................

#log-bin=master-bin                #不用二进制日志了,注释掉

#log-bin-index=master-bin.index                #不用二进制日志的索引了,注释掉



# binary logging format - mixed recommended

binlog_format=mixed

relay-log =  relay-log        #中继日志,添加的这一行

relay-log-index =  relay-log.index       #中继日志的索引,添加的这一行


server-id       = 11        #改下server-id 为11 ,为主的server-id为1的,中间隔几个吧,可能将来要调整id号的值


在第一个节点node1 192.168.0.46 上 主服务器

[root@node1 ~]# mysql

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 3

Server version: 5.5.28-log MySQL Community Server (GPL)


Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.


Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.


Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.


mysql> show master status

    -> ;

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

| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |

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

| master-bin.000002 |      340 |              |                  |

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

1 row in set (0.00 sec)




mysql> show binlog events in 'master-bin.000001';

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

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

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

| master-bin.000001 |   4 | Format_desc |         1 |         107 | Server ver: 5.5.28-log, Binlog ver: 4 |

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

1 row in set (0.00 sec)


mysql>

mysql> show binlog events in 'master-bin.000002';        #已经创建了授权用户

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

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

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

| master-bin.000002 |   4 | Format_desc |         1 |         107 | Server ver: 5.5.28-log, Binlog ver: 4                                               |

| master-bin.000002 | 107 | Query       |         1 |         265 | grant replication slave on *.* to 'repluser'@'192.168.%.%' identified by 'replpass' |

| master-bin.000002 | 265 | Query       |         1 |         340 | flush privileges                                                                    |

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

3 rows in set (0.00 sec)


mysql>


在第二个节点node2 192.168.0.56 上 从服务器

[root@node2 mysql]# service mysqld start

Starting MySQL..                                           [确定]

[root@node2 mysql]# vim /etc/profile.d/mysql.sh

export PATH=$PATH:/usr/local/mysql/bin

[root@node2 mysql]# . /etc/profile.d/mysql.sh

[root@node2 mysql]# mysql

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 1

Server version: 5.5.28 MySQL Community Server (GPL)


Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.


Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.


Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.


mysql> show slave status\G            #可以查看slave的状态,因为slave没启动,所以为空

Empty set (0.00 sec)


#连接主服务器

mysql> change master to master_host='192.168.0.46',master_user='repluser',master_password='replpass',master_log_file='master-bin.000002',master_log_file_pos='340';

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'master_log_file_pos='340'' at line 1

mysql>help change     #查看帮助

Many help items for your request exist.

To make a more specific request, please type 'help <item>',

where <item> is one of the following

topics:

   ALTER TABLE

   CHANGE MASTER TO


mysql> help change master to

image.png

mysql> change master to master_host='192.168.0.46',master_user='repluser',master_password='replpass',master_log_file='master-bin.000002',master_log_pos=340;

Query OK, 0 rows affected (0.02 sec)


mysql>

mysql> show slave status\G            #连上主服务器后,此时可以查看状态了        既可以读主的二进制日志,又可读从的中继日志

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

               Slave_IO_State:

                  Master_Host: 192.168.0.46    #主服务器ip

                  Master_User: repluser    #主服务器用户

                  Master_Port: 3306

                Connect_Retry: 60        #连不上去,多长时间重试一次

              Master_Log_File: master-bin.000002        #当前读取的二进制日志文件

          Read_Master_Log_Pos: 340        #读到的位置340

               Relay_Log_File: relay-log.000001            #当前从服务器中继日志,与主的二进制日志未必统一,将来在从服务器备份的时候,应该记的是主服务器的二进制日志的文件及位置,,,,,因为将来是拿主服务器的二进制日志来做即时点还原的

                Relay_Log_Pos: 4

        Relay_Master_Log_File: master-bin.000002        #中继的Master Log File的文件名与 Master_Log_File是一致的

                       #排错的时候,看下面这两项        下面这两项为Yes,从服务器才能算正常 

             Slave_IO_Running: No        # Slave 上面的 IO thread 没有运行    

            Slave_SQL_Running: No       #Slave 上面的 SQL thread 没有运行

                    #下面几个做复制过滤的

              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: 340        #执行到了340,,上面读可能速度快,但是本地执行可能速度慢

              Relay_Log_Space: 107            #Relay_Log的空间

              Until_Condition: None

               Until_Log_File:

                Until_Log_Pos: 0

           Master_SSL_Allowed: No        #master主从复制上不允许使用ssl

           Master_SSL_CA_File:

           Master_SSL_CA_Path:

              Master_SSL_Cert:

            Master_SSL_Cipher:

               Master_SSL_Key:

        Seconds_Behind_Master: NULL        #从服务器比主服务器慢,,可能慢n个事件,这里没有显示

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

1 row in set (0.00 sec)


#启动从服务器的两个服务 ,( start slave io_thread 只启动io线程)( start slave sql_thread 只启动sql线程)

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

                  Master_User: repluser

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: master-bin.000002

          Read_Master_Log_Pos: 340

               Relay_Log_File: relay-log.000002

                Relay_Log_Pos: 254

        Relay_Master_Log_File: master-bin.000002

             Slave_IO_Running: Yes        # io线程运行起来了

            Slave_SQL_Running: Yes       # sql线程运行起来了

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

              Relay_Log_Space: 404

              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>



在第一个节点node1 192.168.0.46 上 主服务器

mysql> show databases;

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

| Database           |

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

| information_schema |

| mysql              |

| performance_schema |

| test               |

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

4 rows in set (0.02 sec)


mysql>

mysql> CREATE database magedudb;

Query OK, 1 row affected (0.00 sec)


mysql>


在第二个节点node2 192.168.0.56 上 从服务器

mysql> show slave status\G

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

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 192.168.0.46

                  Master_User: repluser

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: master-bin.000002

          Read_Master_Log_Pos: 431        #这里这时主日志位置改了为431

               Relay_Log_File: relay-log.000002

                Relay_Log_Pos: 345

        Relay_Master_Log_File: master-bin.000002

             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: 431        #执行到 431 这一步了,比上一次数字大(上一次是360),说明事件已经复制过来,在本地应用了,意味着本地有这个数据库了

              Relay_Log_Space: 495

              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 |

| magedudb           |        #本地有这个数据库了

| mysql              |

| performance_schema |

| test               |

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

5 rows in set (0.00 sec)


mysql>

从服务器上创建一个数据库,在主服务器上是不会有的,所以从服务器上一定不能允许写操作的,

如何让它不能写操作?打开一个线程连接,执行 flush tables with read lock,刷新所有表并且读锁定,,,,,,这并不影响sql thread往里面写数据,但是其它用户就不能写数据了,,,,,,这种方法不理想,每次打开一个连接,手动锁定,很麻烦

mysql> show global variables like 'read%';

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

| Variable_name        | Value   |

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

| read_buffer_size     | 1048576 |

| read_only            | OFF     |        #只读 关闭,,改为ON就可以让数据库不能写了 (只有管理员才有权限改全局变量,改当前用户,当前会话与其它用户是没有关系的,其它用户连进来,照样能写,想全局禁止,只有改global的,此时只有管理员才有权限)(这里改,从服务器重启后就失效了,,所以只能改配置文件了)

| read_rnd_buffer_size | 4194304 |

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

3 rows in set (0.00 sec)


mysql>


[root@node2 mysql]# vim /etc/my.cnf        #修改配置文件

........................................................................

[mysqld]        #在这个下面

........................................................................

relay-log =  relay-log

relay-log-index =  relay-log.index

read-only = ON  #加上这一行    (这里read_only 下划线,中短横都行, ON,YES,1,TRUE都可以)


[root@node2 mysql]# service mysqld restart        # 重启生效

Shutting down MySQL.                                       [确定]

Starting MySQL..                                           [确定]

[root@node2 mysql]#

[root@node2 mysql]# mysql

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 3

Server version: 5.5.28 MySQL Community Server (GPL)


Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.


Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.


Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.


mysql> show global variables like 'read_only%'

    -> ;

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

| Variable_name | Value |

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

| read_only     | ON    |        # 这是是ON了

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

1 row in set (0.00 sec)


mysql>

mysql> show slave status\G

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

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 192.168.0.46

                  Master_User: repluser

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: master-bin.000002

          Read_Master_Log_Pos: 431

               Relay_Log_File: relay-log.000004

                Relay_Log_Pos: 254

        Relay_Master_Log_File: master-bin.000002

             Slave_IO_Running: Yes        #它启动了    当使用 change master to 之后,就算重启了mysql服务器,复制线程 (这两个线程)也会自动启动的        连主服务器是需要帐号密码的,重启后自动连的时候,如何知道的?

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

              Relay_Log_Space: 404

              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>

[root@node2 mysql]# cd /mydata/data/

[root@node2 data]# ls

ibdata1      master-bin.000001  mysql                 relay-log.000003  test

ib_logfile0  master-bin.000002  node2.magedu.com.err  relay-log.000004

ib_logfile1  master-bin.index   node2.magedu.com.pid  relay-log.index

magedudb     master.info        performance_schema    relay-log.info

[root@node2 data]#

[root@node2 data]# file master.info

master.info: ASCII text

[root@node2 data]#

[root@node2 data]# cat master.info    #每一次更新了相关信息之后

18

master-bin.000002    #现在读的文件

431   #现在读的文件的位置

192.168.0.46    #主服务器

repluser        #帐号

replpass        #密码

3306                #端口号

60                    #重试时间

0






0

1800.000


0

[root@node2 data]#

[root@node2 data]# ll

总计 29888

-rw-rw---- 1 mysql mysql 18874368 03-13 15:39 ibdata1

-rw-rw---- 1 mysql mysql  5242880 03-13 15:39 ib_logfile0

-rw-rw---- 1 mysql mysql  5242880 03-13 13:13 ib_logfile1

drwx------ 2 mysql mysql     4096 03-13 15:22 magedudb

-rw-rw---- 1 mysql mysql    27323 03-13 12:59 master-bin.000001

-rw-rw---- 1 mysql mysql  1038693 03-13 12:59 master-bin.000002

-rw-rw---- 1 mysql mysql       40 03-13 12:59 master-bin.index

-rw-rw---- 1 mysql mysql       85 03-13 15:39 master.info        #允许mysql读写,其它用户没有访问权限

drwx------ 2 mysql root      4096 03-13 12:59 mysql

-rw-rw---- 1 mysql root      4861 03-13 15:39 node2.magedu.com.err

-rw-rw---- 1 mysql mysql        6 03-13 15:39 node2.magedu.com.pid

drwx------ 2 mysql mysql     4096 03-13 12:59 performance_schema

-rw-rw---- 1 mysql mysql      150 03-13 15:39 relay-log.000003

-rw-rw---- 1 mysql mysql      254 03-13 15:39 relay-log.000004

-rw-rw---- 1 mysql mysql       38 03-13 15:39 relay-log.index

-rw-rw---- 1 mysql mysql       45 03-13 15:39 relay-log.info

drwx------ 2 mysql root      4096 03-13 12:59 test

[root@node2 data]#

[root@node2 data]#

[root@node2 data]# file relay-log.info

relay-log.info: ASCII text

[root@node2 data]#

[root@node2 data]# cat relay-log.info

./relay-log.000004        #当前使用的 relay-log 文件

254                               #当前使用的 relay-log 文件的事件位置

master-bin.000002        #正在读取的主服务器上的二进制日志文件

431                             #正在读取的主服务器上的二进制日志文件的事件位置

[root@node2 data]#

结合maser-log.info 和 relay-log.info 来获取相关的信息,并决定下一次自动启动从服务器线程的时候,从什么地方启动,,读取哪一个主服务的二进制日志文件及位置,本地的中继日志文件是哪一个文件,以及位置


maser-log.info 和 relay-log.info是实现复制数据库的重要的基础和前提



read-only = YES,

    在从服务器上设定,为了保持主从一致性,让从服务器不能写,,但对具有SUPER权限的用户没有限定,是不生效的,管理员照样能写,


主服务器上,某个事务已经提交了,二进制事件写到二进制日志文件里面去,二进制日志有缓冲区,(可能此时有些内容未写到二进制日志中去,万一此时,主服务器崩溃了),,,,从服务器不能得到相关的事件,不能将事务完整的结束(跟这个事务相关的某些操作没有复制过来,因为还未保存在主服务器的二进制日志文件中,所以从服务器的中继日志文件中也没有),,,,,,所以主服务器上完成的事务,从服务器上可能完成不了,,,,,,,,,,,如果让主服务器事务一提交,必须立即写到二进制日志文件里面去,别在缓冲区中作任何停留,这就降低了主从不一致的可能性了,


sync-binlog = ON

    在主服务器上设定,用于事务安全




配置主服务器同步二进制日志

在第一个节点node1 192.168.0.46 上 主服务器

mysql> show global variables like '%log%';

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

| Variable_name                           | Value                             |

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

| back_log                                | 50                                |

| binlog_cache_size                       | 32768                             |

| binlog_direct_non_transactional_updates | OFF                               |

| binlog_format                           | MIXED                             |

| binlog_stmt_cache_size                  | 32768                             |

| expire_logs_days                        | 0                                 |

| general_log                             | OFF                               |

| general_log_file                        | /mydata/data/node1.log            |

| innodb_flush_log_at_trx_commit          | 1                                 |

| innodb_locks_unsafe_for_binlog          | OFF                               |

| innodb_log_buffer_size                  | 8388608                           |

| innodb_log_file_size                    | 5242880                           |

| innodb_log_files_in_group               | 2                                 |

| innodb_log_group_home_dir               | ./                                |

| innodb_mirrored_log_groups              | 1                                 |

| log                                     | OFF                               |

| log_bin                                 | ON                                |

| log_bin_trust_function_creators         | OFF                               |

| log_error                               | /mydata/data/node1.magedu.com.err |

| log_output                              | FILE                              |

| log_queries_not_using_indexes           | OFF                               |

| log_slave_updates                       | OFF                               |

| log_slow_queries                        | OFF                               |

| log_warnings                            | 1                                 |

| max_binlog_cache_size                   | 18446744073709547520              |

| max_binlog_size                         | 1073741824                        |

| max_binlog_stmt_cache_size              | 18446744073709547520              |

| max_relay_log_size                      | 0                                 |

| relay_log                               |                                   |

| relay_log_index                         |                                   |

| relay_log_info_file                     | relay-log.info                    |

| relay_log_purge                         | ON                                |

| relay_log_recovery                      | OFF                               |

| relay_log_space_limit                   | 0                                 |

| slow_query_log                          | OFF                               |

| slow_query_log_file                     | /mydata/data/node1-slow.log       |

| sql_log_bin                             | ON                                |

| sql_log_off                             | OFF                               |

| sync_binlog                             | 0                                 |        #是不是同步二进制日志的 在主从复制架构中,为了事务的安全,应该启用起来

| sync_relay_log                          | 0                                 |

| sync_relay_log_info                     | 0                                 |

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

41 rows in set (0.00 sec)


mysql>




从服务器启动后,自动连接主服务获取数据的,万一从服务器崩溃了,下次一启动,会自动连接主服务器复制数据,而有些数据我们在主服务器上想跳过去的,因为我们主服务器上也错了,,,,所以此时我们不应该让从服务器重启自动复制数据


如下图,主服务器,不小心,删了表magedudb.tb1,我们赶紧停掉从服务器

然后准备启动从服务器把magedudb tb1表手动复制到主服务器.

假如从服务器启动,立马连上主服务器进行复制主服务器上的删除事件

也会把从服务器上的相应的表删除掉的,,,,,,,,,,,

所以一般我们不应该让从服务器上的复制线程自动启动的

image.png



在第二个节点 node2 192.168.0.56 上 从服务器

mysql> show global variables like '%slave%';

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

| Variable_name             | Value      |

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

| init_slave                |            |

| log_slave_updates         | OFF        |

| slave_compressed_protocol | OFF        |

| slave_exec_mode           | STRICT     |

| slave_load_tmpdir         | /tmp       |

| slave_max_allowed_packet  | 1073741824 |

| slave_net_timeout         | 3600       |

| slave_skip_errors         | OFF        |

| slave_transaction_retries | 10         |

| slave_type_conversions    |            |

| sql_slave_skip_counter    | 0          |

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

11 rows in set (0.00 sec)


mysql>

mysql> show global variables like '%skip%';

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

| Variable_name          | Value |

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

| skip_external_locking  | ON    |

| skip_name_resolve      | OFF   |

| skip_networking        | OFF   |

| skip_show_database     | OFF   |

| slave_skip_errors      | OFF   |

| sql_slave_skip_counter | 0     |

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

6 rows in set (0.00 sec)


mysql>



马哥也不清楚,有个 skip-slave-start 参数,这里为什么看不到了

在从服务器上

     skip-slave-start=1

当然若不支持  skip-slave-start 这个变量了,有其它办法,让从服务器重启时不自动连主服务器,

把 从服务器mysqld 停止后 ,从服务器中的 master.info 和 relay-log.info 剪切一下,放到别处就可以了,,再启动从服务器的mysqld,(然后把magedudb.tb1复制到主服务器)再手动使用 change master to ,再手动指一遍就可以了(如果想彻底的,重新来定义mysql从服务器的话)

  因为从服务器之所以开机自动启动两个线程(io线程,sql线程), 主要依赖于 master.info 和 relay-log.info


在第二个节点node2 192.168.0.56 上 从服务器

[root@node2 data]# pwd

/mydata/data

[root@node2 data]# ls

ibdata1      master-bin.000001  mysql                 relay-log.000003  test

ib_logfile0  master-bin.000002  node2.magedu.com.err  relay-log.000004

ib_logfile1  master-bin.index   node2.magedu.com.pid  relay-log.index

magedudb     master.info        performance_schema    relay-log.info

[root@node2 data]#


mysql> stop slave;        #停掉从服务器的两个线程(io线程,sql线程), 

Query OK, 0 rows affected (0.01 sec)


mysql>

mysql> show slave status\G

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

               Slave_IO_State:

                  Master_Host: 192.168.0.46

                  Master_User: repluser

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: master-bin.000002

          Read_Master_Log_Pos: 431

               Relay_Log_File: relay-log.000004

                Relay_Log_Pos: 254

        Relay_Master_Log_File: master-bin.000002

             Slave_IO_Running: No            #为No了

            Slave_SQL_Running: No           #为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: 431

              Relay_Log_Space: 404

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

1 row in set (0.00 sec)


mysql>


mysql> start slave io_thread;    #启动IO线程

Query OK, 0 rows affected (0.00 sec)


mysql>

mysql> show slave status\G

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

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 192.168.0.46

                  Master_User: repluser

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: master-bin.000002

          Read_Master_Log_Pos: 431

               Relay_Log_File: relay-log.000004

                Relay_Log_Pos: 254

        Relay_Master_Log_File: master-bin.000002

             Slave_IO_Running: Yes            #此时IO线程已经启动了

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

              Relay_Log_Space: 701

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

1 row in set (0.00 sec)


mysql>

mysql> start slave sql_thread;               #启动SQL线程

Query OK, 0 rows affected (0.00 sec)


mysql>

mysql> show slave status\G

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

               Slave_IO_State: Waiting for master to send eve

                  Master_Host: 192.168.0.46

                  Master_User: repluser

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: master-bin.000002

          Read_Master_Log_Pos: 431

               Relay_Log_File: relay-log.000005

                Relay_Log_Pos: 254

        Relay_Master_Log_File: master-bin.000002

             Slave_IO_Running: Yes

            Slave_SQL_Running: Yes             #此时SQL线程已经启动了

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

              Relay_Log_Space: 551

              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>


mysql> stop slave io_thread;                #停止io线程

Query OK, 0 rows affected (0.00 sec)


mysql>

mysql> show slave status\G

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

               Slave_IO_State:

                  Master_Host: 192.168.0.46

                  Master_User: repluser

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: master-bin.000002

          Read_Master_Log_Pos: 431

               Relay_Log_File: relay-log.000005

                Relay_Log_Pos: 254

        Relay_Master_Log_File: master-bin.000002

             Slave_IO_Running: No            #IO线程已经停掉了

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

              Relay_Log_Space: 551

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

1 row in set (0.00 sec)


mysql> start slave io_thread;        #启动 io 线程

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

                  Master_User: repluser

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: master-bin.000002

          Read_Master_Log_Pos: 431

               Relay_Log_File: relay-log.000006

                Relay_Log_Pos: 254

        Relay_Master_Log_File: master-bin.000002

             Slave_IO_Running: Yes        #IO线程已经启动了

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

              Relay_Log_Space: 551

              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>


往往有的时候我们只需要停止IO线程,再启动IO线程


跟从服务器相关的启动的内容都会保存在数据库服务当中数据目录下的错误日志当中,

[root@node2 data]# tail /mydata/data/node2.magedu.com.err

210313 16:37:17 [Note] Error reading relay log event: slave SQL thread was killed

210313 16:37:17 [ERROR] Error reading packet from server: Lost connection to MySQL server during query ( server_errno=2013)

210313 16:37:17 [Note] Slave I/O thread killed while reading event    #杀死IO线程

210313 16:37:17 [Note] Slave I/O thread exiting, read up to log 'master-bin.000002', position 431

210313 16:39:29 [Note] Slave I/O thread: connected to master 'repluser@192.168.0.46:3306',replication started in log 'master-bin.000002' at position 431

210313 16:40:58 [Note] Slave SQL thread initialized, starting replication in log 'master-bin.000002' at position 431, relay log './relay-log.000004' position: 254            # IO 线程初始化,开始复制了

210313 16:42:35 [ERROR] Error reading packet from server: Lost connection to MySQL server during query ( server_errno=2013)

210313 16:42:35 [Note] Slave I/O thread killed while reading event

210313 16:42:35 [Note] Slave I/O thread exiting, read up to log 'master-bin.000002', position 431

210313 16:44:14 [Note] Slave I/O thread: connected to master 'repluser@192.168.0.46:3306',replication started in log 'master-bin.000002' at position 431

[root@node2 data]#



mysql支持半同步复制

在主服务器和从服务器上各自安装一个插件 google提供的,

设置半同步步骤:

在Master和Slave的mysql命令行运行如下代码:

# On Master  

mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';      #rpl_semi_sync_master是模块插件名     SONAME指的是so文件名    semisync_master.so是模块插件的文件名称

mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;      #启用

mysql> SET GLOBAL rpl_semi_sync_master_timeout = 1000;      #超时时间为1000毫秒,,1秒钟联系不到从服务器,就退出了,,,,( 1秒钟是不是有点短了 )


# On Slave  

mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';  

mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;  

mysql> STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;  


在Master和Slave的my.cnf中编辑:


# On Master          #里面的设置永久有效

[mysqld]  

rpl_semi_sync_master_enabled=1  

rpl_semi_sync_master_timeout=1000 # 1 second  


# On Slave  

[mysqld]  

rpl_semi_sync_slave_enabled=1  



# 也可通过设置全局变量的方式来设置,如下:

set global rpl_semi_sync_master_enabled=1 

# 取消加载插件

mysql> UNINSTALL PLUGIN rpl_semi_sync_master;

==============================================


查看从服务器上的semi_sync是否开启:

mysql> SHOW GLOBAL STATUS LIKE 'rpl_semi%';


查看主服务器上的 rpl_semi_sync_master_enabled  是否开启,注意  Rpl_semi_sync_master_clients  变为1 ,证明主从半同步复制连接成功:



mysql> SHOW GLOBAL STATUS LIKE 'rpl_semi%';

image.png



在第二个节点node2 192.168.0.56 上 从服务器


[root@node2 data]# cd /usr/local/mysql

[root@node2 mysql]# ls

bin      docs            lib         README   sql-bench

COPYING  include         man         scripts  support-files

data     INSTALL-BINARY  mysql-test  share

[root@node2 mysql]# cd lib/plugin/

[root@node2 plugin]# pwd

/usr/local/mysql/lib/plugin

[root@node2 plugin]# ls

adt_null.so     auth_test_plugin.so  libdaemon_example.so  qa_auth_interface.so  semisync_slave.so (半同步复制的插件,从服务器上的)

auth.so         daemon_example.ini   mypluglib.so          qa_auth_server.so

auth_socket.so  debug                qa_auth_client.so     semisync_master.so(半同步复制的插件,主服务器上的)

[root@node2 plugin]#


在第一个节点node1 192.168.0.46 上 主服务器

mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';    #安装成功 装半同步复制插件主模块

Query OK, 0 rows affected (0.02 sec)


mysql> show global variables like '%rpl%';

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

| Variable_name                      | Value |

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

| rpl_recovery_rank                  | 0     |

| rpl_semi_sync_master_enabled       | OFF   |            # 未启用半同步复制的主节点

| rpl_semi_sync_master_timeout       | 10000 |           # 超时时间 10000毫秒 (从服务器一直不响应,主服务器不可能一直等着)            10秒钟其实有点长了

| rpl_semi_sync_master_trace_level   | 32    |          #追踪级别

| rpl_semi_sync_master_wait_no_slave | ON    |          #没有slave的时候,要等待,非要等待一个slave上来

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

5 rows in set (0.00 sec)


mysql> 


在第二个节点node2 192.168.0.56 上 从服务器

mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';         #安装成功 装半同步复制插件从模块

Query OK, 0 rows affected (0.02 sec)


mysql>

mysql> show variables like '%rpl%';        #写不写global 没关系

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

| Variable_name                   | Value |

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

| rpl_recovery_rank               | 0     |

| rpl_semi_sync_slave_enabled     | OFF   |        #没有启动从服务器半同步复制模块

| rpl_semi_sync_slave_trace_level | 32    |

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

3 rows in set (0.00 sec)


mysql> show global  variables like '%rpl%';

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

| Variable_name                   | Value |

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

| rpl_recovery_rank               | 0     |

| rpl_semi_sync_slave_enabled     | OFF   |

| rpl_semi_sync_slave_trace_level | 32    |

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

3 rows in set (0.00 sec)



先启动主的 半同步复制模块

在第一个节点node1 192.168.0.46 上 主服务器

mysql> set global rpl_semi_sync_master_enabled=1;    #主服务器上启动半同步复制模块

Query OK, 0 rows affected (0.00 sec)



mysql> show global variables like '%rpl%';

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

| Variable_name                      | Value |

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

| rpl_recovery_rank                  | 0     |

| rpl_semi_sync_master_enabled       | ON    |    # 启用了

| rpl_semi_sync_master_timeout       | 10000 |        #这个10秒就不改了

| rpl_semi_sync_master_trace_level   | 32    |

| rpl_semi_sync_master_wait_no_slave | ON    |

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

5 rows in set (0.00 sec)


mysql>


在第二个节点node2 192.168.0.56 上 从服务器

mysql> set global rpl_semi_sync_slave_enabled=1;      #从服务器上启动半同步复制模块

Query OK, 0 rows affected (0.00 sec)


mysql> show global variables like '%rpl%';

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

| Variable_name                   | Value |

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

| rpl_recovery_rank               | 0     |

| rpl_semi_sync_slave_enabled     | ON    |    # 为ON了

| rpl_semi_sync_slave_trace_level | 32    |

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

3 rows in set (0.00 sec)


mysql>


在第一个节点node1 192.168.0.46 上 主服务器

mysql> show global status like 'rpl%';

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

| Variable_name                              | Value

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

| Rpl_semi_sync_master_clients               | 0            #半同步客户端是0个,说明半同步复制功能未启用,是把从服务器线程关掉,再连下才能生效的

| 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

| Rpl_status                                 | AUTH_MAS

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

15 rows in set (0.00 sec)


mysql>


在第二个节点node2 192.168.0.56 上 从服务器

mysql> stop slave io_thread;        #只需停止io_thread,再启动就行了

Query OK, 0 rows affected (0.00 sec)


mysql> start slave io_thread;

Query OK, 0 rows affected (0.00 sec)


mysql>


在第一个节点node1 192.168.0.46 上 主服务器

mysql> show global status like '%rpl%';

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

| Variable_name                              | Value       |

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

| Rpl_semi_sync_master_clients               | 1           |        #此时为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           |

| Rpl_status                                 | AUTH_MASTER |

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

15 rows in set (0.00 sec)


mysql>

我们需要经常观察主服务器或从服务器状态变量里面的半同步相关的内容,一旦超时,我们的服务器不联系的话,会自动降级为半同步的????感觉应该为异步????,,,把从服务器关掉,,在主服务器上创建一个数据库(或数据表的话),可能会卡10秒钟的(设定为10秒的话),


在第一个节点node1 192.168.0.46 上 主服务器

mysql> use magedudb;

Database changed

mysql> create table tb1(id int);    #创建表,时间很长,为0.12秒(因为半同步要依赖网络通信才能结束的),如果是异步模式的话,表应该瞬间创建完成

Query OK, 0 rows affected (0.12 sec)


mysql>


在第二个节点node2 192.168.0.56 上 从服务器


mysql> stop slave io_thread;            #停掉从服务器的io线程

Query OK, 0 rows affected (0.01 sec)


mysql>


在第一个节点node1 192.168.0.46 上 主服务器

mysql> create table tb2 (id int);        #卡住了        因为定义的10秒,所以等了10秒

Query OK, 0 rows affected (10.01 sec)


mysql> show global status like '%rpl%';

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

| Variable_name                              | Value       |

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

| Rpl_semi_sync_master_clients               | 1           |            #clients为1,没错

| Rpl_semi_sync_master_net_avg_wait_time     | 299         |        #主服务器网络等待的平均时间

| Rpl_semi_sync_master_net_wait_time         | 599         |       #主服务器网络等待的这一次的时间

| Rpl_semi_sync_master_net_waits             | 2           |            #主服务器网络等待了几次,因为两次复制等待了2次???

| Rpl_semi_sync_master_no_times              | 1           |

| Rpl_semi_sync_master_no_tx                 | 1           |

| Rpl_semi_sync_master_status                | OFF         |

| Rpl_semi_sync_master_timefunc_failures     | 0           |

| Rpl_semi_sync_master_tx_avg_wait_time      | 618         |

| Rpl_semi_sync_master_tx_wait_time          | 618         |

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

| Rpl_status                                 | AUTH_MASTER |

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

15 rows in set (0.02 sec)


mysql> show global status like '%rpl%';                #过一段时间,再执行一次, 一般来讲,等待一段时间超时以后,它会自动降级为半同步的???感觉是异步吧

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

| Variable_name                              | Value       |

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

| Rpl_semi_sync_master_clients               | 1           |

| Rpl_semi_sync_master_net_avg_wait_time     | 299         |

| Rpl_semi_sync_master_net_wait_time         | 599         |

| Rpl_semi_sync_master_net_waits             | 2           |

| Rpl_semi_sync_master_no_times              | 1           |

| Rpl_semi_sync_master_no_tx                 | 1           |

| Rpl_semi_sync_master_status                | OFF         |

| Rpl_semi_sync_master_timefunc_failures     | 0           |

| Rpl_semi_sync_master_tx_avg_wait_time      | 618         |

| Rpl_semi_sync_master_tx_wait_time          | 618         |

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

| Rpl_status                                 | AUTH_MASTER |

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

15 rows in set (0.00 sec)


mysql> create table tb3 (id int);        #现在为 0.01秒,很快,所以一旦有一次超时,从服务器连不上,会自动降级为异步,

Query OK, 0 rows affected (0.01 sec)


mysql>


在第二个节点node2 192.168.0.56 上 从服务器

mysql> start slave io_thread;        #重新启动一下io线程,,,,,,,它会重新跟上去同步的,

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

                  Master_User: repluser

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: master-bin.000002

          Read_Master_Log_Pos: 706    #当前复制的起点位置,这里可能显示的并不准确,因为如果没有读到信息,可能比主服务器落后???,,,,,,,不能观察这个认为它是不是落后?????应该是不是半同步吧,,,,,,,,,,,,

               Relay_Log_File: relay-log.000008

                Relay_Log_Pos: 438

        Relay_Master_Log_File: master-bin.000002

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

              Relay_Log_Space: 826

              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>


在第一个节点node1 192.168.0.46 上 主服务器

mysql> show master status\G

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

            File: master-bin.000002

        Position: 706        #这里位置也是 706

    Binlog_Do_DB:

Binlog_Ignore_DB:

1 row in set (0.00 sec)


mysql>



在第二个节点 node2 192.168.0.56 上 从服务器

怎么知道从服务器是不是落后,主从同步的配置是很繁杂的,所以percona给我们提供了一些工具,专门用来实理管理主从复制的

比如看看从服务器是不是比主服务器慢等相关情况的,

percona-tools,,早期叫 mattkit-tools,是一个叫mattkit的人研发的,后来这个项目被贡献给了 percona组织,所以改名叫 percona-tools ,,,,早期命令叫 mk-开头的命令,比如 mk-slave......mk-replication.现在以pt-开头了,


noarch 表示不分平台的,没有架构的,32位,64位都可以同时用,,一般的这种包依赖于mysql库,依赖于rpm格式的mysql库,所以使用 rpm 来安装 percona-tools 可能会报错,因为我们安装的mysql不是 rpm 包格式提供的,库导给它也不行,percona-tools依赖的是几个perl模块,所以percona-tools是一堆的perl脚本,这就是为什么它是noarch的原因,,,通过yum 安装 percona-tools,它把mysql客户端(rpm格式的)也装上去了,不过没关系,跟我们用的并不冲突

image.png

image.png

image.png

image.png

(percona-tools依赖于rpm的mysql客户端)这个mysql客户端装上去以后,也会创建 /etc/my.cnf文件的,,确保 我们以前的/etc/my.cnf没有被修改


在第二个节点node2 192.168.0.56 上 从服务器

https://www.percona.com/downloads/percona-toolkit/LATEST/  我找 percona-toolkit-2.2.2-1.noarch.rpm 

[root@node2 ~]# wget https://downloads.percona.com/downloads/percona-toolkit/2.2.2/RPM/percona-toolkit-2.2.2-1.noarch.rpm --secure-protocol=tlsv1

--2021-03-15 14:29:16--  https://downloads.percona.com/downloads/percona-toolkit/2.2.2/RPM/percona-toolkit-2.2.2-1.noarch.rpm

正在解析主机 downloads.percona.com... 74.121.199.235

Connecting to downloads.percona.com|74.121.199.235|:443... 已连接。

OpenSSL: error:1409442E:SSL routines:SSL3_READ_BYTES:tlsv1 alert protocol version

无法建立 SSL 连接。

[root@node2 ~]# 

既然报错 ,我把这个文件下载移到我的任意一个网站里,然后 

[root@node2 ~]# wget http://www.aaaaa.cn/percona-toolkit-2.2.2-1.noarch.rpm   这个文件

[root@node2 ~]# rpm -ivh percona-toolkit-2.2.2-1.noarch.rpm    #无法安装

warning: percona-toolkit-2.2.2-1.noarch.rpm: Header V4 DSA signature: NOKEY, key ID cd2efd2a

error: Failed dependencies:

        perl(DBD::mysql) >= 1.0 is needed by percona-toolkit-2.2.2-1.noarch

        perl(IO::Socket::SSL) is needed by percona-toolkit-2.2.2-1.noarch

[root@node2 ~]#

[root@node2 ~]# yum -y --nogpgcheck localinstall percona-toolkit-2.2.2-1.noarch.rpm

image.png

image.png

image.pngimage.png

image.png


[root@node2 ~]# vim /etc/my.cnf        #确保装了percona-tools后自动依赖安装的mysql没有改我们的配置文件

image.png        

在第二个节点node2 192.168.0.56 上 从服务器

[root@node2 ~]# pt            #我们看 pt开头的命令

pt-align                  pt-fk-error-logger        pt-query-digest           pt-table-sync

pt-archiver               pt-heartbeat              pt-show-grants            pt-table-usage

pt-config-diff            pt-index-usage            pt-sift                   pt-upgrade

pt-deadlock-logger        pt-ioprofile              pt-slave-delay            pt-variable-advisor

pt-diskstats              pt-kill                   pt-slave-find             pt-visual-explain

pt-duplicate-key-checker  pt-mext                   pt-slave-restart          ptx

pt-fifo-split             pt-mysql-summary          pt-stalk

pt-find                   pt-online-schema-change   pt-summary

pt-fingerprint            pt-pmp                    pt-table-checksum

[root@node2 ~]# pt


[root@node2 ~]# pt-slave-delay -h        # delay 表示延迟,专门让从服务器比主服务器慢一点时间的,可以指定慢多长时间,这样子,在主服务器上执行了一些误操作,从服务器上不会立即得到的,,,,,但是我们不能依赖于它吧

Option h requires an argument

Usage: pt-slave-delay [OPTIONS] SLAVE_DSN [MASTER_DSN]


Errors in command-line arguments:

  * Error parsing options

  * Missing or invalid slave host


pt-slave-delay starts and stops a slave server as needed to make it lag behind

the master.  The SLAVE_DSN and MASTER_DSN use DSN syntax, and values are copied

from the SLAVE_DSN to the MASTER_DSN if omitted.  For more details, please use

the --help option, or try 'perldoc /usr/bin/pt-slave-delay' for complete

documentation.

[root@node2 ~]#


pt-summary      #搜集一下当前服务器的cpu类型,内存大小等信息

pt-diskstats       #显示一下磁盘IO的相关统计数据的

pt-index-usage         #显示一下当前的索引使用情况的

pt-visual-explain         #可视化explain的,后面讲到查询分析的时候,会用到这个工具

pt-table-checksum         #这是跟复制相关的,


[root@node2 ~]# pt-table-checksum --help    #检查的时候,应该指定检查哪张表


pt-table-checksum performs an online replication consistency check by executing

#(执行一个在线的复制一性检查) 它能够在从服务器上检查从服务器的表与主服务器的表,两个数据是否一致的

#(使用单向加密算法,只要两个数据一样,结果也就一样了)(如果主从服务器两边数据不一样,checksum校验码也会不一样)

checksum queries on the master, which produces different results on replicas

that are inconsistent with the master.  The optional DSN specifies the master

host.  The tool's exit status is nonzero if any differences are found, or if any

warnings or errors occur.  For more details, please use the --help option, or

try 'perldoc /usr/bin/pt-table-checksum' for complete documentation.


Usage: pt-table-checksum [OPTIONS] [DSN]        #  [DSN] 指定一下主服务器是谁


Options:


  --[no]check-binlog-format        Check that the binlog_format is the same on

                                   all servers (default yes)

  --[no]check-plan                 Check query execution plans for safety (

                                   default yes)

  --chunk-index=s                  Prefer this index for chunking tables

  --chunk-index-columns=i          Use only this many left-most columns of a --

                                   chunk-index

  --chunk-size=z                   Number of rows to select for each checksum

                                   query (default 1000)

  --chunk-time=f                   Adjust the chunk size dynamically so each

                                   checksum query takes this long to execute (

                                   default 0.5)

  --[no]create-replicate-table     Create the --replicate database and table if

                                   they do not exist (default yes)

  --[no]empty-replicate-table      Delete previous checksums for each table

                                   before checksumming the table (default yes)

  --float-precision=i              Precision for FLOAT and DOUBLE number-to-

                                   string conversion

  --function=s                     Hash function for checksums (FNV1A_64,

                                   MURMUR_HASH, SHA1, MD5, CRC32, etc)

  --pid=s                          Create the given PID file

  --progress=a                     Print progress reports to STDERR (default

                                   time,30)

  --quiet                      -q  Print only the most important information (

                                   disables --progress) (default 0)

  --recurse=i                      Number of levels to recurse in the hierarchy

                                   when discovering replicas

  --recursion-method=a             Preferred recursion method for discovering

                                   replicas. pt-table-checksum performs several

                                   REPLICA CHECKS before and while running (

                                   default processlist,hosts)

  --replicate=s                    Write checksum results to this table (

                                   default percona.checksums)

  --[no]replicate-check            Check replicas for data differences after

                                   finishing each table (default yes)

  --replicate-check-only           Check replicas for consistency without

                                   executing checksum queries

  --replicate-database=s           USE only this database

  --resume                         Resume checksumming from the last completed

                                   chunk (disables --[no]empty-replicate-table)

  --retries=i                      Retry a chunk this many times when there is

                                   a nonfatal error (default 2)

  --run-time=m                     How long to run.  Optional suffix s=seconds,

                                   m=minutes, h=hours, d=days; if no suffix, s

                                   is used.

  --separator=s                    The separator character used for

                                   CONCAT_WS() (default #)

  --trim                           Add TRIM() to VARCHAR columns (helps when

                                   comparing 4.1 to >= 5.0)

  --[no]version-check              Check for the latest version of Percona

                                   Toolkit, MySQL, and other programs (default

                                   yes)

  --where=s                        Do only rows matching this WHERE clause


Config:


  --config=A                       Read this comma-separated list of config

                                   files; if specified, this must be the first

                                   option on the command line


Connection:


  --ask-pass                       Prompt for a password when connecting to

                                   MySQL

  --defaults-file=s            -F  Only read mysql options from the given file

  --host=s                     -h  Host to connect to (default localhost)

  --password=s                 -p  Password to use when connecting

  --port=i                     -P  Port number to use for connection

  --set-vars=A                     Set the MySQL variables in this comma-

                                   separated list of variable=value pairs

  --socket=s                   -S  Socket file to use for connection

  --user=s                     -u  User for login if not current user


Filter:


  --columns=a                  -c  Checksum only this comma-separated list of

                                   columns

  --databases=h                -d  Only checksum this comma-separated list of

                                   databases

  --databases-regex=s              Only checksum databases whose names match

                                   this Perl regex

  --engines=h                  -e  Only checksum tables which use these storage

                                   engines

  --ignore-columns=H               Ignore this comma-separated list of columns

                                   when calculating the checksum

  --ignore-databases=H             Ignore this comma-separated list of databases

  --ignore-databases-regex=s       Ignore databases whose names match this Perl

                                   regex

  --ignore-engines=H               Ignore this comma-separated list of storage

                                   engines (default FEDERATED,MRG_MyISAM)

  --ignore-tables=H                Ignore this comma-separated list of tables

  --ignore-tables-regex=s          Ignore tables whose names match the Perl

                                   regex

  --tables=h                   -t  Checksum only this comma-separated list of

                                   tables

  --tables-regex=s                 Checksum only tables whose names match this

                                   Perl regex


Help:


  --help                           Show help and exit

  --version                        Show version and exit


Output:


  --explain                        Show, but do not execute, checksum queries (

                                   disables --[no]empty-replicate-table) (

                                   default 0)


Safety:


  --[no]check-replication-filters  Do not checksum if any replication filters

                                   are set on any replicas (default yes)

  --[no]check-slave-tables         Checks that tables on slaves exist and have

                                   all the checksum --columns (default yes)

  --chunk-size-limit=f             Do not checksum chunks this much larger than

                                   the desired chunk size (default 2.0)


Throttle:


  --check-interval=m               Sleep time between checks for --max-lag (

                                   default 1).  Optional suffix s=seconds, m=

                                   minutes, h=hours, d=days; if no suffix, s is

                                   used.

  --check-slave-lag=s              Pause checksumming until this replica's lag

                                   is less than --max-lag

  --max-lag=m                      Pause checksumming until all replicas' lag

                                   is less than this value (default 1s).

                                   Optional suffix s=seconds, m=minutes, h=

                                   hours, d=days; if no suffix, s is used.

  --max-load=A                     Examine SHOW GLOBAL STATUS after every

                                   chunk, and pause if any status variables are

                                   higher than the threshold (default

                                   Threads_running=25)


Option types: s=string, i=integer, f=float, h/H/a/A=comma-separated list, d=DSN, z=size, m=time


Rules:


  This tool accepts additional command-line arguments. Refer to the SYNOPSIS and usage information for details.


DSN syntax is key=value[,key=value...]  Allowable DSN keys:


  KEY  COPY  MEANING

  ===  ====  =============================================

  A    yes   Default character set

  D    no    DSN table database

  F    yes   Defaults file for connection values

  P    yes   Port number to use for connection

  S    no    Socket file to use for connection

  h    yes   Connect to host

  p    yes   Password to use when connecting

  t    no    DSN table table

  u    yes   User for login if not current user


  If the DSN is a bareword, the word is treated as the 'h' key.


Options and values after processing arguments:


  --ask-pass                       FALSE

  --check-binlog-format            TRUE

  --check-interval                 1

  --check-plan                     TRUE

  --check-replication-filters      TRUE

  --check-slave-lag                (No value)

  --check-slave-tables             TRUE

  --chunk-index                    (No value)

  --chunk-index-columns            (No value)

  --chunk-size                     1000

  --chunk-size-limit               2.0

  --chunk-time                     0.5

  --columns                        (No value)

  --config                         /etc/percona-toolkit/percona-toolkit.conf,/etc/percona-toolkit/pt-table            -checksum.conf,/root/.percona-toolkit.conf,/root/.pt-table-checksum.conf

  --create-replicate-table         TRUE

  --databases                      (No value)

  --databases-regex                (No value)

  --defaults-file                  (No value)

  --empty-replicate-table          TRUE

  --engines                        (No value)

  --explain                        0

  --float-precision                (No value)

  --function                       (No value)

  --help                           TRUE

  --host                           localhost

  --ignore-columns

  --ignore-databases

  --ignore-databases-regex         (No value)

  --ignore-engines                 FEDERATED,MRG_MyISAM

  --ignore-tables                  percona.checksums

  --ignore-tables-regex            (No value)

  --max-lag                        1

  --max-load                       Threads_running=25

  --password                       (No value)

  --pid                            (No value)

  --port                           (No value)

  --progress                       time,30

  --quiet                          0

  --recurse                        (No value)

  --recursion-method               processlist,hosts

  --replicate                      percona.checksums

  --replicate-check                TRUE

  --replicate-check-only           FALSE

  --replicate-database             (No value)

  --resume                         FALSE

  --retries                        2

  --run-time                       (No value)

  --separator                      #

  --set-vars

  --socket                         (No value)

  --tables                         (No value)

  --tables-regex                   (No value)

  --trim                           FALSE

  --user                           (No value)

  --version                        FALSE

  --version-check                  TRUE

  --where                          (No value)

[root@node2 ~]#

pt-ioprofile          #可以评估一下服务器的io能力的,当前硬盘的io能力



SSL: 加密传输        只要启用ssl功能,配置证书,就行了

Dual MASTER: 双主模型

设置主-主复制:

1、在两台服务器上各自建立一个具有复制权限的用户;

2、修改配置文件:

# 主服务器上

[mysqld]

server-id = 10

log-bin = mysql-bin                 #每个节点都要启用二进制日志

relay-log = relay-mysql            #每个节点都要启用中继日志文件

relay-log-index = relay-mysql.index           #每个节点都要启用中继日志文件索引

 #自动增长时,为了避免两个服务器数据库将来合并时发生冲突,一个库中的表应该使用奇数,另一个库中的表应该使用偶数,offset=1表示从1开始,increment 表示每次跳2个,

auto-increment-increment = 2           

auto-increment-offset = 1


# 第二个主服务器上

[mysqld]

server-id = 20

log-bin = mysql-bin

relay-log = relay-mysql

relay-log-index = relay-mysql.index

auto-increment-increment = 2

auto-increment-offset = 2


3、如果此时两台服务器均为新建立,且无其它写入操作,各服务器只需记录当前自己二进制日志文件及事件位置,以之作为另外的服务器复制起始位置即可

# 两台服务器启动,两台服务器启动以后,分别记录下来每一个节点的MASTER状态,当前的二进制日志文件以及日志位置,

server1|mysql> SHOW MASTER STATUS\G

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

            File: mysql-bin.000001

        Position: 710

    Binlog_Do_DB: 

Binlog_Ignore_DB: 

1 row in set (0.00 sec)

#另外一个节点的二进制日志文件以及日志位置

server2|mysql> SHOW MASTER STATUS\G

mysql> SHOW MASTER STATUS\G

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

            File: mysql-bin.000003

        Position: 811

    Binlog_Do_DB: 

Binlog_Ignore_DB: 

1 row in set (0.00 sec)


4、各服务器接下来指定对另一台服务器为自己的主服务器即可:

#分别以对方的 > SHOW MASTER STATUS 显示的文件及位置作为自己复制的时候所处的位置

server1|mysql> CHANGE MASTER TO ...,MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=811


server2|mysql> CHANGE MASTER TO ...,MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=710



A: 查看B的二进制日志文件及位置,并以此作为自己的复制起点;

B:与A类似,一个道理    查看A的二进制日志文件及位置,并以此作为自己的复制起点;



主服务器所有操作都复制到从服务器上了,事实上我们可以实现复制过滤,让从服务器只复制主服务器上的某个数据库(某些数据库),,甚至可以只复制某个表(某些表)


自动完成ssl的复制,当然要mysql支持ssl的功能,  

在第一个节点node1 192.168.0.46 上 主服务器

mysql> show global variables like '%ssl%';        #跟ssl相关的全局变量   要想让它们永久有效,必须要写在配置文件当中

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

| Variable_name | Value    |

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

| have_openssl  | DISABLED |        #有openssl ,禁用了,,使用ssl,要启用,,,前提是要使用ssl的功能,改成ENABLED 或 ON

| have_ssl      | DISABLED |       #有ssl ,禁用了,,使用ssl,要启用,,,前提是要使用ssl的功能,改成ENABLED 或 ON

| ssl_ca        |          |

| ssl_capath    |          |

| ssl_cert      |          |            #mysql自己的证书

| ssl_cipher    |          |            #加密算法

| ssl_key       |          |            #自己的私钥

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

7 rows in set (0.00 sec)

服务器端要向客户端联系的时候,要向客户端提供证书的话,服务器端要配置ca(配置服务器端所使用的ca的证书文件),ca的路径(如果服务器端要使用n个ca,在某个目录下放上ca的证书,然后把目录指向这个路径,这个路径下的每一个证书都可以使用了)

mysql>


在第一个节点node1 192.168.0.46 上 主服务器

从服务器到主服务器复制是使用了一个用户来授权的

mysql> help grant

Name: 'GRANT'

Description:

Syntax:

GRANT

    priv_type [(column_list)]

      [, priv_type [(column_list)]] ...

    ON [object_type] priv_level

    TO user_specification [, user_specification] ...

    [REQUIRE {NONE | ssl_option [[AND] ssl_option] ...}]        #REQUIRE  后面可以跟 ssl_option 

# grant replication slave on *.* to 'repluser'@'192.168.%.%' identified by 'replpass' require ssl;表示这个ssl,从服务器过来复制的时候,使用这个帐号密码,如果从服务器不使用ssl的话,不予响应   ( 如果不加  require ssl,我们虽然启用了ssl功能,但是从服务器复制时,可以使用ssl,也可以不不使用ssl );;;;;(当然我们使用ssl,可能会带来许我额外的开销的)

    [WITH with_option ...]


GRANT PROXY ON user_specification

    TO user_specification [, user_specification] ...

    [WITH GRANT OPTION]


object_type:

    TABLE

  | FUNCTION

  | PROCEDURE


priv_level:

    *

  | *.*

  | db_name.*

  | db_name.tbl_name

  | tbl_name

  | db_name.routine_name


user_specification:

    user

    [

        IDENTIFIED BY [PASSWORD] 'password'

      | IDENTIFIED WITH auth_plugin [AS 'auth_string']

    ]


ssl_option:        

    SSL        #授权时这个选项,表示使用ssl

  | X509

  | CIPHER 'cipher'

  | ISSUER 'issuer'

  | SUBJECT 'subject'


with_option:

    GRANT OPTION

  | MAX_QUERIES_PER_HOUR count

  | MAX_UPDATES_PER_HOUR count

  | MAX_CONNECTIONS_PER_HOUR count

  | MAX_USER_CONNECTIONS count


The GRANT statement grants privileges to MySQL user accounts. GRANT

also serves to specify other account characteristics such as use of

secure connections and limits on access to server resources. To use

GRANT, you must have the GRANT OPTION privilege, and you must have the

privileges that you are granting.


Normally, a database administrator first uses CREATE USER to create an

account, then GRANT to define its privileges and characteristics. For

example:


CREATE USER 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';

GRANT ALL ON db1.* TO 'jeffrey'@'localhost';

GRANT SELECT ON db2.invoice TO 'jeffrey'@'localhost';

GRANT USAGE ON *.* TO 'jeffrey'@'localhost' WITH MAX_QUERIES_PER_HOUR 90;


However, if an account named in a GRANT statement does not already

exist, GRANT may create it under the conditions described later in the

discussion of the NO_AUTO_CREATE_USER SQL mode.


The REVOKE statement is related to GRANT and enables administrators to

remove account privileges. See [HELP REVOKE].


When successfully executed from the mysql program, GRANT responds with

Query OK, 0 rows affected. To determine what privileges result from the

operation, use SHOW GRANTS. See [HELP SHOW GRANTS].


URL: http://dev.mysql.com/doc/refman/5.5/en/grant.html



mysql>



普通分类: