0.目录
目录
5.4解决自动复制失败问题(解决Slave_SQL_Running: No问题)
1.需求及目标
基于Mysql主从复制特性实现双机热备,主机从机均为windows 7(linux可类似以此参考)。
详细配置参数如下
主机A | 从机B | |
IP(固定IP) | 192.168.7.161 | 192.168.7.162 |
Mysql版本号(必须同版本,否则会出兼容性错误) | 5.7.10 for win64 | 5.7.10 for win64 |
操作系统 | Win7 64 | Win7 64 |
待双机热备数据库名称 | dbdemo | dbdemo |
目标如下:
1.实现A机B机互为主从;
2.A机写入后自动复制到B机,B机写入后自动复制到A机,
3.A机宕机期间B机持续写,A机恢复后自动将A机宕机期间B机的写数据自动复制到A机。
4.B机宕机期间A机持续写,B机恢复后自动将B机宕机期间A机的写数据自动复制到B机。
2.安装
主机A及从机B,均安装mysql5.7.10。
安装包为(mysql-installer-community-5.7.10.0.msi)
官方下载地址
https://downloads.mysql.com/archives/community/
https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.10-winx64.zip
阿里云mysql镜像下载地址https://mirrors.aliyun.com/mysql/?spm=a2c6h.13651104.0.0.2e535dc87t2kc0
安装过程不再详细描述,一般next即可。
(安装期间勾选了MySql WorkBench以便后面有UI界面可查询)
3.准备工作-A机器B机器均创建空库空表
建库建表sql如下
CREATE DATABASE IF NOT EXISTS dbdemo;
USE dbdemo;
CREATE TABLE categories(
cat_id int not null auto_increment primary key,
cat_name varchar(255) not null,
cat_description text,
cat_date DATE
);
CREATE TABLE products(
prd_id int not null auto_increment primary key,
prd_name varchar(355) not null,
prd_price decimal,
prd_date DATE,
cat_id int not null,
FOREIGN KEY fk_cat(cat_id)
REFERENCES categories(cat_id)
ON UPDATE CASCADE
ON DELETE RESTRICT
);
手动在A机器的两个表分别各插入一条数据,以做区分标记。
4.主从复制-双机热备配置
4.1主服务器A_创建账户访问B机
主机A,Windows打开cmd,cd到目录【C:\Program Files\MySQL\MySQL Server 5.7\bin】
输入命令【mysql -h localhost -u root -p】按提示输入密码然后回车登录mysql
登录mysql后执行下述命令创建名为replicateuser的账号。
/*
主服务器上的sql
创建用户,准备用于主从复制(AB机器互为主从)
主服务器ip:192.168.7.161
从服务器ip:192.168.7.162
使用grant命令在主服务器上为从服务器创建一个账户,并授予replication slave权限,
*/
grant replication slave on *.* to 'replicateuser'@'192.168.7.162' identified by 'replicateuser';
/*刷新MySQL的系统权限相关表*/
flush privileges;
4.2从服务器B_创建账户访问A机
从机B,cmd登录mysql执行以下命令
/*
从服务器上的sql
创建用户,准备用于主从复制(AB机器互为主从)
主服务器ip:192.168.7.161
从服务器ip:192.168.7.162
使用grant命令在主服务器上为从服务器创建一个账户,并授予replication slave权限,
*/
grant replication slave on *.* to 'replicateuser'@'192.168.7.161' identified by 'replicateuser';
/*刷新MySQL的系统权限相关表*/
flush privileges;
4.3 A机测试新创账号连接B机--通过命令行
4.4 B机测试连接A机--通过命令行
4.5 A机-配置my.ini主从复制参数
进入【C:\ProgramData\MySQL\MySQL Server 5.7】,注意不是【C:\Program Files\MySQL\MySQL Server 5.7】目录找到my.ini,在文件中找到相关项进行配置,如无则直接增加。
#wdh config master-slave replicate
#这是数据库ID,此ID是唯一的,ID值不能重复,否则会同步出错,必须为1 到 2的32次方–1之间的一个正整数值.
server-id=1
#二进制日志文件,此项为必填项,否则不能同步数据;如果不取名字的话,那么就会以计算机的名字加编号来命名二进制文件;
log-bin=mysql-log-bin
#需要同步的数据库,如果还需要同步另外的数据库,那么继续逐条添加,如果不写,那么默认同步所有的数据库;
binlog-do-db=dbdemo
保存my.ini文件后重启mysql服务。
4.6 A机查看是否my.ini配置生效
A机cmd,用命令【mysql -h localhost -u root -p】按提示输入密码后登录mysql。
【show variables like '%log_bin%';】命令下发后查询到log_bin为ON,即可。
【show master status\G;】命令进行查询,查询到的【File: mysql-log-bin.000001】和【Position: 154】此两值后续会用到。
cmd窗口执行的记录如下。
C:\Program Files\MySQL\MySQL Server 5.7\bin>mysql -h localhost -u root -p
Enter password: ****
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.10-log MySQL Community Server (GPL)
Copyright (c) 2000, 2015, 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 variables like '%log_bin%';
+---------------------------------+----------------------------------------------------------------+
| Variable_name | Value |
+---------------------------------+----------------------------------------------------------------+
| log_bin | ON |
| log_bin_basename | C:\ProgramData\MySQL\MySQL Server 5.7\Data\mysql-log-bin |
| log_bin_index | C:\ProgramData\MySQL\MySQL Server 5.7\Data\mysql-log-bin.index |
| log_bin_trust_function_creators | OFF |
| log_bin_use_v1_row_events | OFF |
| sql_log_bin | ON |
+---------------------------------+----------------------------------------------------------------+
6 rows in set, 1 warning (0.00 sec)
mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| mysql-log-bin.000001 | 154 | dbdemo | | |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql> show master status\G;
*************************** 1. row ***************************
File: mysql-log-bin.000001
Position: 154
Binlog_Do_DB: dbdemo
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
ERROR:
No query specified
mysql>
4.7 A机指定同步位置
执行如下三条指令
stop slave;
change master to master_host='192.168.7.162',master_user='replicateuser',master_password='replicateuser',master_log_file='mysql-log-bin.000001',master_log_pos=154;
start slave;
三条命令cmd执行记录如下:
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> change master to master_host='192.168.7.162',master_user='replicateuser',master_password='replicateuser',master_log_file='mysql-log-bin.000001',master_log_pos=154;
Query OK, 0 rows affected, 2 warnings (0.21 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql>
A机命令
change master to master_host='192.168.7.162',master_user='replicateuser',master_password='replicateuser',master_log_file='mysql-log-bin.000001',master_log_pos=154;
参数说明如下:
A机命令 | A机命令值示例 | A机命令值含义 |
master_host | '192.168.7.162' | 填入B机的IP地址(注意是B机) |
master_password | 'replicateuser' | 填入B机上的同步账号 |
master_log_file | 'mysql-log-bin.000001' | 从B机上执行【show master status\G;】命令查询到的File名称,实际是从这个binlog开始进行主从复制; |
master_log_pos | 154; | 从B机上执行【show master status\G;】命令查询到的Position值,实际是从这个binlog的位置开始进行主从复制; |
4.8 A机查看同步设置是否成功
Cmd登录mysql后,主要命令就两条【show master status\G;】和【show slave status\G;】;
【show master status\G;】显示File\ Position\Binlog_Do_DB与前述my.ini配置及change master命令参数一致;
【show slave status\G;】显示 Slave_IO_Running: Yes和Slave_SQL_Running: Yes 即可。
Cmd执行记录如下:
Microsoft Windows [版本 6.1.7601]
版权所有 (c) 2009 Microsoft Corporation。保留所有权利。
C:\Program Files\MySQL\MySQL Server 5.7\bin>mysql -h localhost -u root -p
Enter password: ****
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.10-log MySQL Community Server (GPL)
Copyright (c) 2000, 2015, 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\G;
*************************** 1. row ***************************
File: mysql-log-bin.000002
Position: 154
Binlog_Do_DB: dbdemo
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
ERROR:
No query specified
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.7.162
Master_User: replicateuser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-log-bin.000003
Read_Master_Log_Pos: 154
Relay_Log_File: 14JPYI7CBESDNFK-relay-bin.000008
Relay_Log_Pos: 324
Relay_Master_Log_File: mysql-log-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: 154
Relay_Log_Space: 762
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: 2
Master_UUID: 5c503f95-5e4a-11ed-95ba-a0510b4b1044
Master_Info_File: C:\ProgramData\MySQL\MySQL Server 5.7\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
mysql>
4.9 B机-配置my.ini主从复制参数
进入【C:\ProgramData\MySQL\MySQL Server 5.7】,注意不是【C:\Program Files\MySQL\MySQL Server 5.7】目录找到my.ini在文件末尾增加以下配置。
#wdh config master-slave replicate
#这是数据库ID,此ID是唯一的,从服务器的ID必须与主服务器的ID不相同,否则会同步出错,必须为1 到 2的32次方–1之间的一个正整数值.
server-id=2
#二进制日志文件,此项为必填项,否则不能同步数据;如果不取名字的话,那么就会以计算机的名字加编号来命名二进制文件;
log-bin=mysql-log-bin
#需要同步的数据库,如果还需要同步另外的数据库,那么继续逐条添加,如果不写,那么默认同步所有的数据库;
binlog-do-db=dbdemo
保存my.ini文件后重启mysql服务。
配置后的完整my.ini文件如下
# Other default tuning values
# MySQL Server Instance Configuration File
# ----------------------------------------------------------------------
# Generated by the MySQL Server Instance Configuration Wizard
#
#
# Installation Instructions
# ----------------------------------------------------------------------
#
# On Linux you can copy this file to /etc/my.cnf to set global options,
# mysql-data-dir/my.cnf to set server-specific options
# (@localstatedir@ for this installation) or to
# ~/.my.cnf to set user-specific options.
#
# On Windows you should keep this file in the installation directory
# of your server (e.g. C:\Program Files\MySQL\MySQL Server X.Y). To
# make sure the server reads the config file use the startup option
# "--defaults-file".
#
# To run run the server from the command line, execute this in a
# command line shell, e.g.
# mysqld --defaults-file="C:\Program Files\MySQL\MySQL Server X.Y\my.ini"
#
# To install the server as a Windows service manually, execute this in a
# command line shell, e.g.
# mysqld --install MySQLXY --defaults-file="C:\Program Files\MySQL\MySQL Server X.Y\my.ini"
#
# And then execute this in a command line shell to start the server, e.g.
# net start MySQLXY
#
#
# Guildlines for editing this file
# ----------------------------------------------------------------------
#
# In this file, you can use all long options that the program supports.
# If you want to know the options a program supports, start the program
# with the "--help" option.
#
# More detailed information about the individual options can also be
# found in the manual.
#
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html
#
#
# CLIENT SECTION
# ----------------------------------------------------------------------
#
# The following options will be read by MySQL client applications.
# Note that only client applications shipped by MySQL are guaranteed
# to read this section. If you want your own MySQL client program to
# honor these values, you need to specify it as an option during the
# MySQL client library initialization.
#
[client]
no-beep
# pipe
# socket=0.0
port=3306
[mysql]
default-character-set=utf8
# SERVER SECTION
# ----------------------------------------------------------------------
#
# The following options will be read by the MySQL Server. Make sure that
# you have installed the server correctly (see above) so it reads this
# file.
#
# server_type=3
[mysqld]
# The next three options are mutually exclusive to SERVER_PORT below.
# skip-networking
# enable-named-pipe
# shared-memory
# shared-memory-base-name=MYSQL
# The Pipe the MySQL Server will use
# socket=MYSQL
# The TCP/IP Port the MySQL Server will listen on
port=3306
# Path to installation directory. All paths are usually resolved relative to this.
# basedir="C:/Program Files/MySQL/MySQL Server 5.7/"
# Path to the database root
datadir=C:/ProgramData/MySQL/MySQL Server 5.7\Data
# The default character set that will be used when a new schema or table is
# created and no character set is defined
character-set-server=utf8
# The default storage engine that will be used when create new tables when
default-storage-engine=INNODB
# Set the SQL mode to strict
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
# Enable Windows Authentication
# plugin-load=authentication_windows.dll
# General and Slow logging.
log-output=FILE
general-log=0
general_log_file="5P8LHGI6PY4QZ5L.log"
slow-query-log=1
slow_query_log_file="5P8LHGI6PY4QZ5L-slow.log"
long_query_time=10
# Binary Logging.
log-bin=mysql-log-bin
# Error Logging.
log-error="5P8LHGI6PY4QZ5L.err"
# Server Id.
server-id=2
binlog-do-db=dbdemo
# Secure File Priv.
secure-file-priv="C:/ProgramData/MySQL/MySQL Server 5.7/Uploads"
# The maximum amount of concurrent sessions the MySQL server will
# allow. One of these connections will be reserved for a user with
# SUPER privileges to allow the administrator to login even if the
# connection limit has been reached.
max_connections=151
# Query cache is used to cache SELECT results and later return them
# without actual executing the same query once again. Having the query
# cache enabled may result in significant speed improvements, if your
# have a lot of identical queries and rarely changing tables. See the
# "Qcache_lowmem_prunes" status variable to check if the current value
# is high enough for your load.
# Note: In case your tables change very often or if your queries are
# textually different every time, the query cache may result in a
# slowdown instead of a performance improvement.
query_cache_size=0
# The number of open tables for all threads. Increasing this value
# increases the number of file descriptors that mysqld requires.
# Therefore you have to make sure to set the amount of open files
# allowed to at least 4096 in the variable "open-files-limit" in
# section [mysqld_safe]
table_open_cache=2000
# Maximum size for internal (in-memory) temporary tables. If a table
# grows larger than this value, it is automatically converted to disk
# based table This limitation is for a single table. There can be many
# of them.
tmp_table_size=18M
# How many threads we should keep in a cache for reuse. When a client
# disconnects, the client's threads are put in the cache if there aren't
# more than thread_cache_size threads from before. This greatly reduces
# the amount of thread creations needed if you have a lot of new
# connections. (Normally this doesn't give a notable performance
# improvement if you have a good thread implementation.)
thread_cache_size=10
#*** MyISAM Specific options
# The maximum size of the temporary file MySQL is allowed to use while
# recreating the index (during REPAIR, ALTER TABLE or LOAD DATA INFILE.
# If the file-size would be bigger than this, the index will be created
# through the key cache (which is slower).
myisam_max_sort_file_size=100G
# If the temporary file used for fast index creation would be bigger
# than using the key cache by the amount specified here, then prefer the
# key cache method. This is mainly used to force long character keys in
# large tables to use the slower key cache method to create the index.
myisam_sort_buffer_size=27M
# Size of the Key Buffer, used to cache index blocks for MyISAM tables.
# Do not set it larger than 30% of your available memory, as some memory
# is also required by the OS to cache rows. Even if you're not using
# MyISAM tables, you should still set it to 8-64M as it will also be
# used for internal temporary disk tables.
key_buffer_size=8M
# Size of the buffer used for doing full table scans of MyISAM tables.
# Allocated per thread, if a full scan is needed.
read_buffer_size=54K
read_rnd_buffer_size=256K
#*** INNODB Specific options ***
# innodb_data_home_dir=0.0
# Use this option if you have a MySQL server with InnoDB support enabled
# but you do not plan to use it. This will save memory and disk space
# and speed up some things.
# skip-innodb
# If set to 1, InnoDB will flush (fsync) the transaction logs to the
# disk at each commit, which offers full ACID behavior. If you are
# willing to compromise this safety, and you are running small
# transactions, you may set this to 0 or 2 to reduce disk I/O to the
# logs. Value 0 means that the log is only written to the log file and
# the log file flushed to disk approximately once per second. Value 2
# means the log is written to the log file at each commit, but the log
# file is only flushed to disk approximately once per second.
innodb_flush_log_at_trx_commit=1
# The size of the buffer InnoDB uses for buffering log data. As soon as
# it is full, InnoDB will have to flush it to disk. As it is flushed
# once per second anyway, it does not make sense to have it very large
# (even with long transactions).
innodb_log_buffer_size=1M
# InnoDB, unlike MyISAM, uses a buffer pool to cache both indexes and
# row data. The bigger you set this the less disk I/O is needed to
# access data in tables. On a dedicated database server you may set this
# parameter up to 80% of the machine physical memory size. Do not set it
# too large, though, because competition of the physical memory may
# cause paging in the operating system. Note that on 32bit systems you
# might be limited to 2-3.5G of user level memory per process, so do not
# set it too high.
innodb_buffer_pool_size=8M
# Size of each log file in a log group. You should set the combined size
# of log files to about 25%-100% of your buffer pool size to avoid
# unneeded buffer pool flush activity on log file overwrite. However,
# note that a larger logfile size will increase the time needed for the
# recovery process.
innodb_log_file_size=48M
# Number of threads allowed inside the InnoDB kernel. The optimal value
# depends highly on the application, hardware as well as the OS
# scheduler properties. A too high value may lead to thread thrashing.
innodb_thread_concurrency=9
# The increment size (in MB) for extending the size of an auto-extend InnoDB system tablespace file when it becomes full.
innodb_autoextend_increment=64
# The number of regions that the InnoDB buffer pool is divided into.
# For systems with buffer pools in the multi-gigabyte range, dividing the buffer pool into separate instances can improve concurrency,
# by reducing contention as different threads read and write to cached pages.
innodb_buffer_pool_instances=8
# Determines the number of threads that can enter InnoDB concurrently.
innodb_concurrency_tickets=5000
# Specifies how long in milliseconds (ms) a block inserted into the old sublist must stay there after its first access before
# it can be moved to the new sublist.
innodb_old_blocks_time=1000
# It specifies the maximum number of .ibd files that MySQL can keep open at one time. The minimum value is 10.
innodb_open_files=300
# When this variable is enabled, InnoDB updates statistics during metadata statements.
innodb_stats_on_metadata=0
# When innodb_file_per_table is enabled (the default in 5.6.6 and higher), InnoDB stores the data and indexes for each newly created table
# in a separate .ibd file, rather than in the system tablespace.
innodb_file_per_table=1
# Use the following list of values: 0 for crc32, 1 for strict_crc32, 2 for innodb, 3 for strict_innodb, 4 for none, 5 for strict_none.
innodb_checksum_algorithm=0
# The number of outstanding connection requests MySQL can have.
# This option is useful when the main MySQL thread gets many connection requests in a very short time.
# It then takes some time (although very little) for the main thread to check the connection and start a new thread.
# The back_log value indicates how many requests can be stacked during this short time before MySQL momentarily
# stops answering new requests.
# You need to increase this only if you expect a large number of connections in a short period of time.
back_log=80
# If this is set to a nonzero value, all tables are closed every flush_time seconds to free up resources and
# synchronize unflushed data to disk.
# This option is best used only on systems with minimal resources.
flush_time=0
# The minimum size of the buffer that is used for plain index scans, range index scans, and joins that do not use
# indexes and thus perform full table scans.
join_buffer_size=256K
# The maximum size of one packet or any generated or intermediate string, or any parameter sent by the
# mysql_stmt_send_long_data() C API function.
max_allowed_packet=4M
# If more than this many successive connection requests from a host are interrupted without a successful connection,
# the server blocks that host from performing further connections.
max_connect_errors=100
# Changes the number of file descriptors available to mysqld.
# You should try increasing the value of this option if mysqld gives you the error "Too many open files".
open_files_limit=4161
# Set the query cache type. 0 for OFF, 1 for ON and 2 for DEMAND.
query_cache_type=0
# If you see many sort_merge_passes per second in SHOW GLOBAL STATUS output, you can consider increasing the
# sort_buffer_size value to speed up ORDER BY or GROUP BY operations that cannot be improved with query optimization
# or improved indexing.
sort_buffer_size=256K
# The number of table definitions (from .frm files) that can be stored in the definition cache.
# If you use a large number of tables, you can create a large table definition cache to speed up opening of tables.
# The table definition cache takes less space and does not use file descriptors, unlike the normal table cache.
# The minimum and default values are both 400.
table_definition_cache=1400
# Specify the maximum size of a row-based binary log event, in bytes.
# Rows are grouped into events smaller than this size if possible. The value should be a multiple of 256.
binlog_row_event_max_size=8K
# If the value of this variable is greater than 0, a replication slave synchronizes its master.info file to disk.
# (using fdatasync()) after every sync_master_info events.
sync_master_info=10000
# If the value of this variable is greater than 0, the MySQL server synchronizes its relay log to disk.
# (using fdatasync()) after every sync_relay_log writes to the relay log.
sync_relay_log=10000
# If the value of this variable is greater than 0, a replication slave synchronizes its relay-log.info file to disk.
# (using fdatasync()) after every sync_relay_log_info transactions.
sync_relay_log_info=10000
4.10 B机查看是否配置生效
B机,cmd登录mysql后执行以下命令查询
注意:【show variables like '%log_bin%';】命令下发后查询到log_bin为ON。
注意【show master status\G;】命令查询到的【File: mysql-log-bin.000001】和【Position: 154】此两值后续会用到。
B机cmd执行记录如下
mysql> show master status\G;
*************************** 1. row ***************************
File: mysql-log-bin.000001
Position: 154
Binlog_Do_DB: dbdemo
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
ERROR:
No query specified
mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| mysql-log-bin.000001 | 154 | dbdemo | | |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql>
4.11 B机指定同步位置
cmd登录mysql后执行以下三条命令
stop slave;
change master to master_host='192.168.7.161',master_user='replicateuser',master_password='replicateuser',master_log_file='mysql-log-bin.000001',master_log_pos=154;
start slave;
B机命令
change master to master_host='192.168.7.161',master_user='replicateuser',master_password='replicateuser',master_log_file='mysql-log-bin.000001',master_log_pos=154;
参数说明:
B机命令 | B机命令值示例 | B机命令值含义 |
master_host | '192.168.7.161' | 填入A机的IP地址。(注意是A机) |
master_password | 'replicateuser' | 填入A机上的同步账号 |
master_log_file | 'mysql-log-bin.000001' | 从A机上执行【show master status\G;】命令查询到的File名称,实际是从这个binlog开始进行主从复制; |
master_log_pos | 154; | 从A机上执行【show master status\G;】命令查询到的Position值,实际是从这个binlog的位置开始进行主从复制; |
上述三条命令cmd执行记录如下
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.13 sec)
mysql> change master to master_host='192.168.7.161',master_user='replicateuser',master_password='replicateuser',master_log_file='mysql-log-bin.000001',master_log_pos=154;
Query OK, 0 rows affected, 2 warnings (0.13 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql>
4.12 B机查看同步设置是否成功
B机,Cmd登录mysql后,主要命令两条【show master status\G;】和【show slave status\G;】;
【show master status\G;】显示File\ Position\Binlog_Do_DB与前述my.ini配置及change master命令参数一致;
【show slave status\G;】显示 Slave_IO_Running: Yes和Slave_SQL_Running: Yes 即可。
B机Cmd执行记录如下
C:\Program Files\MySQL\MySQL Server 5.7\bin>mysql -h localhost -u root -p
Enter password: ****
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.10-log MySQL Community Server (GPL)
Copyright (c) 2000, 2015, 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\G;
*************************** 1. row ***************************
File: mysql-log-bin.000003
Position: 154
Binlog_Do_DB: dbdemo
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
ERROR:
No query specified
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.7.161
Master_User: replicateuser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-log-bin.000002
Read_Master_Log_Pos: 154
Relay_Log_File: 5P8LHGI6PY4QZ5L-relay-bin.000008
Relay_Log_Pos: 324
Relay_Master_Log_File: mysql-log-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: 154
Relay_Log_Space: 762
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
Master_UUID: 0c46dc6a-27eb-11ea-9894-a0510b4b1044
Master_Info_File: C:\ProgramData\MySQL\MySQL Server 5.7\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
mysql>
5.测试踩坑记录
5.1测试1-更改A机列字段类型-自动同步成功
A机执行命令
ALTER TABLE `dbdemo`.`categories`
CHANGE COLUMN `cat_date` `cat_date` DATETIME NULL DEFAULT NULL ;
此时切换到B机上查阅categories的cat_date类型自动由原来的date类型变为datetime类型了
5.2测试2-更改B机列字段类型
B机执行以下命令
ALTER TABLE `dbdemo`.`products`
CHANGE COLUMN `prd_date` `prd_date` DATETIME NULL DEFAULT NULL ;
此时切换到A机查看列类型已自动更改。
5.3测试3-A机插入命令带外键-踩坑失败
A机执行以下命令
INSERT INTO `dbdemo`.`products` (`prd_name`, `prd_price`, `prd_date`, `cat_id`) VALUES ('prd_A_0002', '1', '2022-11-08 10:40:21', '1');
INSERT INTO `dbdemo`.`products` (`prd_name`, `prd_price`, `prd_date`, `cat_id`) VALUES ('prd_A_0003', '1', '2022-11-08 10:40:22', '1');
INSERT INTO `dbdemo`.`products` (`prd_name`, `prd_price`, `prd_date`, `cat_id`) VALUES ('prd_A_0004', '1', '2022-11-08 10:40:23', '1');
此时B机没有同步到上述数据,怀疑是外键约束导致不能同步成功。
此时B机没有同步到上述数据,怀疑是外键约束导致不能同步成功。
分析开始:
B机cmd登录mysql输入命令【show master status\G;】和【show slave status\G;】,查找到Slave_SQL_Running: No以及Seconds_Behind_Master: NULL,和Last_Errno: 1452,
结论:发现果然是因为外键问题导致。原因为A机categories表有cat_id为1 的数据,但B机表categories没有此数据,导致A机的sql【INSERT INTO `dbdemo`.`products` (`prd_name`, `prd_price`, `prd_date`, `cat_id`) VALUES ('prd_A_0002', '1', '2022-11-08 10:40:21', '1');】同步到B机时因外键约束找不到数据而无法插入。
上述分析过程两个命令在cmd执行记录如下
mysql> show master status\G;
*************************** 1. row ***************************
File: mysql-log-bin.000003
Position: 618
Binlog_Do_DB: dbdemo
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
ERROR:
No query specified
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.7.161
Master_User: replicateuser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-log-bin.000002
Read_Master_Log_Pos: 1188
Relay_Log_File: 5P8LHGI6PY4QZ5L-relay-bin.000008
Relay_Log_Pos: 804
Relay_Master_Log_File: mysql-log-bin.000002
Slave_IO_Running: Yes
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: 1452
Last_Error: Could not execute Write_rows event on table dbdemo.products; Cannot add or update a child row: a foreign key constraint fails (`d
bdemo`.`products`, CONSTRAINT `products_ibfk_1` FOREIGN KEY (`cat_id`) REFERENCES `categories` (`cat_id`) ON UPDATE CASCADE), Error_code: 1452; handler error HA
_ERR_NO_REFERENCED_ROW; the event's master log mysql-log-bin.000002, end_log_pos 901
Skip_Counter: 0
Exec_Master_Log_Pos: 634
Relay_Log_Space: 1796
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: 1452
Last_SQL_Error: Could not execute Write_rows event on table dbdemo.products; Cannot add or update a child row: a foreign key constraint fails (`d
bdemo`.`products`, CONSTRAINT `products_ibfk_1` FOREIGN KEY (`cat_id`) REFERENCES `categories` (`cat_id`) ON UPDATE CASCADE), Error_code: 1452; handler error HA
_ERR_NO_REFERENCED_ROW; the event's master log mysql-log-bin.000002, end_log_pos 901
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 0c46dc6a-27eb-11ea-9894-a0510b4b1044
Master_Info_File: C:\ProgramData\MySQL\MySQL Server 5.7\Data\master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State:
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp: 221108 10:41:11
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
mysql>
5.4解决自动复制失败问题(解决Slave_SQL_Running: No问题)
在从机B机上执行以下三个命令
【stop slave;】
【set global sql_slave_skip_counter=1;】
【start slave;】
执行上述命令跳过错误后,再执行命令【show slave status\G;】查看是否同步状态恢复,【Slave_IO_Running: Yes Slave_SQL_Running: Yes】即可
cmd登录mysql后执行记录如下
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
mysql> set global sql_slave_skip_counter=1;
Query OK, 0 rows affected (0.09 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: 192.168.7.161
Master_User: replicateuser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-log-bin.000002
Read_Master_Log_Pos: 1188
Relay_Log_File: 5P8LHGI6PY4QZ5L-relay-bin.000009
Relay_Log_Pos: 324
Relay_Master_Log_File: mysql-log-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: 1188
Relay_Log_Space: 1745
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
Master_UUID: 0c46dc6a-27eb-11ea-9894-a0510b4b1044
Master_Info_File: C:\ProgramData\MySQL\MySQL Server 5.7\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
mysql>
6 再次测试A->B自动复制
A机执行sql(保证外键均有)
INSERT INTO `dbdemo`.`categories` (`cat_name`, `cat_description`, `cat_date`) VALUES ('cat_A0002', 'A0002_desc', '2022-11-08 11:06:19');
INSERT INTO `dbdemo`.`products` (`prd_name`, `prd_price`, `prd_date`, `cat_id`) VALUES ('prd_A_0005', '1', '2022-11-08 11:07:34', '2');
INSERT INTO `dbdemo`.`products` (`prd_name`, `prd_price`, `prd_date`, `cat_id`) VALUES ('prd_A_0006', '1', '2022-11-08 11:07:35', '2');
INSERT INTO `dbdemo`.`products` (`prd_name`, `prd_price`, `prd_date`, `cat_id`) VALUES ('prd_A_0007', '1', '2022-11-08 11:07:36', '2');
分别查询A机及B机两个表的数据,A机上述sql影响的数据已经自动同步到B机了。ok,一致。
7再次测试B->A自动复制
B机执行sql
INSERT INTO `dbdemo`.`categories` (`cat_name`, `cat_description`, `cat_date`) VALUES ('cat_B0003', 'B0003_desc', '2022-11-08 11:19:01');
/*这里实际预测了categories的主键会在insert时自增到3*/
INSERT INTO `dbdemo`.`products` (`prd_name`, `prd_price`, `prd_date`, `cat_id`) VALUES ('prd_B_0009', '2', '2022-11-08 11:19:02', '3');
INSERT INTO `dbdemo`.`products` (`prd_name`, `prd_price`, `prd_date`, `cat_id`) VALUES ('prd_B_0009', '2', '2022-11-08 11:19:03', '3');
INSERT INTO `dbdemo`.`products` (`prd_name`, `prd_price`, `prd_date`, `cat_id`) VALUES ('prd_B_0010', '2', '2022-11-08 11:19:03', '3');
分别查询A机及B机两个表的数据,B机上述sql影响的数据已经自动同步到A机了。ok,一致。
8.测试主机A宕机场景
8.1测试场景顺序
1.主机A宕机, B机在写;
2.主机A恢复(期望A机从B机自动同步复制数据);
3.查看主机A和从机B的数据一致性
8.2实测过程及结果
将A机服务关闭,然后在B机上输入命令show processlist;结果如下。下图中B机上第一个【show processlist;】执行时A机正常。下图中B机上第二个【show processlist;】执行时A机已宕机。
可对比看出宕机时缺少republicateuser的process,以及systemuser 的state状态变为Reconnecting after a failed master event read
mysql> show processlist;
+----+-------------+-----------------+------+---------+-------+--------------------------------------------------------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+-------------+-----------------+------+---------+-------+--------------------------------------------------------+------------------+
| 7 | root | localhost:52091 | NULL | Query | 0 | starting | show processlist |
| 9 | root | localhost:52401 | NULL | Sleep | 9232 | | NULL |
| 10 | root | localhost:52402 | NULL | Sleep | 9232 | | NULL |
| 11 | system user | | NULL | Connect | 18287 | Reconnecting after a failed master event read | NULL |
| 12 | system user | | NULL | Connect | 17796 | Slave has read all relay log; waiting for more updates | NULL |
+----+-------------+-----------------+------+---------+-------+--------------------------------------------------------+------------------+
5 rows in set (0.00 sec)
mysql>
当A机宕机时,在B机上输入命令【show slave status\G;】结果如下,显示Slave_IO_State: Reconnecting after a failed master event read
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Reconnecting after a failed master event read
Master_Host: 192.168.7.161
Master_User: replicateuser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-log-bin.000002
Read_Master_Log_Pos: 2384
Relay_Log_File: 5P8LHGI6PY4QZ5L-relay-bin.000010
Relay_Log_Pos: 324
Relay_Master_Log_File: mysql-log-bin.000002
Slave_IO_Running: Connecting
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: 2384
Relay_Log_Space: 1907
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: 2003
Last_IO_Error: error reconnecting to master 'replicateuser@192.168.7.161:3306' - retry-time: 60 retries: 2
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 0c46dc6a-27eb-11ea-9894-a0510b4b1044
Master_Info_File: C:\ProgramData\MySQL\MySQL Server 5.7\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: 221108 16:05:30
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
mysql> show master status\G;
*************************** 1. row ***************************
File: mysql-log-bin.000003
Position: 1790
Binlog_Do_DB: dbdemo
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.01 sec)
ERROR:
No query specified
mysql>
B机执行sql插入数据,执行成功,sql如下
INSERT INTO `dbdemo`.`products` (`prd_name`, `prd_price`, `prd_date`, `cat_id`) VALUES ('prd_B_0011', '3', '2022-11-08 16:08:40', '3');
INSERT INTO `dbdemo`.`products` (`prd_name`, `prd_price`, `prd_date`, `cat_id`) VALUES ('prd_B_0012', '3', '2022-11-08 16:08:41', '3');
INSERT INTO `dbdemo`.`products` (`prd_name`, `prd_price`, `prd_date`, `cat_id`) VALUES ('prd_B_0013', '3', '2022-11-08 16:08:42', '3');
将A机恢复正常(服务开启),然后查询products的数据
结果:一致,A机恢复后查询出的数据与B机执行sql后结果一致;
9.测试从机B宕机场景及结论
测试场景顺序
1.从机B宕机, 主机A正在写;
2.从机B恢复(期望B机从A机自动同步复制数据);
3.查看主机A和从机B的数据一致性
测试过程不再罗列。
结论
将B机从宕机状态恢复(启动其服务),期望B机自动将B机宕机期间A机的数据自动复制过来。
结论:自动复制成功,B机恢复后,B机与A机数据一致。
10.潜在问题-主键自增及从机延时
双主数据库如果均用自增主键,则两边同时进行写操作时可能存在自增主键冲突的问题。
Mysql建议使用一主一从或一主多从方式,主服务器负责写,从服务器负责读,可实现读写分离,且实现了读端的流量削峰和均衡,但主从复制也引入了主从延时问题,当然延时很小,网搜的帖子测试在主机写后,再自从机读取的延迟在毫秒级。
11.延伸问题-关于读写分离或分库主键类型选择
阅读了以下三篇文章。
MySQL分库分表id主键处理_赵广陆的博客-CSDN博客_mysql 分表主键id
mysql 自增id和UUID做主键性能分析,及最优方案 - 腾讯云开发者社区-腾讯云
Mysql 使用UUID和自增主键ID性能对比测试_菠萝-琪琪的博客-CSDN博客
参考上述资料后主键的选择方式:
单库:使用int自增作为主键;中小数据量分布式系统:采用UUID作为主键;
大数据分布式系统:可参考snowflake算法自定义生成主键;
12.其他
12.1查询mysql日志模式
mysql> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW |
+---------------+-------+
1 row in set, 1 warning (0.00 sec)
mysql>
12.2win7修改mysql的默认引擎的位置
在C:\ProgramData\MySQL\MySQL Server 5.7\my.ini中
# The default storage engine that will be used when create new tables when default-storage-engine=INNODB |
12.3读写分离吞吐量计算示例-参考
12.4查看主从通讯I/O和SQL线程状态
以下id为11,12,13三行的state是需要关注的,以下是主从复制A机B机连接正常状态的查询结果。
mysql> show processlist;
+----+---------------+-----------------------+------+-------------+-------+---------------------------------------------------------------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+---------------+-----------------------+------+-------------+-------+---------------------------------------------------------------+------------------+
| 7 | root | localhost:52091 | NULL | Query | 0 | starting | show processlist |
| 9 | root | localhost:52401 | NULL | Sleep | 7384 | | NULL |
| 10 | root | localhost:52402 | NULL | Sleep | 7384 | | NULL |
| 11 | system user | | NULL | Connect | 16439 | Waiting for master to send event | NULL |
| 12 | system user | | NULL | Connect | 15948 | Slave has read all relay log; waiting for more updates | NULL |
| 13 | replicateuser | 14JPYI7CBESDNFK:65297 | NULL | Binlog Dump | 11577 | Master has sent all binlog to slave; waiting for more updates | NULL |
+----+---------------+-----------------------+------+-------------+-------+---------------------------------------------------------------+------------------+
6 rows in set (0.02 sec)
mysql>
资料参考
windows下使用mysql双机热备功能 /清除热备主从命令 - 执笔者 - 博客园
昊鼎王五:mysql配置主从关系时的语句master_log_pos的值到底填写什么?_昊鼎王五的博客-CSDN博客_master_log_pos
mysql主从复制-CHANGE MASTER TO 语法详解_jesseyoung的博客-CSDN博客_change master to
mysql主从复制搭建中几种log和pos详解__lynnwu的博客-CSDN博客
Mysql搭建双主热备_K_Kyle的博客-CSDN博客_mysql双主热备
Windows上MySQL开启Binlog日志以及如何查看_啊荻~的博客-CSDN博客_windows查看binlog日志
mysql中文文档-主从复制