MHA+ProxySQL,mysql的高可用集群+读写分离(一)GTID主从复制
01 前言 & 综述
本次受邀为一家小公司做技术顾问,然后提出了要做数据库的高可用集群与负载均衡方案。
主要步骤如下:
•1、安装mysql(本文省略)•2、安装主从•3、安装MHA•4、安装proxySQL•5、数据迁移(本文省略)•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.cnf
vi /etc/my.cnf
# GTID 主从复制
server-id = 3
expire_logs_days = 7
gtid_mode = on
log-bin = /data0/mysql/mysql-binlog
binlog_format = row
log_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 = 2M
datadir=/data0/mysql
socket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
pid-file=/var/run/mysqld/mysqld.pid
# GTID 主从复制
server-id = 3
expire_logs_days = 7
gtid_mode = on
log-bin = /data0/mysql/mysql-binlog
binlog_format = row
log_slave_updates = 1
skip_name_resolve = 1
open_files_limit = 65535
back_log = 1024
max_connections = 1000
max_connect_errors = 1000000
table_open_cache = 1024
table_definition_cache = 1024
table_open_cache_instances = 64
thread_stack = 512K
external-locking = FALSE
max_allowed_packet = 32M
sort_buffer_size = 4M
join_buffer_size = 4M
thread_cache_size = 768
query_cache_size = 0
query_cache_type = 0
interactive_timeout = 600
wait_timeout = 600
tmp_table_size = 32M
max_heap_table_size = 32M
slow_query_log = 1
slow_query_log_file = /data0/mysql/slow.log
log-error = /data0/mysql/error.log
long_query_time = 2
sync_binlog = 1
binlog_cache_size = 4M
max_binlog_cache_size = 1G
max_binlog_size = 1G
enforce_gtid_consistency = 1
master_info_repository = TABLE
relay_log_info_repository = TABLE
key_buffer_size = 32M
read_buffer_size = 8M
read_rnd_buffer_size = 4M
bulk_insert_buffer_size = 64M
relay_log_recovery = 1
relay-log-purge = 1
lock_wait_timeout = 3600
explicit_defaults_for_timestamp = 1
innodb_thread_concurrency = 0
innodb_sync_spin_loops = 100
innodb_spin_wait_delay = 30
innodb_buffer_pool_size = 1024M
innodb_buffer_pool_instances = 8
innodb_buffer_pool_load_at_startup = 1
innodb_buffer_pool_dump_at_shutdown = 1
transaction_isolation = REPEATABLE-READ
innodb_flush_log_at_trx_commit = 1
innodb_log_buffer_size = 32M
innodb_log_file_size = 2G
innodb_log_files_in_group = 2
innodb_flush_neighbors = 0
innodb_write_io_threads = 8
innodb_read_io_threads = 8
innodb_purge_threads = 8
innodb_page_cleaners = 4
innodb_open_files = 65535
innodb_flush_method = O_DIRECT
innodb_checksum_algorithm = crc32
innodb_lru_scan_depth = 4000
innodb_lock_wait_timeout = 10
innodb_rollback_on_timeout = 1
innodb_print_all_deadlocks = 1
innodb_file_per_table = 1
innodb_online_alter_log_max_size = 4G
internal_tmp_disk_storage_engine = InnoDB
innodb_stats_on_metadata = 0
innodb_status_file = 1
innodb_status_output = 0
innodb_status_output_locks = 0
performance_schema = 1
performance_schema_instrument = '%=on'
# innodb monitor
innodb_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]
quick
max_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;
# 从1
ssh-copy-id -i ~/.ssh/id_dsa.pub 172.31.145.38;
# 从2
ssh-copy-id -i ~/.ssh/id_dsa.pub 172.31.145.40;
注意:在manager节点安装在mysql主从复制集群中的一台服务器的前提下,一定要让本机也可以免密ssh登录本机。
三台机器,以上命令都执行一遍。
3、添加hosts
sudo vi /etc/hosts
172.31.145.39 node1
172.31.145.38 node2
172.31.145.40 node3
sudo echo 172.31.145.39 node1 >> /etc/hosts
sudo echo 172.31.145.38 node2 >> /etc/hosts
sudo echo 172.31.145.40 node3 >> /etc/hosts
三台机器,以上命令都执行一遍。
4、互信测试
ssh node1
ssh node2
ssh node3
三台机器,以上命令都执行一遍。
成功信息如下:
[mysql@iZm5e2mylql8b8vqklsir7Z ~]$ ssh node1
Last login: Mon Mar 30 21:50:50 2020 from 172.31.145.39
Welcome to Alibaba Cloud Elastic Compute Service !
[mysql@iZm5ebq5g3dxxlguud3akeZ ~]$ ssh node2
Last login: Mon Mar 30 21:52:50 2020 from 172.31.145.40
Welcome to Alibaba Cloud Elastic Compute Service !
[mysql@iZm5e2mylql8b8vqklsir7Z ~]$ ssh node3
Last 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 slave•GTID + row
主要配置
# 编辑my.cnf
vi /etc/my.cnf
# GTID 主从复制
server-id = 3
expire_logs_days = 7
gtid_mode = on
log-bin = /data0/mysql/mysql-binlog
binlog_format = row
log_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入门与提高实践》