核心逻辑就三个步骤
主库和从库同步数据,保证完全一致
配置主库和从库的数据库参数,从库设置只读
找到主库同步位点,启动同步流程
前言 很多人觉得 MySQL 主从复制、读写分离配置复杂、坑多,实则理清核心逻辑后,整体流程非常标准化。本文基于云服务器 + BT面板 + MySQL8.0 真实实操整理,全程落地可用,同时汇总所有高频踩坑点,零基础也能顺利搭建主从备份、读写分离架构。
核心逻辑就三个步骤 MySQL主从搭建、读写分离落地,归根结底只有三步,所有配置、命令、优化都是围绕这三点展开:
主库和从库同步数据,保证完全一致 :初始化全量数据对齐,为增量同步打下基础
配置主库和从库的数据库参数,从库设置只读 :区分主从身份、开启日志、优化环境,保障同步稳定
找到主库同步位点,启动同步流程 :绑定主从链路,开启实时增量同步
一、第一步:主从数据初始化对齐(核心基础) 主从同步的前提是初始数据完全一致 ,否则启动同步后会出现主键冲突、表不存在等报错,直接导致同步中断。
1.1 主库一致性锁表(防止位点和数据变动) 首次搭建主从、全量数据同步时,需要锁定主库,避免导出数据期间主库产生新写入,造成数据不一致。
1 2 3 4 5 FLUSH TABLES WITH READ LOCK; SHOW MASTER STATUS;
执行完 SHOW MASTER STATUS 后,务必记录对应的 File(日志文件名) 和 Position(位点值) ,这是主从同步的精准起点。
1.2 全量数据备份与导入 InnoDB引擎生产环境推荐无锁备份,不阻塞业务读写,实现数据快照一致性:
1 2 mysqldump -uroot -p --all-databases --master-data=2 --single-transaction > full_backup.sql
将导出的备份文件上传至从库服务器,导入从库数据库,完成主从初始数据完全对齐 。数据导入完成后,解锁主库,恢复正常业务读写:
1.3 创建主从同步专属账号(仅主库操作) 主从同步需要独立的复制账号,仅授予复制权限,遵循最小权限原则。同时适配MySQL8.0加密规则,解决握手失败问题:
1 2 3 4 5 6 7 8 9 10 DROP USER IF EXISTS 'repl' @'%' ;DROP USER IF EXISTS 'repl' @'从库IP' ;CREATE USER 'repl' @'%' IDENTIFIED WITH mysql_native_password BY '自定义密码' ;GRANT REPLICATION SLAVE ON * .* TO 'repl' @'%' ;FLUSH PRIVILEGES;
重点说明 :同步账号 repl 只需在主库创建,主从库账号密码可以不一致 ,从库无需创建该账号,不影响同步链路。
二、第二步:主从参数配置,从库开启只读限制 数据对齐后,核心是修改 my.cnf 配置文件,区分主从身份、开启日志功能、优化云服务器环境,同时给从库配置只读,杜绝数据乱写入。
2.1 核心配置约束(必遵守)
server-id 全局唯一 :主库、从库ID不能重复,主库默认1,从库默认2
主从 sql-mode、字符集、表名大小写规则必须完全一致,避免同步报错
云服务器必须开启 skip_name_resolve = 1 ,关闭DNS反向解析,解决公网握手超时、连接被拦截问题
2.2 主库完整 my.cnf 配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 [client] port = 3306 socket = /tmp/mysql.sock[mysqld] port = 3306 socket = /tmp/mysql.sockconnect_timeout = 120 datadir = /www/server/datadefault_storage_engine = InnoDBkey_buffer_size = 32 Mmax_allowed_packet = 1 Gtable_open_cache = 1024 max_heap_table_size = 64 Msort_buffer_size = 768 Knet_buffer_length = 4 Kread_buffer_size = 768 Kread_rnd_buffer_size = 256 Kmyisam_sort_buffer_size = 8 Mthread_cache_size = 16 tmp_table_size = 32 Mlower_case_table_names = 1 default_authentication_plugin = mysql_native_passwordsql-mode =NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLESexplicit_defaults_for_timestamp = true skip_name_resolve = 1 max_connections = 100 max_connect_errors = 10000 open_files_limit = 65535 log-bin =mysql-binbinlog_format =ROWserver-id = 1 binlog_expire_logs_seconds = 600000 slow_query_log =1 slow-query-log-file =/www/server/data/mysql-slow.loglong_query_time =3 early-plugin-load = "" innodb_data_home_dir = /www/server/datainnodb_data_file_path = ibdata1:10 M:autoextendinnodb_log_group_home_dir = /www/server/datainnodb_buffer_pool_size = 512 Minnodb_log_file_size = 256 Minnodb_log_buffer_size = 16 Minnodb_flush_log_at_trx_commit = 1 innodb_lock_wait_timeout = 50 innodb_max_dirty_pages_pct = 90 innodb_read_io_threads = 2 innodb_write_io_threads = 2 [mysqldump] quick max_allowed_packet = 500 M[mysql] no-auto-rehash [myisamchk] key_buffer_size = 32 Msort_buffer_size = 768 Kread_buffer = 2 Mwrite_buffer = 2 M[mysqlhotcopy] interactive-timeout plugin-load-add =rpl_semi_sync_master.sorpl_semi_sync_master =ON rpl_semi_sync_master_wait_for_slave_count =1 rpl_semi_sync_master_wait_point =AFTER_SYNC
2.3 从库完整 my.cnf 配置(核心只读) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 [client] port = 3306 socket = /tmp/mysql.sock[mysqld] port = 3306 socket = /tmp/mysql.sockdatadir = /www/server/datadefault_storage_engine = InnoDBkey_buffer_size = 32 Mmax_allowed_packet = 1 Gtable_open_cache = 2048 sort_buffer_size = 768 Knet_buffer_length = 4 Kread_buffer_size = 768 Kread_rnd_buffer_size = 256 Kmyisam_sort_buffer_size = 8 Mtmp_table_size = 64 Mmax_heap_table_size = 64 Mlower_case_table_names = 1 default_authentication_plugin = mysql_native_passwordsql-mode =NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLESexplicit_defaults_for_timestamp = true skip-name-resolve max_connections = 500 max_connect_errors = 10000 open_files_limit = 65535 server-id = 2 relay_log = relay-binlog_bin = OFF log_replica_updates = 0 read_only = ON super_read_only = ON replicate_ignore_db =mysqlreplicate_ignore_db =information_schemareplicate_ignore_db =performance_schemareplicate_ignore_db =sysreplicate_wild_do_table =hn_db.%slow_query_log =1 slow-query-log-file =/www/server/data/mysql-slow.loglong_query_time =3 early-plugin-load = "" innodb_data_home_dir = /www/server/datainnodb_data_file_path = ibdata1:10 M:autoextendinnodb_log_group_home_dir = /www/server/datainnodb_buffer_pool_size = 256 Minnodb_log_file_size = 512 Minnodb_log_buffer_size = 16 Minnodb_flush_log_at_trx_commit = 1 innodb_lock_wait_timeout = 50 innodb_max_dirty_pages_pct = 90 innodb_read_io_threads = 2 innodb_write_io_threads = 2 [mysqldump] quick max_allowed_packet = 500 M[mysql] no-auto-rehash [myisamchk] key_buffer_size = 32 Msort_buffer_size = 768 Kread_buffer = 2 Mwrite_buffer = 2 M[mysqlhotcopy] interactive-timeout
配置修改完成后,重启主从MySQL服务 ,让所有参数生效。
三、第三步:配置同步位点,启动主从同步 数据对齐、参数配置完成后,最后一步就是绑定主库信息、填写之前记录的同步位点,启动实时同步。
3.1 从库重置并配置同步链路 清空从库旧的同步记录,避免配置冲突,绑定主库IP、端口、同步账号和精准位点:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 STOP SLAVE; RESET SLAVE ALL ; CHANGE MASTER TO MASTER_HOST= '主库公网IP' , MASTER_PORT= 3306 , MASTER_USER= 'repl' , MASTER_PASSWORD= '同步账号密码' , MASTER_LOG_FILE= 'mysql-bin.000011' , MASTER_LOG_POS= 11532 ; START SLAVE;
3.2 同步状态校验(关键) 通过命令查看完整同步状态,排查异常:
正常同步标准 :
Slave_IO_Running: Yes(成功拉取主库binlog日志)
Slave_SQL_Running: Yes(成功执行日志、同步数据)
Slave_IO_State: Waiting for source to send event(实时监听主库新数据)
异常快速判断 :
四、关键实操注意事项(避坑汇总) 4.1 同步重启恢复规则 MySQL8.0 默认将同步位点持久化到系统表,从库重启后,同步位点不会丢失 。但通过 CHANGE MASTER TO 配置的主库连接信息为临时内存配置,重启MySQL后会失效,如需永久生效,可写入配置文件。
4.2 单条数据报错同步逻辑 若某一行数据同步出错,仅会暂停当前数据表 的后续同步,其他数据表不受影响。生产环境禁止跳过报错,否则会造成永久数据不一致,需手动对齐主从数据后重启同步。
4.3 主库读写权限说明 仅首次全量初始化需要锁表,日常同步故障、重启从库、重新绑定位点,无需锁定主库 ,主库可正常读写业务数据,同步恢复后会自动追平断开期间的所有增量数据。
4.4 binlog日志过期风险 主库binlog日志会自动过期清理,若从库断开同步时间过久,主库清理了旧日志,增量同步会彻底失效,此时需要重新全量备份对齐数据,重建同步链路。
4.5 主从账号权限差异说明 同步专用repl账号主从密码、权限可不一致;但业务账号、root账号建议仅在主库操作,不要手动修改从库账号密码和权限,避免同步覆盖导致报错。
五、总结 MySQL主从备份、读写分离架构,核心始终围绕数据对齐、参数配置、位点同步 三大步骤。看似坑多,实则所有报错和问题,基本都是参数不统一、网络拦截、数据初始不一致、账号授权异常导致。
按照本文标准化流程配置,搭配云服务器专属优化参数,可完美实现MySQL实时主从备份、读写分离,兼顾数据安全和业务查询性能。
修改后的主库完整配置参考 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 [client] port = 3306 socket = /tmp/mysql.sock[mysqld] port = 3306 socket = /tmp/mysql.sockconnect_timeout = 120 datadir = /www/server/datadefault_storage_engine = InnoDBkey_buffer_size = 32 Mmax_allowed_packet = 1 Gtable_open_cache = 1024 max_heap_table_size = 64 Msort_buffer_size = 768 Knet_buffer_length = 4 Kread_buffer_size = 768 Kread_rnd_buffer_size = 256 Kmyisam_sort_buffer_size = 8 Mthread_cache_size = 16 tmp_table_size = 32 Mlower_case_table_names = 1 default_authentication_plugin = mysql_native_passwordsql-mode =NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLESexplicit_defaults_for_timestamp = true skip_name_resolve = 1 max_connections = 100 max_connect_errors = 10000 open_files_limit = 65535 log-bin =mysql-binbinlog_format =ROWserver-id = 1 binlog_expire_logs_seconds = 600000 slow_query_log =1 slow-query-log-file =/www/server/data/mysql-slow.loglong_query_time =3 early-plugin-load = "" innodb_data_home_dir = /www/server/datainnodb_data_file_path = ibdata1:10 M:autoextendinnodb_log_group_home_dir = /www/server/datainnodb_buffer_pool_size = 512 Minnodb_log_file_size = 256 Minnodb_log_buffer_size = 16 Minnodb_flush_log_at_trx_commit = 1 innodb_lock_wait_timeout = 50 innodb_max_dirty_pages_pct = 90 innodb_read_io_threads = 2 innodb_write_io_threads = 2 [mysqldump] quick max_allowed_packet = 500 M[mysql] no-auto-rehash [myisamchk] key_buffer_size = 32 Msort_buffer_size = 768 Kread_buffer = 2 Mwrite_buffer = 2 M[mysqlhotcopy] interactive-timeout plugin-load-add =rpl_semi_sync_master.sorpl_semi_sync_master =ON rpl_semi_sync_master_wait_for_slave_count =1 rpl_semi_sync_master_wait_point =AFTER_SYNC
修改后的从库完整配置参考 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 [client] port = 3306 socket = /tmp/mysql.sock[mysqld] port = 3306 socket = /tmp/mysql.sockdatadir = /www/server/datadefault_storage_engine = InnoDBkey_buffer_size = 32 Mmax_allowed_packet = 1 Gtable_open_cache = 2048 sort_buffer_size = 768 Knet_buffer_length = 4 Kread_buffer_size = 768 Kread_rnd_buffer_size = 256 Kmyisam_sort_buffer_size = 8 Mtmp_table_size = 64 Mmax_heap_table_size = 64 Mlower_case_table_names = 1 default_authentication_plugin = mysql_native_passwordsql-mode =NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLESexplicit_defaults_for_timestamp = true skip-name-resolve max_connections = 500 max_connect_errors = 10000 open_files_limit = 65535 server-id = 2 relay_log = relay-binlog_bin = OFF log_replica_updates = 0 read_only = ON super_read_only = ON replicate_ignore_db =mysqlreplicate_ignore_db =information_schemareplicate_ignore_db =performance_schemareplicate_ignore_db =sysreplicate_wild_do_table =hn_db.%slow_query_log =1 slow-query-log-file =/www/server/data/mysql-slow.loglong_query_time =3 early-plugin-load = "" innodb_data_home_dir = /www/server/datainnodb_data_file_path = ibdata1:10 M:autoextendinnodb_log_group_home_dir = /www/server/datainnodb_buffer_pool_size = 256 Minnodb_log_file_size = 512 Minnodb_log_buffer_size = 16 Minnodb_flush_log_at_trx_commit = 1 innodb_lock_wait_timeout = 50 innodb_max_dirty_pages_pct = 90 innodb_read_io_threads = 2 innodb_write_io_threads = 2 [mysqldump] quick max_allowed_packet = 500 M[mysql] no-auto-rehash [myisamchk] key_buffer_size = 32 Msort_buffer_size = 768 Kread_buffer = 2 Mwrite_buffer = 2 M[mysqlhotcopy] interactive-timeout