1.什么是MySQL主从复制?
mysql主从同步定义
主从同步使得数据可以从一个数据库服务器复制到其他服务器上,在复制数据时,一个服务器充当主服务器(master),其余的服务器充当从服务器(slave)。因为复制是异步进行的,所以从服务器不需要一直连接着主服务器,从服务器甚至可以通过拨号断断续续地连接主服务器。通过配置文件,可以指定复制所有的数据库,某个数据库,甚至是某个数据库上的某个表。
使用主从同步的好处:
- 通过增加从服务器来提高数据库的性能,在主服务器上执行写入和更新,在从服务器上向外提供读功能,可以动态地调整从服务器的数量,从而调整整个数据库的性能。
- 提高数据安全-因为数据已复制到从服务器,从服务器可以终止复制进程,所以,可以在从服务器上备份而不破坏主服务器相应数据
- 在主服务器上生成实时数据,而在从服务器上分析这些数据,从而提高主服务器的性能
2.MySQL主从同步的原理。
Mysql内建的复制功能是构建大型,高性能应用程序的基础。将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的数据复制到其它主机(slaves)上,并重新执行一遍来实现的。复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志可以记录发送到从服务器的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。
简单介绍一下这个图,实现主从同步其实是由三个线程完成的
- 主库和从库进行对接需要的是Io线程
- SQL线程主要是监控relay-log日志,并执行其新增的日志内容
- bin-log dump线程主要是主管log-bin日志
1.slave请求与Master建立连接,请求报文中包括
MASTER_HOST=’192.168.2.200’
MASTER_USER=’rep’
MASTER_PASSWORD=’rep’
MASTER_LOG_FILE=’ mysql-bin.000014’
MASTER_LOG_POS=333’
2.主库IO线程收到请求会将信息发送给bin-log dump 线程
3.bin-log dump线程就会根据信息将对应的log-bin日志传回给Master的IO线程,由Master的IO线程传给salve 的IO线程。
4.salve 中的IO线程就会将传来的信息写入中继日志(relay-log)中.
5.并且将节点写入Master info文件中作为记录
6.SQL监控着中继日志,只要有新数据,就会重新执行新加的SQL语句。
7.SQL线程将数据写入到从库的数据文件中。
3.安装环境
-
[root@localhost ~]# yum install ncurses-devel -y [root@localhost ~]# yum install libaio-devel -y
ncurses-devel:ncurses是字符终端下屏幕控制的基本库。
libaio-devel: linux kernel 提供了5个系统调用来实现异步IO。
安装数据库(这里用cmake安装MySQL5.5版本)
(https://www.cnblogs.com/hanjiali/p/13941511.html中有详细MySQL部署过程,这里就不作过多的介绍,直接操作)
相关数据包在
链接:https://pan.baidu.com/s/1yPYaLIB9M-k5c_U2yxaJ3A
提取码:2vbi
-
24 yum install ncurses-devel -y 25 yum install libaio-devel -y 26 mkdir /tools/ 27 cd /tools/ 28 rz 29 yum install -y lrzsz 30 rz 31 tar xf cmake-2.8.6.tar.gz -C /usr/src/ 32 cd /usr/src/cmake-2.8.6/ 33 ./configure && gmake && gmake install 37 cd /tools/ 38 tar xf mysql-5.5.22.tar.gz -C /usr/src/ 39 cd /usr/src/mysql-5.5.22/ 40 cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS=all -DSYSCONFDIR=/etc && make && make install 41 echo "PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile 42 . /etc/profile 43 /bin/cp -p /usr/src/mysql-5.5.22/support-files/my-medium.cnf /etc/my.cnf 44 /bin/cp -p /usr/src/mysql-5.5.22/support-files/mysql.server /etc/init.d/mysqld 45 chmod +x /etc/init.d/mysqld 46 chkconfig --add mysqld 47 chkconfig mysqld on 48 useradd -M -s /sbin/nologin mysql 49 /usr/local/mysql/scripts/mysql_install_db --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data/ --user=mysql 50 /etc/init.d/mysqld start 51 netstat -anptu|grep 3306 52 mysqladmin -uroot password "123123"
[root@localhost ~]# groupadd mysql
groupadd:“mysql”组已存在
[root@localhost ~]# useradd -s /sbin/nologin -g mysql -M mysql
useradd:用户“mysql”已存在[root@localhost ~]# pkill mysqld
[root@localhost ~]# ps -ef|grep mysql
root 38106 18999 0 18:37 pts/0 00:00:00 grep --color=auto mysql
创建多实例的数据文件目录
-
[root@localhost ~]# mkdir -p /data/{3306,3307}/data [root@localhost ~]# tree /data /data ├── 3306 │ └── data └── 3307 └── data
脚本配置文件进行解压
-
[root@localhost tools]# unzip data.zip Archive: data.zip creating: data/ creating: data/3306/ inflating: data/3306/my.cnf inflating: data/3306/mysql creating: data/3307/ inflating: data/3307/my.cnf inflating: data/3307/mysql [root@localhost tools]# cp data/3306/my.cnf /data/3306/ [root@localhost tools]# cp data/3307/my.cnf /data/3307/ [root@localhost tools]# tree /data/ /data/ ├── 3306 │ ├── data │ └── my.cnf └── 3307 ├── data └── my.cnf 4 directories, 2 files
将启动文件复制到/data下
-
[root@localhost tools]# cp data/3306/mysql /data/3306/ [root@localhost tools]# cp data/3307/mysql /data/3307/ [root@localhost tools]# tree /data /data ├── 3306 │ ├── data │ ├── my.cnf │ └── mysql └── 3307 ├── data ├── my.cnf └── mysql
-
进入3306和3307的my.conf 将配置文件的制动位置改为basedir = /usr/local/mysql/
用户授权
-
[root@localhost ~]# chown -R mysql.mysql /data [root@localhost ~]# find /data/ -type f -name "mysql"|xargs ls -l -rw-r--r-- 1 mysql mysql 1307 11月 17 18:11 /data/3306/mysql -rw-r--r-- 1 mysql mysql 1307 11月 17 18:11 /data/3307/mysql
初始化数据库 创建基础的数据文件(出现两个ok则成功)
-
[root@localhost ~]# cd /usr/local/mysql/ [root@localhost mysql]# ls bin data include lib mysql-test scripts sql-bench COPYING docs INSTALL-BINARY man README share support-files [root@localhost mysql]# cd scripts/ [root@localhost scripts]# ls mysql_install_db
[root@localhost scripts]# ./mysql_install_db --basedir=/usr/local/mysql --datadir=/data/3306/data --user=mysql
Installing MySQL system tables...
OK
Filling help tables...
OK[root@localhost scripts]# ./mysql_install_db --basedir=/usr/local/mysql --datadir=/data/3307/data --user=mysql
Installing MySQL system tables...
OK
Filling help tables...
OK
初始化成功后可以查看一下自己的数据库
-
root@localhost scripts]# tree /data/ /data/ ├── 3306 │ ├── data │ │ ├── mysql │ │ │ ├── columns_priv.frm │ │ │ ├── columns_priv.MYD │ │ │ ├── columns_priv.MYI │ │ │ ├── db.frm │ │ │ ├── db.MYD │ │ │ ├── db.MYI │ │ │ ├── event.frm │ │ │ ├── event.MYD │ │ │ ├── event.MYI │ │ │ ├── func.frm │ │ │ ├── func.MYD │ │ │ ├── func.MYI │ │ │ ├── general_log.CSM │ │ │ ├── general_log.CSV │ │ │ ├── general_log.frm │ │ │ ├── help_category.frm │ │ │ ├── help_category.MYD │ │ │ ├── help_category.MYI │ │ │ ├── help_keyword.frm │ │ │ ├── help_keyword.MYD │ │ │ ├── help_keyword.MYI │ │ │ ├── help_relation.frm │ │ │ ├── help_relation.MYD │ │ │ ├── help_relation.MYI │ │ │ ├── help_topic.frm │ │ │ ├── help_topic.MYD │ │ │ ├── help_topic.MYI │ │ │ ├── host.frm │ │ │ ├── host.MYD │ │ │ ├── host.MYI │ │ │ ├── ndb_binlog_index.frm │ │ │ ├── ndb_binlog_index.MYD │ │ │ ├── ndb_binlog_index.MYI │ │ │ ├── plugin.frm │ │ │ ├── plugin.MYD │ │ │ ├── plugin.MYI │ │ │ ├── proc.frm │ │ │ ├── proc.MYD │ │ │ ├── proc.MYI │ │ │ ├── procs_priv.frm │ │ │ ├── procs_priv.MYD │ │ │ ├── procs_priv.MYI │ │ │ ├── proxies_priv.frm │ │ │ ├── proxies_priv.MYD │ │ │ ├── proxies_priv.MYI │ │ │ ├── servers.frm │ │ │ ├── servers.MYD │ │ │ ├── servers.MYI │ │ │ ├── slow_log.CSM │ │ │ ├── slow_log.CSV │ │ │ ├── slow_log.frm │ │ │ ├── tables_priv.frm │ │ │ ├── tables_priv.MYD │ │ │ ├── tables_priv.MYI │ │ │ ├── time_zone.frm │ │ │ ├── time_zone_leap_second.frm │ │ │ ├── time_zone_leap_second.MYD │ │ │ ├── time_zone_leap_second.MYI │ │ │ ├── time_zone.MYD │ │ │ ├── time_zone.MYI │ │ │ ├── time_zone_name.frm │ │ │ ├── time_zone_name.MYD │ │ │ ├── time_zone_name.MYI │ │ │ ├── time_zone_transition.frm │ │ │ ├── time_zone_transition.MYD │ │ │ ├── time_zone_transition.MYI │ │ │ ├── time_zone_transition_type.frm │ │ │ ├── time_zone_transition_type.MYD │ │ │ ├── time_zone_transition_type.MYI │ │ │ ├── user.frm │ │ │ ├── user.MYD │ │ │ └── user.MYI │ │ ├── mysql-bin.000001 │ │ ├── mysql-bin.000002 │ │ ├── mysql-bin.index │ │ ├── performance_schema │ │ │ ├── cond_instances.frm │ │ │ ├── db.opt │ │ │ ├── events_waits_current.frm │ │ │ ├── events_waits_history.frm │ │ │ ├── events_waits_history_long.frm │ │ │ ├── events_waits_summary_by_instance.frm │ │ │ ├── events_waits_summary_by_thread_by_event_name.frm │ │ │ ├── events_waits_summary_global_by_event_name.frm │ │ │ ├── file_instances.frm │ │ │ ├── file_summary_by_event_name.frm │ │ │ ├── file_summary_by_instance.frm │ │ │ ├── mutex_instances.frm │ │ │ ├── performance_timers.frm │ │ │ ├── rwlock_instances.frm │ │ │ ├── setup_consumers.frm │ │ │ ├── setup_instruments.frm │ │ │ ├── setup_timers.frm │ │ │ └── threads.frm │ │ └── test │ ├── my.cnf │ └── mysql └── 3307 ├── data │ ├── mysql │ │ ├── columns_priv.frm │ │ ├── columns_priv.MYD │ │ ├── columns_priv.MYI │ │ ├── db.frm │ │ ├── db.MYD │ │ ├── db.MYI │ │ ├── event.frm │ │ ├── event.MYD │ │ ├── event.MYI │ │ ├── func.frm │ │ ├── func.MYD │ │ ├── func.MYI │ │ ├── general_log.CSM │ │ ├── general_log.CSV │ │ ├── general_log.frm │ │ ├── help_category.frm │ │ ├── help_category.MYD │ │ ├── help_category.MYI │ │ ├── help_keyword.frm │ │ ├── help_keyword.MYD │ │ ├── help_keyword.MYI │ │ ├── help_relation.frm │ │ ├── help_relation.MYD │ │ ├── help_relation.MYI │ │ ├── help_topic.frm │ │ ├── help_topic.MYD │ │ ├── help_topic.MYI │ │ ├── host.frm │ │ ├── host.MYD │ │ ├── host.MYI │ │ ├── ndb_binlog_index.frm │ │ ├── ndb_binlog_index.MYD │ │ ├── ndb_binlog_index.MYI │ │ ├── plugin.frm │ │ ├── plugin.MYD │ │ ├── plugin.MYI │ │ ├── proc.frm │ │ ├── proc.MYD │ │ ├── proc.MYI │ │ ├── procs_priv.frm │ │ ├── procs_priv.MYD │ │ ├── procs_priv.MYI │ │ ├── proxies_priv.frm │ │ ├── proxies_priv.MYD │ │ ├── proxies_priv.MYI │ │ ├── servers.frm │ │ ├── servers.MYD │ │ ├── servers.MYI │ │ ├── slow_log.CSM │ │ ├── slow_log.CSV │ │ ├── slow_log.frm │ │ ├── tables_priv.frm │ │ ├── tables_priv.MYD │ │ ├── tables_priv.MYI │ │ ├── time_zone.frm │ │ ├── time_zone_leap_second.frm │ │ ├── time_zone_leap_second.MYD │ │ ├── time_zone_leap_second.MYI │ │ ├── time_zone.MYD │ │ ├── time_zone.MYI │ │ ├── time_zone_name.frm │ │ ├── time_zone_name.MYD │ │ ├── time_zone_name.MYI │ │ ├── time_zone_transition.frm │ │ ├── time_zone_transition.MYD │ │ ├── time_zone_transition.MYI │ │ ├── time_zone_transition_type.frm │ │ ├── time_zone_transition_type.MYD │ │ ├── time_zone_transition_type.MYI │ │ ├── user.frm │ │ ├── user.MYD │ │ └── user.MYI │ ├── mysql-bin.000001 │ ├── mysql-bin.000002 │ ├── mysql-bin.index │ ├── performance_schema │ │ ├── cond_instances.frm │ │ ├── db.opt │ │ ├── events_waits_current.frm │ │ ├── events_waits_history.frm │ │ ├── events_waits_history_long.frm │ │ ├── events_waits_summary_by_instance.frm │ │ ├── events_waits_summary_by_thread_by_event_name.frm │ │ ├── events_waits_summary_global_by_event_name.frm │ │ ├── file_instances.frm │ │ ├── file_summary_by_event_name.frm │ │ ├── file_summary_by_instance.frm │ │ ├── mutex_instances.frm │ │ ├── performance_timers.frm │ │ ├── rwlock_instances.frm │ │ ├── setup_consumers.frm │ │ ├── setup_instruments.frm │ │ ├── setup_timers.frm │ │ └── threads.frm │ └── test ├── my.cnf └── mysql 10 directories, 190 files
启动数据库时报错
解决办法是进入/data3306/mysql将路径改为:CmdPath="/usr/local/mysql/bin"
-
[root@localhost 3307]# /data/3306/mysql start MySQL is running... [root@localhost 3307]# /data/3307/mysql start Starting MySQL... [root@localhost 3307]# netstat -lntup|grep 330[6,7] tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 49691/mysqld tcp 0 0 0.0.0.0:3307 0.0.0.0:* LISTEN 50607/mysqld
配置成功
多实例环境进行主从复制(主从同步)
环境搭建
- 3306------>master
- 3307------>slave
将master中的打开并且确定server-id不同
- server-id的值使用服务器IP地址的后8位,避免不同机器的id重复
[root@localhost ~]# egrep "log-bin = /data/3306/mysql-bin|server-id" /data/330{6,7}/my.cnf /data/3306/my.cnf:log-bin = /data/3306/mysql-bin /data/3306/my.cnf:server-id = 1 /data/3307/my.cnf:server-id = 3
如果生效直接会在/data/3306/下生成日志文件
或者 执行如下命令,进行查看
-
[root@localhost 3306]# mysql -uroot -p123123 -P3306 -e "show variables like 'log_bin';"
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
在主的数据库中添加用于从库的账号rep
-
mysql> grant replication slave on *.* to 'rep'@'192.168.2.%' identified by '123123'; Query OK, 0 rows affected (0.00 sec)
-
刷新数据库 mysql> flush privileges; Query OK, 0 rows affected (0.00 sec)
通常来说在备份时要进行锁数据库(这里可以不用锁,现在只是演示,不是必做)
-
mysql> flush table with read lock; Query OK, 0 rows affected (0.00 sec)
锁住之后重新开个窗口
-
[root@localhost ~]# mysqldump -uroot -p123123 -P3306 -A -B --events --master-data=2 >/opt/rep.sql
进入 vim /opt/rep.sql 查看是否有节点
-
- 对主数据库进行解锁,提供服务
mysql> unlock tables; Query OK, 0 rows affected (0.00 sec)
- 主库3306配置完毕,现在配置从库3307,将目标指向从库的3306
-
mysql> CHANGE MASTER TO MASTER_HOST='192.168.2.200', MASTER_USER='rep', MASTER_PASSWORD='rep', MASTER_LOG_FILE='mysql-bin.000014', MASTER_LOG_POS=333; Query OK, 0 rows affected (0.00 sec)
- 报错:
解决方式:停止slave ,然后执行,最后在开启服务。
-
检测是否成功,当主库给发送日志,则master.info会不停的进行更新
- 重启从库
-
mysql> stop slave; Query OK, 0 rows affected (0.00 sec) mysql> start slave; Query OK, 0 rows affected (0.00 sec) mysql> show slave statusG; *************************** 1. row *************************** Slave_IO_State: Connecting to master Master_Host: 192.168.2.200 Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000014 Read_Master_Log_Pos: 333 Relay_Log_File: localhost-relay-bin.000002 Relay_Log_Pos: 4 Relay_Master_Log_File: mysql-bin.000014 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: 333 Relay_Log_Space: 107 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: 1130 Last_IO_Error: error connecting to master 'rep@192.168.2.200:3306' - retry-time: 60 retries: 86400 Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 0 1 row in set (0.00 sec)
两个yes,则说明搭建成功
- 测试
- 在主库中创建一个表,在从库中看是否也得到了更新。