当前位置: 首页 > 后端技术 > PHP

MySQL主从复制《主库已经有数据的解决方案》《几种复制模式》

时间:2023-03-29 19:00:22 PHP

MySQL主从复制架构目前MySQL支持两种复制方式:1.传统方式:基于主库的bin-log,将日志事件和事件位置复制到从库,然后应用从库来达到主从同步的目的。2.Gtid模式(推荐MySQL>=5.7):在基于GTID的复制中,从库会将已经执行过的事务的GTID值通知主库,然后主库返回列表所有未执行的事务的GTIDs到从库,并且可以保证同一个事务在指定的从库中只执行一次。MySQL复制有很多种:1.异步复制    一个主库,一个或多个从库,数据异步同步到从库。2、同步复制    是MySQL集群中特有的复制方式。3.半同步复制    在异步复制的基础上,保证在主库上的任何事务提交之前,至少有一个从库接收到事务并记录在日志中。4.延迟复制    在异步复制的基础上,人为设置了主库和从库的数据同步延迟时间,即保证数据延迟至少为该参数。下面是基于二进制日志点的异步复制:MySQL主从复制原理:我们在MySQL中配置好主从后,只要对Master节点进行写操作,这个操作就会保存到MySQL的binary-log(bin-log)日志,当slave连接上master后,master机器会为slave开启binlogdump线程。当master的binlog发生变化时,master的dump线程会通知slave,并将相应的binlog内容发送给slave。开启主从同步后,Slave节点会创建2个线程,1个I/O线程,1个SQL线程。I/O线程:这个线程链接到master机器。当master机器的binlog发送给slave时,IO线程会将日志内容写入本地的中继日志(Relaylog)中。SQL线程:该线程读取relaylog中的内容,并根据relaylog中的内容对Slave数据库进行相应的操作。可能出现的问题:在大量写请求的情况下,Slave数据可能与Master数据不一致。这是由于日志传输过程中有短暂的延迟,或者大量的写命令,系统速度不匹配造成的。这就是MySQL主从同步的大致原理。binlog和relaylog这两个日志文件其实在其中起到了作用。1.配置主从数据库服务器参数:主服务器参数:[mysqld]log-bin=/www/server/data/mysql-binbinlog_format=mixedserver-id=100#expire_logs_days=10#log过期时间#max_binlog_size=200M#log最大容量不能设置,有默认值。设置后MySQL无法重启。我遇到过这样一种情况,binlog_do_db=test#binlog_do_db指定了记录二进制日志的数据库,也就是需要复制的数据库名。如果复制多个数据库,重复设置该选项2.从服务器参数:[mysqld]log-bin=/www/server/data/mysql-binbinlog_format=mixedserver-id=200#expire_logs_days=10#log过期时间#max_binlog_size=200M#日志的最大容量,可以不设置,有个默认值,设置后MySQL不能重启,我遇到的情况relay_log=/www/server/data/relay-bin#指定存放路径和文件relay_log日志的前缀,如果不指定,默认使用主机名作为前缀默认情况下,主从复制信息存储在文件系统中。如果slaveserver挂了,很容易有文件记录和实际同步信息在不同的情况下,存储在表中可以通过innodb的崩溃恢复机制保证数据记录的一致性主服务器上的帐户:您需要设置REPLICATIONSLAVE权限:CREATEUSER'account'@'2.7.4.5'IDENTIFIEDBY'password';GRANTREPLICATIONSLAVEON*.*TO'repl'@'1.1.1.1';刷新权限;#Refreshprivileges3.对Slave服务器的操作:查看文件名和在showmasterstatus中输入binlogoffset;查看master的binlog文件名和binlog偏移量2.配置从服务器:mysql>CHANGEMASTERTO->MASTER_HOST='1.1.1.1',->MASTER_USER='account',->MASTER_PASSWORD='password',->MASTER_LOG_FILE='mysql-bin.00001',->MASTER_LOG_POS=66;#注意,这里的master_log_file是binlog的文件名,输入上图中的mysql-bin.00001,每个人可能不一样#注意,这里的master_log_pos是binlog的偏移量,输入上图中的66,以及每个人的可能都不一样。4、保持主从数据库中的数据一致(主库已经有数据的解决方法)主从数据库中的数据必须保持一致,否则主从同步会出现bug...解决方法对已经有数据的主库:第一种方案是选择忽略主库之前的数据,不处理。该方案只适用于不重要、可有可无的数据,业务可以容忍主从数据库数据不一致。方案二是备份主库的数据,然后将主库导出的数据导入到从库,然后启动主从复制,保证主从库数据的一致性.下面是第二种方案的操作:锁定主库,只允许读不能写。这样做的目的是防止在备份过程中或备份完成后插入新数据,导致备份数据与主数据不一致。mysql>flushtableswithreadlock;2、通过在mysql主服务器上全量备份初始化从服务器上的数据:[root@localhostdata]#cd/data/db_backup/[root@localhostdb_backup]#mysqldump-uroot-p--master-data=1--single-transaction--routines--triggers--events--all-databases>all.sql输入密码:3.解锁master数据库:unlocktables;4、将所有数据导入从数据库,保证主从数据一致5、启动主从同步:在从服务器的MySQL命令行输入startslave;启用从机同步,然后输入showslavestatus\G;查看slave节点的状态6.注意:如果IO线程一直处于Connecting状态,可以看看两台机器是不是连不上。如果能连上,那可能是slave账号密码写错了。再次关闭slave,输入上面的配置命令开启slave。如果SQL线程处于NO状态,可能是从库和主库数据不一致导致的,或者事务回滚。如果是后者,先关闭stopslave,然后查看master的binlog和position,然后输入配置命令,再输入setGLOBALSQL_SLAVE_SKIP_COUNTER=1;,然后启动slave;再次。如果前者通过,则检查是否有未同步的表,是否存在主库存在但从库不存在的表,自己同步重新配置。Couldnotfindfirstlogfilenameinbinarylogindexfile如果通过查看从库状态发现这个问题,查看主库状态,通过执行以下命令在从库配置中写入File和Position字段从库中的SQL语句。changemastertomaster_log_file='mysql-bin.000001',master_log_pos=3726ERROR1872(HY000):Slavefailedtoinitializerelayloginfostructurefromtherepository如果在启动slave时出现这个错误,主要是因为之前的slave使用了relay-log,可以执行如下语句启动slave。重置奴隶;启动奴隶;七、总结:1、MySQL从5.6开始引入GTID(GlobalTransactionIDs)(MySQL>=5.7在5.7完善,推荐),使复制功能的配置、监控和管理更容易实现,更健壮。配置方法与基于日志的主从复制大致相同,不再赘述。MySQL5.7推荐使用GTID配置主从复制。2、由于高并发,MySQL主从复制会造成主从同步延迟。MySQL在这方面有两种机制,一种是半同步复制,用来解决主库数据丢失的问题;另一种是并行复制,用于解决主从同步延迟问题。具体解决方案将在下一篇文章中讨论。..Mysqlmaster-master半同步一、半同步概述首先了解mysql的几种复制异步复制MySQL复制默认为异步复制,Master将事件写入binlog,提交事务,不知道slave是否接收或处理;缺点:不能保证所有的事务都被所有的slave接收到。同步复制Master提交事务,直到事务在所有slave上都提交完毕后,才会返回客户端事务执行完成信息;缺点:完成交易可能会造成延迟。半同步复制当master开启半同步复制功能时,至少要有一台slave开启半同步复制功能。当master向slave提交事务,事务已经写入relay-log并刷新到磁盘时,slave会通知master已经收到;收到,此时Master会自动切换到异步复制机制;注意:半同步复制功能只有在Master和Slave上开启才有效,只开启一侧,依然是异步复制。下面详细介绍主主半同步:通过mysql的半同步插件,在两个数据库之间设置半同步,实现主主半同步架构。这样做相对于半同步的好处是两个数据库处于完全对等的位置,可以方便地自动切换。需要注意的一点是,建议设置为只读,这样同一时间只能写入一个数据库。如果两者同时写入,如果出现同步不一致,那么数据恢复需要对比两个数据库。自动切换可以使用keepalived做vip1的漂移同步过程,在每个准备提交的事务完成数据更新之前,主库将数据更新事件记录在二进制日志中。MySQL按照事务提交的顺序记录二进制日志。主库记录二进制日志后,会告诉存储引擎事务可以提交了。2、从库会启动一个工作线程,I/O线程会和主库建立一个正常的客户端连接,然后在主库上启动一个特殊的。二进制转储(binlogdump)线程,这个二进制转储线程会读取主库上二进制日志中的事件。如果线程追上了主库,就会进入休眠状态,直到主库发信号通知有新的事件,再次醒来。3、从库的SQL线程从relaylog中读取事件,在从库上执行,完成一半的复制同步相比异步,可以解决不丢数据的问题,但是解决不了切换问题很好。MySQL的默认复制是异步复制。执行完客户端提交的事务后,主库会立即返回结果给客户端。不关心从库是否接收并处理配置自动切换时可能出现的问题:如果主库异常,master上已经提交的事务可能不会同步到从库这个时候,而且此时从库会被强制提升为主库,会导致新的主库上数据不完整。推荐的解决方案是切换可写数据库时检查同步状态。2、配置主主半同步测试环境:数据库mysql5.7。.准备数据库yuminstallmysql-community-servermysql-community-server-5.7.20-1.el7.x86_64注意:安装服务器的时候,客户端也会自动安装。但是安装客户端,而不是安装服务器。使用无密码方法创建数据目录。该目录不得存在。注意:CentOS7中mysql的多实例管理可以直接通过systemctl进行。在my.cnf配置中,section必须有@关键字进行管理,所以也统一使用实例名mysqld--initialize-insecure--user=mysql--datadir=/var/lib/mysqld@3320来创建data目录这里配置my.cnf文件[mysqld@3320]#注意段中一定要有@符号datadir=/var/lib/mysqld@3320#datadirectorysocket=/var/lib/mysqld@3320/mysqld@3320.sockport=3320pid-file=/var/run/mysqld@3320/mysqld@3320.pidlog-error=/var/log/mysqld.logskip-name-resolve=1#bin-log相关配置log-bin=mysql-binbinlog_cache_size=128Kinnodb_flush_log_at_trx_commit=1binlog_format=MIXEDexpire_logs_days=7max_binlog_size=500Mlog-slave-updates=0slave-skip-errors=1062,1032#relay-log配置relay_log_recovery=1relay@-bin-log=mysqld-log配置数据库user=mysqllanguage=/usr/share/mysql/englishdefault-storage-engine=InnoDBcharacter-set-server=UTF8master_info_repository=TABLErelay_log_info_repository=TABLEtmpdir=/var/tmp#设置只读为可读可写read-only=0#mysql5.7必须有server-id才能启动server-id=1然后就可以启动数据库了systemctlstartmysqld@33202。创建用户我们创建数据目录的方式是没有密码的。所以可以直接登录注意:只能使用sock文件登录mysql-uroot-S/var/lib/mysqld@3320/mysqld@3320.sock我们先设置root账户的密码。再创建一个用于配置半同步SETpassword='admin';将*.*上的所有内容授予“admin”标识的“root”@“127.0.0.1”,并带有授予选项;刷新权限;注销重新登录查看root密码是否创建成功grantreplicationclient,replicationslaveon*.*to'SemiSync'@'%'identifiedby'admin';#远程同步账号需要重新加载,超级权限3.安装半同步插件INSTALLPLUGINrpl_semi_sync_masterSONAME'semisync_master.so'INSTALLPLUGINrpl_semi_sync_slaveSONAME'semisync_slave.so'安装插件后可以通过showplugins查看已安装的插件,修改my.cnf配置文件,在文件中添加如下选项#启用binlog,启动半同步sync_binlog=1rpl_semi_sync_master_enabled=1rpl_semi_sync_slave_enabled=1对另一个节点重复上述步骤,创建相同的实例。注意:server_id需要不同,半同步插件也需要安装,因为我们配置的是main-master半同步4.配置半同步设置192.168。先执行showmasterstatuson54,查看binlog文件及其位置,显示如下。注意这一步一定要保证没有写入数据,否则会导致不同步。通常这里会把表锁住,防止产生新的数据,然后设置到40,使用showslavestatus\G查看半同步状态。如果图中最后两行(未截取完整的命令输出)不是Yes,可以在输出命令的Last_IO_Error或Last_SQL_Error选项中查看错误信息。然后这里按照提示进行处理,单向半同步配置好了,然后在另外一个节点上设置同样的半同步。这样就形成了主半同步。现在可以测试数据同步了。