vlambda博客
学习文章列表

MHA+ProxySQL,mysql的高可用集群+读写分离(一)GTID主从复制

01 前言 & 综述

本次受邀为一家小公司做技术顾问,然后提出了要做数据库的高可用集群与负载均衡方案。

主要步骤如下:

1、安装mysql(本文省略)2、安装主从3、安装MHA4、安装proxySQL5、数据迁移(本文省略)6、程序测试(本文省略)

详细事项如下:

1、在A、B、C三台机器上搭建三套mysql数据库(5.7版本);2、搭建一主二从,使用半同步、GTID、从库只读等机制;3、搭建MHA,建立故障自动切换机制,建立VIP;4、搭建proxySQL,进行自动负载均衡操作,读写分离,读操作自动分配到两台从库上;5、从X机器(5.5版本)上导出数据,在A、B、C机器上恢复备份;怎么不停机备份?或者停机快速备份?数据量大概有30多G。mysqldump? mysqlpump? mydupmer?xtrabackup?6、测试环境演练7、停机迁移

机器规划:

机器 主从 名称
172.31.145.39 node1
172.31.145.38 node2
172.31.145.40 node3

02 主要mysql配置

省略安装mysql步骤。

实际上还有一步是挂载数据盘,也省略了。

主要配置:

# 编辑my.cnfvi /etc/my.cnf
# GTID 主从复制server-id = 3expire_logs_days = 7gtid_mode = onlog-bin = /data0/mysql/mysql-binlogbinlog_format = rowlog_slave_updates = 1

全部配置:

# For advice on how to change settings please see# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html
[mysqld]## Remove leading # and set to the amount of RAM for the most important data# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.# innodb_buffer_pool_size = 128M## Remove leading # to turn on a very important data integrity option: logging# changes to the binary log between backups.# log_bin## Remove leading # to set options mainly useful for reporting servers.# The server defaults are faster for transactions and fast SELECTs.# Adjust sizes as needed, experiment to find the optimal values.# join_buffer_size = 128M# sort_buffer_size = 2M# read_rnd_buffer_size = 2Mdatadir=/data0/mysqlsocket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security riskssymbolic-links=0
pid-file=/var/run/mysqld/mysqld.pid
# GTID 主从复制server-id = 3expire_logs_days = 7gtid_mode = onlog-bin = /data0/mysql/mysql-binlogbinlog_format = rowlog_slave_updates = 1

skip_name_resolve = 1open_files_limit = 65535back_log = 1024max_connections = 1000max_connect_errors = 1000000table_open_cache = 1024table_definition_cache = 1024table_open_cache_instances = 64thread_stack = 512Kexternal-locking = FALSEmax_allowed_packet = 32Msort_buffer_size = 4Mjoin_buffer_size = 4Mthread_cache_size = 768query_cache_size = 0query_cache_type = 0interactive_timeout = 600wait_timeout = 600tmp_table_size = 32Mmax_heap_table_size = 32Mslow_query_log = 1slow_query_log_file = /data0/mysql/slow.loglog-error = /data0/mysql/error.loglong_query_time = 2sync_binlog = 1binlog_cache_size = 4Mmax_binlog_cache_size = 1Gmax_binlog_size = 1Genforce_gtid_consistency = 1master_info_repository = TABLErelay_log_info_repository = TABLE
key_buffer_size = 32Mread_buffer_size = 8Mread_rnd_buffer_size = 4Mbulk_insert_buffer_size = 64M
relay_log_recovery = 1relay-log-purge = 1
lock_wait_timeout = 3600explicit_defaults_for_timestamp = 1
innodb_thread_concurrency = 0innodb_sync_spin_loops = 100innodb_spin_wait_delay = 30
innodb_buffer_pool_size = 1024Minnodb_buffer_pool_instances = 8innodb_buffer_pool_load_at_startup = 1innodb_buffer_pool_dump_at_shutdown = 1
transaction_isolation = REPEATABLE-READ
innodb_flush_log_at_trx_commit = 1innodb_log_buffer_size = 32Minnodb_log_file_size = 2Ginnodb_log_files_in_group = 2innodb_flush_neighbors = 0innodb_write_io_threads = 8innodb_read_io_threads = 8innodb_purge_threads = 8innodb_page_cleaners = 4innodb_open_files = 65535
innodb_flush_method = O_DIRECTinnodb_checksum_algorithm = crc32innodb_lru_scan_depth = 4000
innodb_lock_wait_timeout = 10innodb_rollback_on_timeout = 1innodb_print_all_deadlocks = 1innodb_file_per_table = 1innodb_online_alter_log_max_size = 4Ginternal_tmp_disk_storage_engine = InnoDBinnodb_stats_on_metadata = 0innodb_status_file = 1innodb_status_output = 0innodb_status_output_locks = 0performance_schema = 1performance_schema_instrument = '%=on'
# innodb monitorinnodb_monitor_enable="module_innodb"innodb_monitor_enable="module_server"innodb_monitor_enable="module_dml"innodb_monitor_enable="module_ddl"innodb_monitor_enable="module_trx"innodb_monitor_enable="module_os"innodb_monitor_enable="module_purge"innodb_monitor_enable="module_log"innodb_monitor_enable="module_lock"innodb_monitor_enable="module_buffer"innodb_monitor_enable="module_index"innodb_monitor_enable="module_ibuf_system"innodb_monitor_enable="module_buffer_page"innodb_monitor_enable="module_adaptive_hash"
[mysqldump]quickmax_allowed_packet = 32M

03 ssh互信

1、生成密钥

ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa

2、拷贝到其他机器

# 主ssh-copy-id -i ~/.ssh/id_dsa.pub 172.31.145.39;# 从1ssh-copy-id -i ~/.ssh/id_dsa.pub 172.31.145.38;# 从2ssh-copy-id -i ~/.ssh/id_dsa.pub 172.31.145.40;

注意:在manager节点安装在mysql主从复制集群中的一台服务器的前提下,一定要让本机也可以免密ssh登录本机。

三台机器,以上命令都执行一遍。

3、添加hosts

sudo vi /etc/hosts
172.31.145.39 node1172.31.145.38 node2172.31.145.40 node3
sudo echo 172.31.145.39 node1 >> /etc/hostssudo echo 172.31.145.38 node2 >> /etc/hostssudo echo 172.31.145.40 node3 >> /etc/hosts

三台机器,以上命令都执行一遍。

4、互信测试

ssh node1ssh node2ssh node3

三台机器,以上命令都执行一遍。

成功信息如下:

[mysql@iZm5e2mylql8b8vqklsir7Z ~]$ ssh node1Last login: Mon Mar 30 21:50:50 2020 from 172.31.145.39
Welcome to Alibaba Cloud Elastic Compute Service !
[mysql@iZm5ebq5g3dxxlguud3akeZ ~]$ ssh node2Last login: Mon Mar 30 21:52:50 2020 from 172.31.145.40
Welcome to Alibaba Cloud Elastic Compute Service !
[mysql@iZm5e2mylql8b8vqklsir7Z ~]$ ssh node3Last login: Mon Mar 30 21:50:09 2020 from 172.31.145.38
Welcome to Alibaba Cloud Elastic Compute Service !
[mysql@iZm5eh3yfwvy52yb78f6obZ ~]$

可以看到实现了机器间的免密登录,登录后的主机名已经改变,如下所示:

[mysql@iZm5ebq5g3dxxlguud3akeZ ~]$
[mysql@iZm5e2mylql8b8vqklsir7Z ~]$
[mysql@iZm5eh3yfwvy52yb78f6obZ ~]$

03 主从

一主两从 + replication slaveGTID + row

主要配置

# 编辑my.cnfvi /etc/my.cnf
# GTID 主从复制server-id = 3expire_logs_days = 7gtid_mode = onlog-bin = /data0/mysql/mysql-binlogbinlog_format = rowlog_slave_updates = 1

连接数据库,创建主从复制账号

mysql -u root -p

所有机器都执行以下语句

# 账号创建create user 'repl'@'172.31.145.%' identified by 'replZw@1987';
# 创建复制权限grant replication slave on *.* to 'repl'@'172.31.145.%';
# 刷新权限flush privileges;
# 创建MHA管理账号create user 'zs'@'172.31.145.%' identified by 'adminZw@1987';
# 赋权grant all privileges on *.* to 'zs'@'172.31.145.%';
# 刷新权限flush privileges;

执行完成后,导出dump。

由于是GTID方式,不需要添加--master-data参数,命令如下:

mysqldump --set-gtid-purged=off --single-transaction -u root -p --all-databases > all_0331.sql

推送到从库

scp all_0331.sql node2:/home/mysql/scp all_0331.sql node3:/home/mysql/

在从库恢复

mysql -u root -p < all_0331.sql

在所有从库都要执行,刚刚在主库创建的repl账号

# 注意大写CHANGE MASTER TO MASTER_HOST='172.31.145.39',MASTER_USER='repl',MASTER_PASSWORD='replZw@1987',MASTER_AUTO_POSITION=1;
start slave;
show slave status \G;

04 GTID不成功、GTID 事务冲突 等问题

1、在主库查看权限对不对

show grants for 'repl'@'172.31.145.%';
mysql> show grants for 'repl'@'172.31.145.%';+---------------------------------------------------------+| Grants for repl@172.31.145.% |+---------------------------------------------------------+| GRANT REPLICATION SLAVE ON *.* TO 'repl'@'172.31.145.%' |+---------------------------------------------------------+1 row in set (0.00 sec)

2、 在从库连接主库,测试repl账号密码对不对

mysql -urepl -h node1 -p -P3306

3、重新设置GTID、账号密码

主库查询GTID

show global variables like '%gtid%'\G;
……*************************** 3. row ***************************Variable_name: gtid_executed Value: 1b083812-71db-11ea-ad0c-00163e0a2908:1-19,89b2f4fc-7299-11ea-942c-00163e08f16f:1-10……

从库执行,主要获取gtid_purged在从库重置:

stop slave;
reset slave;
reset master;
set global gtid_purged='1b083812-71db-11ea-ad0c-00163e0a2908:1-18';
# 注意大写CHANGE MASTER TO MASTER_HOST='172.31.145.39',MASTER_USER='repl',MASTER_PASSWORD='replZw@1987',MASTER_AUTO_POSITION=1;
start slave;
show slave status \G;

05 第一篇完结

陆陆续续花了一个星期,搭建了基于GTID的主从复制、MHA的高可用架构、proxySQL的读写分离。

本文是第一篇,大概会用三篇左右的篇幅将这套架构怎么搭建的说完。

参考书籍:《mysql技术内幕:第5版》、《mysql王者晋级之路》、《跟老男孩学Linux运维:mysql入门与提高实践》