摘要
MySql单节点、主从、双主的构建过程,及其配置文件的说明
本文基于mysql-8.0.30
1.单节点
安装
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 wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.30-linux-glibc2.12-x86_64.tar.xz tar -Jxvf mysql-8.0.30-linux-glibc2.12-x86_64.tar.xz mv mysql-8.0.30-linux-glibc2.12-x86_64 mysql8sudo sugroupadd mysql useradd -r -g mysql -s /bin/false mysql cd mysql8mkdir -p datas/mysqlchown -R mysql:mysql dataschmod -R 750 datasvim /etc/bashrc export PATH=$PATH :/usr/local/soft/mysql8/bintouch my.cnf
警告⚠️
默认情况下,mysql按照下面的文件顺序加载配置,后面的配置会覆盖前面的配置
/etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf ~/.my.cnf
建议将配置文件创建到/etc/my.cnf
,这样所有用户都可以使用,特殊配置可以创建在当前用户的~/.my.cnf
中。
本文以下内容除特殊指定配置文件路径外,都是基于/etc/my.cnf
的默认配置文件
配置
配置段说明
[mysql] 和 [client] 都是针对客户端的配置,后面的配置会覆盖前面的相同配置
[mysql] 只针对 mysql
命令,可以通过mysql --help
查看配置项及其缺省值
[client] 针对 mysql
、mysqldump
、mysqlimport
、mysqladmin
, 等等,所有的客户端命令
[mysqld] 只是针对服务器端的配置,针对 mysqld
命令,可以通过mysqld --verbose --help
查看配置项及其缺省值
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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 vim my.cnf [mysql] default-character-set=utf8mb4 local_infile=ON [client] default-character-set=utf8mb4 port = 3306 socket = /tmp/mysql.sock [mysqld] skip-name-resolve secure_file_priv="" local_infile=ON default_authentication_plugin=mysql_native_password port = 3306 server-id = 1001 user = mysql socket = /tmp/mysql.sock basedir = /usr/local/soft/mysql8 datadir = /usr/local/soft/mysql8/datas/mysql log-bin = mysql-bin binlog-format = ROW binlog_expire_logs_seconds =864000 sync-binlog=0 innodb_data_home_dir =./ innodb_log_group_home_dir =./ log-error =mysql.log pid-file =mysql.pid character-set-server=utf8mb4 lower_case_table_names=1 autocommit =1 slow_query_log=1 slow_query_log_file=db_slow.log long_query_time=5 log_output=FILE log_queries_not_using_indexes=1 skip-external-locking key_buffer_size = 256M max_allowed_packet = 64M table_open_cache = 1024 sort_buffer_size = 4M net_buffer_length = 8K read_buffer_size = 4M read_rnd_buffer_size = 512K myisam_sort_buffer_size = 64M thread_cache_size = 64 tmp_table_size = 128M explicit_defaults_for_timestamp = true max_connections = 500 max_connect_errors = 100 open_files_limit = 65535 default_storage_engine = InnoDB innodb_data_file_path = ibdata1:10M:autoextend innodb_buffer_pool_size = 1024M innodb_log_buffer_size = 16M innodb_flush_log_at_trx_commit = 1 innodb_lock_wait_timeout = 50 [mysqldump] quick max_allowed_packet = 16M [myisamchk] key_buffer_size = 256M sort_buffer_size = 4M read_buffer = 2M write_buffer = 2M [mysqlhotcopy] interactive-timeout
数据库初始化
1 2 3 4 5 6 sudo mysqld --user=mysql --initialize-insecuresudo mysqld --defaults-file=/usr/local/soft/mysql8/my.cnf --user=mysql --initialize-insecure
启动数据库
1 2 3 4 5 6 7 8 9 sudo mysqld_safe --user=mysql &sudo mysqld_safe --defaults-file=/usr/local/soft/mysql8/my.cnf --user=mysql &ps -ef|grep mysql
开机启动+启动关闭mysql命令
方法1[推荐]:使用mysql提供的脚本
1 2 3 4 5 6 7 8 9 10 cd /usr/local/soft/mysql8/support-files/sudo cp mysql.server /etc/init.d/mysqldsudo systemctl enable mysqldchkconfig --list sudo systemctl disable mysqld
1 2 3 4 sudo systemctl start mysqldsudo systemctl stop mysqld
方法2:自己写命令
1 2 3 4 5 6 7 8 9 10 11 sudo chmod +x /etc/rc.d/rc.localsudo vim /etc/rc.localsudo /usr/local/soft/mysql8/bin/mysqld_safe --user=mysql &sudo /usr/local/soft/mysql8/bin/mysqld_safe --defaults-file=/usr/local/soft/mysql8/my.cnf --user=mysql &
1 2 3 4 5 6 7 8 9 10 sudo /usr/local/soft/mysql8/bin/mysqld_safe --defaults-file=/usr/local/soft/mysql8/my.cnf --user=mysql &sudo /usr/local/soft/mysql8/bin/mysqladmin -uroot -ppassword shutdownsudo vim /etc/bashrcalias mysql-start="sudo /usr/local/soft/mysql8/bin/mysqld_safe --user=mysql &" alias mysql-stop="sudo /usr/local/soft/mysql8/bin/mysqladmin -uroot -ppassword shutdown"
检查mysql是否启动成功
1 2 3 4 5 6 7 8 9 10 > ps aux | grep mysqld root 3960 0.0 0.0 124212 3240 ? S 03:13 0:00 /bin/sh /usr/local/soft/mysql8/bin/mysqld_safe --datadir=/usr/local/soft/mysql8/datas/mysql --pid-file=/usr/local/soft/mysql8/datas/mysql/mysql.pid mysql 5071 0.9 13.1 3167692 529720 ? Sl 03:13 0:02 /usr/local/soft/mysql8/bin/mysqld --basedir=/usr/local/soft/mysql8 --datadir=/usr/local/soft/mysql8/datas/mysql --plugin-dir=/usr/local/soft/mysql8/lib/plugin --user=mysql --log-error=/usr/local/soft/mysql8/datas/mysql/mysql.log --open-files-limit=65535 --pid-file=/usr/local/soft/mysql8/datas/mysql/mysql.pid --socket=/tmp/mysql.sock --port=3306 root 5320 0.0 0.0 119448 920 pts/0 S+ 03:18 0:00 grep --color=auto mysqld > netstat -tunpl | grep 3306 tcp6 0 0 :::33060 :::* LISTEN 5071/mysqld tcp6 0 0 :::3306 :::* LISTEN 5071/mysqld
登录
1 2 3 4 5 6 7 8 9 mysql -uroot --skip-password mysql -uroot -p mysql -uroot -p -hxxx.xxx.xxx.xxx -P3306
1 error while loading shared libraries:libtinfo.so.5: cannot open shared object file : No such file or directory
解决方法
1 2 sudo ln -s /usr/lib64/libtinfo.so.6.0 /usr/lib64/libtinfo.so.5
修改密码
1 2 3 4 5 6 7 mysql> ALTER USER 'root' @'localhost' IDENTIFIED WITH mysql_native_password BY '123456' ; mysql> ALTER USER 'root' @'localhost' IDENTIFIED BY '123456' ; mysql> FLUSH PRIVILEGES;
授予root用户system_user
权限
1 2 mysql> grant system_user on *.* to 'root' @'localhost' ; mysql> flush privileges;
开启远程访问
1 2 3 4 5 mysql> use mysql; mysql> update user set user.Host='%' where user.User='root' ; mysql> flush privileges; mysql> select user,host from user;
警告⚠️
非常不建议开启root用户的远程访问权限,建议新创建一个用户,并仅授予必要的权限
1 2 3 4 5 6 7 8 9 10 11 12 mysql> CREATE USER 'username' @'%' IDENTIFIED BY 'password' ; mysql> CREATE DATABASE my_database CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; mysql> GRANT all privileges ON my_database.* TO 'username' @'%' ; mysql> FLUSH PRIVILEGES; mysql> show grants for username@"%" \G mysql> select user,host from mysql.user;
关闭mysql
1 sudo mysqladmin -uroot -p shutdown
2.主从
1 2 master: 10.250.0.243 slave: 10.250.0.82
auto.cnf
1 2 [auto] server-uuid=6e9a571e-330e-11ed-a3f8-0a53e7cced43
master配置文件
1 2 3 4 server-id = 1001 log-bin = mysql-bin
slave配置文件
1 2 3 4 5 6 7 8 9 10 server-id = 1002 relay-log-index=slave-relay-bin.index relay-log=slave-relay-bin relay_log_purge=1 log_slave_updates=1
主库创建同步帐号
1 2 3 4 5 mysql> CREATE USER 'vagrant' @'10.250.%.%' IDENTIFIED BY 'vagrant' ; mysql> ALTER USER 'vagrant' @'10.250.%.%' IDENTIFIED WITH mysql_native_password BY 'vagrant' ; mysql> GRANT REPLICATION SLAVE ON *.* TO 'vagrant' @'10.250.%.%' ; mysql> FLUSH PRIVILEGES;
如果此时主库已经有数据,则需要先将主库数据导入到从库后再开启主从复制
1 2 3 4 5 6 7 8 9 10 11 12 mysqldump -uroot --all-databases --triggers --routines --events -p > all_databases.sql mysql> FLUSH TABLES WITH READ LOCK; mysql> UNLOCK TABLES; mysql -uroot -p < all_databases.sql
从节点设置同步
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 mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000008 | 1140 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) mysql> CHANGE MASTER TO MASTER_HOST='10.250.0.243' , MASTER_PORT=3306, MASTER_USER='vagrant' , MASTER_PASSWORD='vagrant' , MASTER_LOG_FILE='mysql-bin.000008' , MASTER_LOG_POS=1140; mysql> START slave; mysql> SHOW slave status \G; *************************** 1. row *************************** Slave_IO_State: Master_Host: 10.250.0.243 Master_User: vagrant Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000008 Read_Master_Log_Pos: 1140 Relay_Log_File: slave-relay-bin.000001 Relay_Log_Pos: 4 Relay_Master_Log_File: mysql-bin.000008 Slave_IO_Running: Yes Slave_SQL_Running: Yes
如果Slave_IO_Running
和Slave_SQL_Running
都是Yes
,则说明主从复制配置成功。
此时在master中执行SHOW PROCESSLIST;
可以查看到同步信息
1 2 3 4 5 6 7 8 9 mysql> SHOW PROCESSLIST; +----+-----------------+-------------------+------+-------------+------+-----------------------------------------------------------------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+-----------------+-------------------+------+-------------+------+-----------------------------------------------------------------+------------------+ | 5 | event_scheduler | localhost | NULL | Daemon | 49 | Waiting on empty queue | NULL | | 8 | vagrant | 10.250.0.82:33924 | NULL | Binlog Dump | 49 | Source has sent all binlog to replica; waiting for more updates | NULL | | 9 | root | 127.0.0.1:42410 | NULL | Query | 0 | init | SHOW PROCESSLIST | +----+-----------------+-------------------+------+-------------+------+-----------------------------------------------------------------+------------------+ 3 rows in set (0.00 sec)
主从架构,从库应该是禁止写操作的,否则有可能会导致主从同步失败(如主键冲突),所以为了保证数据的一致性,应该禁止从库写操作。
1 2 3 4 5 read_only=1 super_read_only=1
开启GTID(全局事务ID)主从复制模式
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 gtid_mode=on enforce_gtid_consistency=on mysql> show master status; +------------------+----------+--------------+------------------+----------------------------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+----------------------------------------+ | mysql-bin.000014 | 1183 | | | 6e9a571e-330e-11ed-a3f8-0a53e7cced42:1 | +------------------+----------+--------------+------------------+----------------------------------------+ 1 row in set (0.00 sec) mysql> SHOW VARIABLES like "%gtid%" ; +----------------------------------+----------------------------------------+ | Variable_name | Value | +----------------------------------+----------------------------------------+ | binlog_gtid_simple_recovery | ON | | enforce_gtid_consistency | ON | | gtid_executed | 6e9a571e-330e-11ed-a3f8-0a53e7cced42:1 | | gtid_executed_compression_period | 0 | | gtid_mode | ON | | gtid_next | AUTOMATIC | | gtid_owned | | | gtid_purged | | | session_track_gtids | OFF | +----------------------------------+----------------------------------------+ 9 rows in set (0.00 sec)
主从架构,一个master可以配置多个slave。
1 2 3 4 5 6 7 8 9 10 是由日本人开发的一个基于Perl脚本写的工具。这个工具专门用于监控主库的状态, 当发现master节点故障时,会提升其中拥有新数据的slave节点成为新的master节点, 在此期间,MHA会通过其他从节点获取额外的信息来避免数据一致性方面的问题。 MHA还提供了mater节点的在线切换功能,即按需切换master-slave节点。 MHA能够在30秒内实现故障切换,并能在故障切换过程中,最大程度的保证数据一致性。 MHA是需要单独部署的,分为Manager节点和Node节点,两种节点。 其中Manager节点一般是单独部署的一台机器。而Node节点一般是部署在每台MySQL机器上的。 Node节点得通过解析各个MySQL的日志来进行一些操作。 Manager节点会通过探测集群里的Node节点去判断各个Node所在机器上的MySQL运行是否正常, 如果发现某个Master故障了,就直接把他的一个Slave提升为Master,然后让其他Slave都挂到新的Master上去,完全透明。
MHA安装包下载地址:https://github.com/yoshinorim/mha4mysql-manager/releases
MHA使用说明:https://github.com/yoshinorim/mha4mysql-manager/wiki
3.双主
双主模式就是两个mysql互为主从
两个master都不能设置只读
以上面主从为例,我们继续搭建双主架构
从库关闭只读并开启binlog
1 2 3 4 5 6 7 8 9 server-id = 1002 log-bin = mysql-bin
主库也要开启中继日志
1 2 3 4 5 6 7 8 9 10 server-id = 1001 relay-log-index=slave-relay-bin.index relay-log=slave-relay-bin relay_log_purge=1 log_slave_updates=1
从库上创建同步帐号
1 2 3 4 5 mysql> CREATE USER 'vagrant' @'10.250.%.%' IDENTIFIED BY 'vagrant' ; mysql> ALTER USER 'vagrant' @'10.250.%.%' IDENTIFIED WITH mysql_native_password BY 'vagrant' ; mysql> GRANT REPLICATION SLAVE ON *.* TO 'vagrant' @'10.250.%.%' ; mysql> FLUSH PRIVILEGES;
查看从库的master状态
1 2 3 4 5 6 7 mysql> SHOW master status; +------------------+----------+--------------+------------------+----------------------------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+----------------------------------------+ | mysql-bin.000014 | 1183 | | | 6e9a571e-330e-11ed-a3f8-0a53e7cced42:1 | +------------------+----------+--------------+------------------+----------------------------------------+ 1 row in set (0.00 sec)
主库上配置主从信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 mysql> CHANGE MASTER TO MASTER_HOST='10.250.0.82' , MASTER_PORT=3306, MASTER_USER='vagrant' , MASTER_PASSWORD='vagrant' , MASTER_LOG_FILE='mysql-bin.000014' , MASTER_LOG_POS=1183; mysql> START slave; mysql> SHOW slave status \G; *************************** 1. row *************************** Slave_IO_State: Waiting for source to send event Master_Host: 10.250.0.82 Master_User: vagrant Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000014 Read_Master_Log_Pos: 1183 Relay_Log_File: slave-relay-bin.000002 Relay_Log_Pos: 326 Relay_Master_Log_File: mysql-bin.000014 Slave_IO_Running: Yes Slave_SQL_Running: Yes
此时双主架构搭建完成。
双主架构下,每个master还可以配置多个slave用于数据备份。
双主架构自增主键冲突问题解决方法
1 2 3 4 5 6 7 8 9 10 auto_increment_offset = 1 auto_increment_increment = 2 auto_increment_offset = 2 auto_increment_increment = 2
双主高可用架构:MMM(Master-Master replication managerfor Mysql,Mysql主主复制管理器)
1 2 3 4 5 是一套由Perl语言实现的脚本程序,可以对mysql集群进行监控和故障迁移。 他需要两个Master,同一时间只有一个Master对外提供服务,可以说是主备模式。 他是通过一个VIP(虚拟IP)的机制来保证集群的高可用。 整个集群中,在主节点上会通过一个VIP地址来提供数据读写服务, 而当出现故障时,VIP就会从原来的主节点漂移到其他节点,由其他节点提供服务。
4.半同步复制
1 2 3 4 5 6 无论是主从复制还是双主复制,默认数据同步都是异步进行,主服务在向客户端反馈执行结果时,是不知道binlog是否同步成功了的。 这时候如果主服务宕机了,而从服务还没有备份到新执行的binlog,那就有可能会丢数据。 那怎么解决这个问题呢,这就要靠MySQL的半同步复制机制来保证数据安全。 半同步复制机制是一种介于异步复制和全同步复制之前的机制。 主库在执行完客户端提交的事务后,并不是立即返回客户端响应,而是等待至少一个从库接收并写到relay log中,才会返回给客户端。 MySQL在等待确认时,默认会等10秒,如果超过10秒没有收到ack,就会降级成为异步复制。
安装半同步复制插件
1 2 3 4 5 6 7 mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so' ; Query OK, 0 rows affected, 1 warning (0.02 sec) mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so' ; Query OK, 0 rows affected, 1 warning (0.01 sec)
如果是双主架构,则都需要安装两个插件
开启配置
1 2 3 4 5 rpl_semi_sync_master_enabled=1 rpl_semi_sync_slave_enabled=1
重启mysql后查看是否配置成功
1 2 3 4 5 6 7 8 9 10 11 12 13 mysql> show global variables like 'rpl_semi%' ; +-------------------------------------------+------------+ | Variable_name | Value | +-------------------------------------------+------------+ | rpl_semi_sync_master_enabled | ON | | rpl_semi_sync_master_timeout | 10000 | | rpl_semi_sync_master_trace_level | 32 | | rpl_semi_sync_master_wait_for_slave_count | 1 | | rpl_semi_sync_master_wait_no_slave | ON | | rpl_semi_sync_master_wait_point | AFTER_SYNC | | rpl_semi_sync_slave_enabled | ON | | rpl_semi_sync_slave_trace_level | 32 | +-------------------------------------------+------------+