本文共 9024 字,大约阅读时间需要 30 分钟。
Mysql 中有一种日志叫做 bin 日志(二进制日志)。这个日志会记录下所有修改了数据库的SQL 语句(insert,update,delete,create/alter/drop table, grant 等等)。
主从复制的原理其实就是把主服务器上的 bin 日志复制到从服务器上执行一遍,这样从服务器上的数据就和主服务器上的数据相同了。
- 主节点必须启用二进制日志,记录任何修改了数据库数据的事件。
- 从节点开启一个线程(I/O Thread)把自己扮演成 mysql 的客户端,通过 mysql 协议,请求主节点的二进制日志文件中的事件
- 主节点启动一个线程(dump Thread),检查自己二进制日志中的事件,跟对方请求的位置对比,如果不带请求位置参数,则主节点就会从第一个日志文件中的第一个事件一个一个发送给从节点。
- 从节点接收到主节点发送过来的数据把它放置到中继日志(Relay log)文件中。并记录该次请求到主节点的具体哪一个二进制日志文件内部的哪一个位置。
- 从节点启动另外一个线程(sql Thread ),把 Relay log 中的事件读取出来,并在本地再执行一次。
从节点:
- I/O Thread: 从 Master 节点请求二进制日志事件,并保存于中继日志中。
- Sql Thread: 从Relay log 中读取日志事件并在本地完成重放。
主节点:
- Dump Thread:为每个 Slave 的 I/O Thread 启动一个 dump 线程,用于向从节点发送二进制事件。
思考:从节点需要建立二进制日志文件吗?
看情况,如果从节点需要作为其他节点的主节点时,是需要开启二进制日志文件的。这种情况叫做级联复制。如果只是作为从节点,则不需要创建二进制文件。
server-id
:为主服务器A的ID值 log-bin
:二进制变更日值server-id=1log-bin=mysql-bin
[root@server1 data]# vim /etc/my.cnf####[mysqld]datadir=/usr/local/mysql/datasocket=/usr/local/mysql/data/mysql.socksymbolic-links=0server-id=1 log-bin=mysql-bin ####
[root@server1 data]# /etc/init.d/mysqld restart //重启mysqlShutting down MySQL.. SUCCESS! Starting MySQL. SUCCESS! [root@server1 data]# ls //出现了二进制日志auto.cnf ib_logfile0 mysql-bin.index server1.pidca-key.pem ib_logfile1 mysql.sock server-cert.pemca.pem ibtmp1 mysql.sock.lock server-key.pemclient-cert.pem mysql performance_schema sysclient-key.pem mysql-bin.000001 private_key.pemib_buffer_pool mysql-bin.000002 public_key.pemibdata1 mysql-bin.000003 server1.err[root@server1 data]# mysql -pwestos @@@@mysql> grant REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED BY 'westos'; //进行授权Query OK, 0 rows affected, 1 warning (0.01 sec)mysql> show master status; //查看主库的状态+------------------+----------+--------------+------------------+-------------------+| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |+------------------+----------+--------------+------------------+-------------------+| mysql-bin.000003 | 437 | | | |+------------------+----------+--------------+------------------+-------------------+1 row in set (0.00 sec)mysql> show master status\G;*************************** 1. row *************************** File: mysql-bin.000003 Position: 437 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 1 row in set (0.00 sec)ERROR: No query specified@@@@
/usr/local/mysql/data
scp给作为slave的server2;(还有相应的脚本) 做完这一步之后,要记得在slave删除其中的data目录; 在slave上进行初始化,写入数据,生成数据目录datalog_bin = mysql-binserver_id = 2relay_log = mysql-relay-binlog_slave_updates = 1read_only = 1
- server_id:是必须的,而且唯一。
- log_bin:slave没有必要开启二进制日志bin_log,但是在一些情况下,必须设置,例如,如果slave为其它slave的master,必须设置bin_log。在这里,我们开启了二进制日志,而且显示的命名(默认名称为hostname,但是,如果hostname改变则会出现问题)。
- relay_log:配置中继日志,log_slave_updates表示slave将复制事件写进自己的二进制日志(后面会看到它的用处)。 有些人开启了slave的二进制日志,却没有设置log_slave_updates,然后查看slave的数据是否改变,这是一种错误的配置。
- read_only:尽量使用read_only,它防止改变数据(除了特殊的线程)。但是,read_only并是很实用,特别是那些需要在slave上创建表的应用。
[root@server2 data]# vim /etc/my.cnf####[mysqld]datadir=/usr/local/mysql/datasocket=/usr/local/mysql/data/mysql.socksymbolic-links=0server-id=2####[root@server2 data]# /etc/init.d/mysqld restart //重启Shutting down MySQL. SUCCESS! Starting MySQL. SUCCESS!
[root@server2 data]# mysql -pwestos@@@@mysql> CHANGE MASTER TO MASTER_HOST='172.25.21.2',MASTER_USER='repl',MASTER_PASSWORD='westos',MASTER_LOG_FILE='mysql-bin.000003',MASTER_LOG_POS=437;Query OK, 0 rows affected, 2 warnings (0.03 sec)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: 172.25.21.2 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000003 Read_Master_Log_Pos: 437 Relay_Log_File: server2-relay-bin.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: mysql-bin.000003 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: 437 Relay_Log_Space: 529 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: 0Master_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 Master_UUID: d9624fe3-99a2-11eb-aa09-5254005fb835 Master_Info_File: /usr/local/mysql/data/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: 1 row in set (0.00 sec)ERROR: No query specified@@@@
[root@server1 data]# mysqlbinlog mysql-bin.000003/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;DELIMITER /*!*/;# at 4#210410 10:27:12 server id 1 end_log_pos 123 CRC32 0xdba41e46 Start: binlog v 4, server v 5.7.31-log created 210410 10:27:12 at startup# Warning: this binlog is either in use or was not closed properly.ROLLBACK/*!*/;BINLOG 'AA1xYA8BAAAAdwAAAHsAAAABAAQANS43LjMxLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADXFgEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQAAUYepNs='/*!*/;# at 123#210410 10:27:12 server id 1 end_log_pos 154 CRC32 0xc64880cd Previous-GTIDs# [empty]# at 154#210410 10:28:40 server id 1 end_log_pos 219 CRC32 0x1be471a7 Anonymous_GTID last_committed=0 sequence_number=1 rbr_only=noSET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;# at 219#210410 10:28:40 server id 1 end_log_pos 437 CRC32 0x256f4fcf Query thread_id=2 exec_time=0 error_code=0SET TIMESTAMP=1618021720/*!*/;SET @@session.pseudo_thread_id=2/*!*/;SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;SET @@session.sql_mode=1436549152/*!*/;SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;/*!\C utf8 *//*!*/;SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;SET @@session.lc_time_names=0/*!*/;SET @@session.collation_database=DEFAULT/*!*/;GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED WITH 'mysql_native_password' AS '*28C1E2BE21B45562A34B6CC34A19CFAFC2F88F96'/*!*/;SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;DELIMITER ;# End of log file/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@server1 data]# mysql -pwestosmysql> create database westos;Query OK, 1 row affected (0.01 sec)mysql> show databases;+--------------------+| Database |+--------------------+| information_schema || mysql || performance_schema || sys || westos |+--------------------+5 rows in set (0.00 sec)
[root@server2 data]# mysql -pwestosmysql> show databases;+--------------------+| Database |+--------------------+| information_schema || mysql || performance_schema || sys |+--------------------+4 rows in set (0.00 sec)mysql> show databases; //复制成功+--------------------+| Database |+--------------------+| information_schema || mysql || performance_schema || sys || westos | //复制+--------------------+5 rows in set (0.00 sec)
~~server2作初始化
直接server1把etc下的my。cnf发给server2 还有个脚本也要发送改server2的环境变量
。/bash——profileserver2生成用户,初始化
4。 server1也启动mysql
做server1和server2的数据同步
server1在ect/my。cnf写入2行数据 重启restart 登陆mysql grantmysql-bin。000:记录所有对数据库的操作
mysql-bin。index二进制索引文件,记录所有二进制日志5。 server2(做为从)
etc/my。cnf变更,写一行 不是rpm包,用脚本重启(不能用systemctl) 进入mysql (备份数据mysqldump)~~转载地址:http://vpsv.baihongyu.com/