MariaDB/MySQL内建的复制功能是构建大型,高性能应用程序的基础。将MySQL的数据分布到多个系统上去,这种分布的机制,是经过将MySQL的某一台主机的数据复制到其它主机(slaves)上,并从新执行一遍来实现的。复制过程当中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志能够记录发送到从服务器的更新。当一个从服务器链接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,而后封锁并等待主服务器通知新的更新。
请注意当你进行复制时,全部对复制中的表的更新必须在主服务器上进行。不然,你必需要当心,以免用户对主服务器上的表进行的更新与对从服务器上的表所进行的更新之间的冲突。mysql
1.mysql支持的复制类型:linux
(1):基于语句的复制:在主服务器上执行的SQL语句,在从服务器上执行一样的语句。MySQL默认采用基于语句的复制,效率比较高。
一旦发现无法精确复制时,会自动选着基于行的复制。
(2):基于行的复制:把改变的内容复制过去,而不是把命令在从服务器上执行一遍. 从mysql5.0开始支持
(3):混合类型的复制: 默认采用基于语句的复制,一旦发现基于语句的没法精确的复制时,就会采用基于行的复制。sql
2.复制解决的问题shell
MySQL复制技术有如下一些特色:
(1).数据分布 (Data distribution )
(2).负载平衡(load balancing)
(3).备份(Backups)
(4).高可用性和容错行 High availability and failover数据库
3.复制如何工做vim
总体上来讲,复制有3个步骤:
(1).master将改变记录到二进制日志(binary log)中(这些记录叫作二进制日志事件,binary log events);
(2).slave将master的binary log events拷贝到它的中继日志(relay log);
(3).slave重作中继日志中的事件,将改变反映它本身的数据。
缓存
该过程的第一部分就是master记录二进制日志。在每一个事务更新数据完成以前,master在二日志记录这些改变。MySQL将事务串行的写入二进制日志,即便事务中的语句都是交叉执行的。在事件写入二进制日志完成后,master通知存储引擎提交事务。安全
下一步就是slave将master的binary log拷贝到它本身的中继日志。首先,slave开始一个工做线程――I/O线程。I/O线程在master上打开一个普通的链接,而后开始binlog dump process。Binlog dump process从master的二进制日志中读取事件,若是已经跟上master,它会睡眠并等待master产生新的事件。I/O线程将这些事件写入中继日志。服务器
SQL slave thread(SQL从线程)处理该过程的最后一步。SQL线程从中继日志读取事件,并重放其中的事件而更新slave的数据,使其与master中的数据一致。只要该线程与I/O线程保持一致,中继日志一般会位于OS的缓存中,因此中继日志的开销很小。tcp
此外,在master中也有一个工做线程:和其它MySQL的链接同样,slave在master中打开一个链接也会使得master开始一个线程。复制过程有一个很重要的限制――复制在slave上是串行化的,也就是说master上的并行更新操做不能在slave上并行操做。
二.复制配置过程简介
有两台MySQL数据库服务器MASTER和SLAVE,MASTER为主服务器,SLAVE为从服务器,初始状态时,MASTER和MASTER中的数据信息相同,当MASTER中的数据发生变化时,SLAVE也跟着发生相应的变化,使得MASTER和SLAVE的数据信息同步,达到备份的目的。
要点:
负责在主、从服务器传输各类修改动做的媒介是主服务器的二进制变动日志,这个日志记载着须要传输给从服务器的各类修改动做。所以,主服务器必须激活二进制日志功能。从服务器必须具有足以让它链接主服务器并请求主服务器把二进制变动日志传输给它的权限。
配置主从复制的过程:
1).主节点操做步骤
(1)、启用二进制日志
(2)、设置一个在当前集群中惟一的server-id;
(3)、建立一个有复制权限(replication slave,replication client)账号;
2).slave节点的操做步骤
(1)、启用中继日志;
(2)、设置一个在当前集群中惟一的server-id;
(3)、使用有复制权限的用户账号链接至主服务器,并启动复制线程;
注意:
(1)、服务器版本:主从服务器版本一致;
若是版本不一致,必须保证从服务器的版本高于主服务器的版本;
(2)、若是mysql数据库的隔离级别为可读,其二进制日志格式尽可能使用基于行的;
实验环境:
服务器版本为:CentOS 7.2
实验拓扑图
关闭SELinux
setenforce = 0
vim /etc/systemctl/selinux
SELINUX=permissive
开启防火墙服务
systemctl mask iptables
firewall-cmd --permanent --add-service=mysql
firewall-cmd --reload
数据库软件版本为:
mariadb-5.5.46-linux-x86_64.tar.gz
MASTER的IP地址:192.168.1.10/24
SLAVE1的IP地址:192.168.1.20/24
SLAVE2的IP地址:192.168.1.30/24
若master数据库已运行一段时间,可导出master数据库内容,使用scp命令拷贝至从服务器并导入
具体命令以下:
mysqldump -uroot -p --quick --all-databases --flush-logs --delete-master-logs --single-transaction > sync.sql #导出数据库 scp sync.sql root@slave1:/mydata #拷贝至从服务器 mysql -uroot -p <sync.sql #导入至从服务器
安装Mariadb通用二进制包
下载二进制包:
]# wget http://mirrors.neusoft.edu.cn/mariadb//mariadb-5.5.56/bintar-linux-x86_64/mariadb-5.5.56-linux-x86_64.tar.gz ]# tar xf mariadb-5.5.56-linux-x86_64.tar.gz -C /usr/local
(1).新建数据库目录,并设置属主属组
]# mkdir /mydata/{data,binlogs} -pv mkdir: created directory ‘/mydata’ mkdir: created directory ‘/mydata/data’ mkdir: created directory ‘/mydata/binlogs’ ]# chown mysql.mysql /mydata -R
(2).新建用户并配置安装包属主为mysql
]# useradd -r -s /sbin/nologin mysql ]# id mysql uid=992(mysql) gid=990(mysql) groups=990(mysql) ]# cd /usr/local ]# chown mysql.root mariadb-5.5.56-linux-x86_64/ -R
(3).连接安装包目录为mysql(便于管理)
]# ln -sv mariadb-5.5.56-linux-x86_64/ mysql ‘mysql’ -> ‘mariadb-5.5.56-linux-x86_64/’ ]# ll mysql/ total 176 drwxr-xr-x. 2 mysql root 4096 May 22 19:47 bin -rw-r--r--. 1 mysql root 17987 Apr 30 19:09 COPYING drwxr-xr-x. 3 mysql root 17 May 22 19:47 data -rw-r--r--. 1 mysql root 8245 Apr 30 19:09 EXCEPTIONS-CLIENT drwxr-xr-x. 3 mysql root 18 May 22 19:47 include -rw-r--r--. 1 mysql root 8694 Apr 30 19:09 INSTALL-BINARY drwxr-xr-x. 3 mysql root 4096 May 22 19:47 lib drwxr-xr-x. 4 mysql root 28 May 22 19:47 man drwxr-xr-x. 11 mysql root 4096 May 22 19:47 mysql-test -rw-r--r--. 1 mysql root 108813 Apr 30 19:09 README drwxr-xr-x. 2 mysql root 29 May 22 19:47 scripts drwxr-xr-x. 27 mysql root 4096 May 22 19:47 share drwxr-xr-x. 4 mysql root 4096 May 22 19:47 sql-bench drwxr-xr-x. 3 mysql root 4096 May 22 19:47 support-files
(4).拷贝并编辑my.cnf文件
]# cp support-files/my-large.cnf /etc/my.cnf cp: overwrite ‘/etc/my.cnf’? y master ]# vim /etc/my.cnf log-bin=/mydata/binlogs/mysql-bin datadir=/mydata/data skip_name_resolve=on innodb_file_per_table=on
(5).初始化数据库并查看生成的文件
]# scripts/mysql_install_db --user=mysql --datadir=/myata/data ]# ls /mydata/{data,binlogs} /mydata/binlogs: mysql-bin.000001 mysql-bin.000002 mysql-bin.index /mydata/data: aria_log.00000001 aria_log_control mysql performance_schema test
(6).连接mysql运行所需的头文件与库文件
]# ln -sv /usr/local/mysql/include/ /usr/include/mysql ‘/usr/include/mysql’ -> ‘/usr/local/mysql/include/’ 指定动态连接库文件搜寻目录 [root@master mysql]# vim /etc/ld.so.conf.d/mysql /usr/local/mysql/lib ]# ldconfig ]# ldconfig -p | grep mysql 查看动态连接库文件 libmysqld.so.18 (libc6,x86-64) => /usr/local/mysql/lib/libmysqld.so.18 libmysqld.so (libc6,x86-64) => /usr/local/mysql/lib/libmysqld.so libmysqlclient.so.18 (libc6,x86-64) => /usr/lib64/mysql/libmysqlclient.so.18 libmysqlclient.so.18 (libc6,x86-64) => /usr/local/mysql/lib/libmysqlclient.so.18 libmysqlclient.so (libc6,x86-64) => /usr/local/mysql/lib/libmysqlclient.so
(7).编辑mariadb启动单元,以systemctl控制
]# vim /etc/systemd/system/mariadb.service [Unit] Description=MariaDB database server After=syslog.target After=network.target [Service] Type=simple User=mysql Group=mysql ExecStart=/usr/local/mysql/bin/mysqld_safe --basedir=/usr/local/mysql TimeoutSec=300 PrivateTmp=false [Install] WantedBy=multi-user.target ]# chmod +x /etc/systemd/system/mariadb.service ]# systemctl daemon-reload #更新守护进程
(8).启动mariadb,并查看端口状态
]# systemctl start mariadb.service #如为未启动成功,再次启动一次便可(缘由未知) ]# ss -nl | grep 3306 tcp LISTEN 0 50 *:3306 *:*
(9).配置系统环境变量
]# vim /etc/profile.d/mysql.sh #profile.d目录下的文件开机会自动执行一次 export PATH=/usr/local/mysql/bin:$PATH ]# source /etc/profile.d/mysql.sh #读取shell脚本 ]# echo $PATH /usr/local/mysql/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
(10).安全初始化数据库
]# mysql_secure_installation Enter current password for root (enter for none): OK, successfully used password, moving on... Set root password? [Y/n] y #是否设置root密码 New password: Re-enter new password: Password updated successfully! Reloading privilege tables.. ... Success! Remove anonymous users? [Y/n] y #是否删除匿名用户 ... Success! Disallow root login remotely? [Y/n] y #是否容许root用户远程登陆 ... Success! Remove test database and access to it? [Y/n] y #是否删除测试数据库 - Dropping test database... ... Success! - Removing privileges on test database... ... Success! Reload privilege tables now? [Y/n] y #是否当即更新权限 ... Success!
(1).编辑master的my.cnf配置文件并重启服务
[root@master mysql]# vim /etc/my.cnf log-bin=/mydata/binlogs/mysql-bin #二进制日志文件路径 datadir=/mydata/data #数据库文件路径 binlog_format=mixed #二进制日志文件保存格式为混合模式(语句,行) server-id = 1 #服务器id号 [root@master mysql]# systemctl restart mariadb.service #重启服务
(2).登陆mysql,并建立有复制权限的用户
[root@master mysql]# mysql -uroot -p MariaDB [(none)]> GRANT REPLICATION CLIENT,REPLICATION SLAVE ON *.* TO 'backup1'@'slave1' IDENTIFIED BY 'backpass'; #建立有复制权限,并制定登陆主机的用户 Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]> SHOW MASTER STATUS; #查看master的日志和pos点 +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000003 | 1832 | | | +------------------+----------+--------------+------------------+
(1).编辑slave1的my.cnf配置文件并重启服务
[root@slave1 mysql]# vim /etc/my.cnf log-bin=/mydata/binlogs/mysql-bin datadir=/mydata/data relay-log=/mydata/binlogs/relay-bin #中继日志文件路径 relay-log_index=/mydata/binlogs/relay-bin.index #中继日志文件索引路径名称 log_slave_updates=on #将复制事件写进本身的二进制日志 skip_name_resolve=on #跳过名称解析 innodb_file_per_table=on #开启innodb引擎独立表空间 read_only=on #开启只读防止改变数据 binlog_format=mixed #二进制日志文件保存格式为混合模式(语句,行) server-id = 2 #id号不得与其余服务器相同 [root@slave1 mysql]# systemctl restart mariadb.service #重启服务
(2)登陆slave1的数据库
[root@slave1 mysql]# mysql -uroot -p MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='master',\ #主服务器主机名称 -> MASTER_USER='backup1',\ #用于复制的用户 -> MASTER_PASSWORD='backpass',\ #复制用户的密码 -> MASTER_PORT=3306,\ #链接使用的端口 -> MASTER_LOG_FILE='mysql-bin.000003',\ #起点日志文件 -> MASTER_LOG_POS=1832,\ #起点位置 -> MASTER_CONNECT_RETRY=10,\ #链接重试间隔 -> MASTER_HEARTBEAT_PERIOD=2; #心跳间隔时间 Query OK, 0 rows affected (0.00 sec)
(3).启动同步并查看从服务器同步状态
MariaDB [(none)]> START SLAVE; #启动同步进程 Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]> SHOW SLAVE STATUS\G #查看从服务器线程的关键参数的信息 *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: master Master_User: backup1 #被用于链接主服务器的当前用户 Master_Port: 3306 Connect_Retry: 10 #链接重试间隔 Master_Log_File: mysql-bin.000003 #I/O线程当前正在读取的主服务器二进制日志文件的名称 Read_Master_Log_Pos: 1832 #在当前的主服务器二进制日志中,I/O线程已经读取的位置 Relay_Log_File: relay-bin.000003 #SQL线程当前正在读取和执行的中继日志文件的名称 Relay_Log_Pos: 529 #在当前的中继日志中,SQL线程已读取和执行的位置 Relay_Master_Log_File: mysql-bin.000003 #由SQL线程执行的包含多数近期事件的主服务器二进制日志文件的名称 Slave_IO_Running: Yes #I/O线程是否被启动并成功地链接到主服务器上 Slave_SQL_Running: Yes #SQL线程是否被启动 ... Master_Server_Id: 2
(4).创建有复制权限的用户,让slave2能够复制本地binlog
MariaDB [(none)]> GRANT REPLICATION CLIENT,REPLICATION SLAVE ON *.* TO 'backup2'@'slave2' IDENTIFIED BY 'backpass'; Query OK, 0 rows affected, 1 warning (0.00 sec) MariaDB [(none)]> SHOW MASTER STATUS; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000003 | 1655 | | | +------------------+----------+--------------+------------------+
(1).编辑slave2的my.cnf配置文件并重启服务
[root@slave2 mysql]# vim /etc/my.cnf datadir=/mydata/data relay-log=/mydata/binlogs/relay-bin #中继日志文件路径 relay-log_index=/mydata/binlogs/relay-bin.index #中继日志文件索引路径名称 log_slave_updates=on #将复制事件写进本身的二进制日志 skip_name_resolve=on #跳过名称解析 innodb_file_per_table=on #开启innodb引擎独立表空间 read_only=on #开启只读防止改变数据 binlog_format=mixed #二进制日志文件保存格式为混合模式(语句,行) server-id = 3 #id号不得与其余服务器相同 [root@slave2 mysql]# systemctl restart mariadb.service #重启服务
(2).登陆slave2数据库
[root@slave1 mysql]# mysql -uroot -p MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='slave1',\ #服务器主机名称 -> MASTER_USER='backup2',\ #用于复制的用户 -> MASTER_PASSWORD='backpass',\ #复制用户的密码 -> MASTER_PORT=3306,\ #链接使用的端口 -> MASTER_LOG_FILE='mysql-bin.000003',\ #起点日志文件 -> MASTER_LOG_POS=1655,\ #起点位置 -> MASTER_CONNECT_RETRY=10,\ #链接重试间隔 -> MASTER_HEARTBEAT_PERIOD=2; #心跳间隔时间 Query OK, 0 rows affected (0.00 sec)
(3)启动同步并查看从服务器同步状态
MariaDB [(none)]> START SLAVE; #启动同步进程 Query OK, 0 rows affected, 1 warning (0.00 sec) MariaDB [(none)]> SHOW SLAVE STATUS\G #查看从服务器线程的关键参数的信息 *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: slave1 Master_User: backup2 Master_Port: 3306 Connect_Retry: 10 Master_Log_File: mysql-bin.000003 Read_Master_Log_Pos: 3038 Relay_Log_File: relay-bin.000002 Relay_Log_Pos: 1912 Relay_Master_Log_File: mysql-bin.000003 Slave_IO_Running: Yes #I/O线程是否被启动并成功地链接到主服务器上 Slave_SQL_Running: Yes #SQL线程是否被启动 ... Master_Server_Id: 2
(1).在主服务器导入数据库(让数据库发生改变便可)
[root@master mysql]# mysql -uroot -p < hellodb.sql #导入数据库文件 [root@master mysql]# mysql -uroot -p MariaDB [(none)]> SHOW DATABASES; #查看数据库 +--------------------+ | Database | +--------------------+ | information_schema | | hellodb | | mysql | | performance_schema | +--------------------+ 4 rows in set (0.00 sec) MariaDB [(none)]> USE hellodb #进入数据库 Database changed MariaDB [hellodb]> SHOW TABLES; #查看表 +-------------------+ | Tables_in_hellodb | +-------------------+ | classes | | coc | | courses | | scores | | students | | teachers | | toc | +-------------------+ 7 rows in set (0.00 sec)
(2).登陆slave2从服务器查看同步是否成功
[root@slave2 mysql]# mysql -uroot -p MariaDB [(none)]> SHOW DATABASES; #查看数据库同步是否更新 +--------------------+ | Database | +--------------------+ | information_schema | | hellodb | | mysql | | performance_schema | +--------------------+ 4 rows in set (0.00 sec) MariaDB [(none)]> USE hellodb; #进入数据库 Database changed MariaDB [hellodb]> SHOW TABLES; #查看表 +-------------------+ | Tables_in_hellodb | +-------------------+ | classes | | coc | | courses | | scores | | students | | teachers | | toc | +-------------------+ 7 rows in set (0.00 sec)
(3).查看slave2的主服务器的pos点,与本地的中继pos点
MariaDB [(none)]> SHOW SLAVE STATUS\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: slave1 Master_User: backup2 Master_Port: 3306 Connect_Retry: 10 Master_Log_File: mysql-bin.000003 Read_Master_Log_Pos: 10718 #在当前的主服务器二进制日志中,I/O线程已经读取的位置已改变 Relay_Log_File: relay-bin.000002 Relay_Log_Pos: 9592 #在当前的中继日志中,SQL线程已读取和执行的位置已改变 Relay_Master_Log_File: mysql-bin.000003 Slave_IO_Running: Yes Slave_SQL_Running: Yes ...
同步成功,读写分离实验待续。。。