11月13日mysql进阶3 mysql半同步复制、读写分离和主节点的高可用

1、半同步复制

半同步复制指当一个主节点有多个从节点时,其中一个或几个从节点使用同步复制的方式,其他从节点使用异步复制的方式,称为半同步复制,同步复制时客户端在访问mysql数据库并完成一个写操作后,从节点会立即将数据同步到本地并将结果反馈给主节点,证明自己已经同步完成,客户端才能进行第二次写操作,如果主节点等待从节点反馈的时间超过了规定的超时时间,这个从节点会自动降级为异步复制模方式。
实现过程如下:

1、配置一个主从复制的集群,并测试主从复制可用
2、在主上的设置
MariaDB [(none)]> install plugin rpl_semi_sync_master soname 'semisync_master.so';   
---在主节点上安装半同步的插件,rpl_semi_sync_master为插件的名字,semisync_master.so为模块的名字,可以通过rpm -ql mariadb-server获得模块的名字
MariaDB [(none)]> set @@global.rpl_semi_sync_master_enabled=on;  ---开启半同步插件
MariaDB [(none)]> show global variables like 'rpl_semi%';
+------------------------------------+-------+
| Variable_name                      | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled       | ON    |   ---发现已经开启
| rpl_semi_sync_master_timeout       | 10000 |   ---定义超时时长,如果10s没有反馈结果给主节点,这个从节点就自动降级为异步复制
| rpl_semi_sync_master_trace_level   | 32    |
| rpl_semi_sync_master_wait_no_slave | ON    |  ---没有从节点时是否开启同步复制
+------------------------------------+-------+
MariaDB [(none)]> show global status like 'rpl_semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 0    |   ---发现连接的从节点为0
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 0     |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
| Rpl_semi_sync_master_tx_wait_time          | 0     |
| Rpl_semi_sync_master_tx_waits              | 0     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 0     |
+--------------------------------------------+-------+
3、在从节点上的设置
MariaDB [(none)]> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';    ---从节点安装半同步复制插件
MariaDB [(none)]> set @@global.rpl_semi_sync_slave_enabled=on;   ---开启同步复制插件
MariaDB [(none)]> show global variables like 'rpl_semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+

MariaDB [(none)]> show global status like 'rpl_semi%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | OFF   |    ---此时发现仍然是关闭的
+----------------------------+-------+
MariaDB [(none)]> stop slave io_thread;
MariaDB [(none)]> start slave io_thread;   ---重新开启io_thread线程
MariaDB [(none)]> show global status like 'rpl_semi%';  ---发现开启了
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
4、在主节点上的操作
MariaDB [(none)]> show global status like 'rpl_semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |  ---发现已经有一个同步复制的从节点了,从节点相对于主节点就是客户端,因为从节点要连接到主节点上进行复制
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 0     |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
| Rpl_semi_sync_master_tx_wait_time          | 0     |
| Rpl_semi_sync_master_tx_waits              | 0     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 0     |
+--------------------------------------------+-------+
MariaDB [(none)]> use mydb;
MariaDB [mydb]> create table students (id int unsigned primary key auto_increment,name char(20) not null,age int unsigned,gender enum('F','M'),major varchar(30));   ---创建一个表
MariaDB [mydb]> show global status like 'rpl_semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |
| Rpl_semi_sync_master_net_avg_wait_time     | 411   |  ---发现网络的平均等待时间大概为0.5s
| Rpl_semi_sync_master_net_wait_time         | 411   |
| Rpl_semi_sync_master_net_waits             | 1     |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 475   |  ---写到事物日志的平均等待时间也是0.5s左右
| Rpl_semi_sync_master_tx_wait_time          | 475   |
| Rpl_semi_sync_master_tx_waits              | 1     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 1     |
+--------------------------------------------+-------+
MariaDB [mydb]> insert into students (name,age,gender)values('zhang',31,'F');   ---插入一些数据
MariaDB [mydb]> show global status like 'rpl_semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |
| Rpl_semi_sync_master_net_avg_wait_time     | 581   |  ---网络平均等待时间0.5s左右
| Rpl_semi_sync_master_net_wait_time         | 1163  |
| Rpl_semi_sync_master_net_waits             | 2     |   ---网络等待2次
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 412   |
| Rpl_semi_sync_master_tx_wait_time          | 825   |
| Rpl_semi_sync_master_tx_waits              | 2     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 2     |
+--------------------------------------------+-------+
5、在从节点上的操作
MariaDB [mydb]> select * from students;   ---发现同步完成
+----+-------+------+--------+-------+
| id | name  | age  | gender | major |
+----+-------+------+--------+-------+
|  1 | zhang |   31 | F      | NULL  |
+----+-------+------+--------+-------+

2、复制过滤器

仅复制有限一个或几个数据库相关的数据,而非所有;由复制过滤器进行;
有两种实现思路:
(1) 主服务器
主服务器仅向二进制日志中记录有关特定数据库相关的写操作;
问题:其它库的time-point recovery将无从实现,因为二进制日志不全,所以对于其他库无法进行重放二级制日志,一般这种方法不会使用;
binlog_do_db=
binlog_ignore_db=
(2) 从服务器
从服务器的SQL _THREAD仅重放关注的数据库或表相关的事件,并将其应用于本地;
问题:网络IO和磁盘IO,因为会将所有库的数据复制到从服务器的中继日志中,只是从中继日志中重放的时候只会挑选特定的数据库或表进行重放;
Replicate_Do_DB= ---只复制某个库
Replicate_Ignore_DB= ---除了某个库都复制
Replicate_Do_Table=
Replicate_Ignore_Table=
Replicate_Wild_Do_Table= ---可以用通配符表示表明,比如*mydb
Replicate_Wild_Ignore_Table=
示例

此实验是在1中示例的基础上进行的
在从节点上的操作
MariaDB [mydb]> stop slave;
MariaDB [mydb]> set @@global.Replicate_Ignore_db=hellodb;    ---表示设置hellodb这个数据库不复制,如果要长期有效要写到配置文件里
MariaDB [mydb]> start slave;
MariaDB [mydb]> show slave status \G  ---可以看到不复制的数据库
2、在主节点上的操作
MariaDB [mydb]> create database hellodb;
3、在从节点上的操作
MariaDB [mydb]> show databases;   ---没有发现hellodb这个数据库
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mydb               |
| mysql              |
| performance_schema |
| test               |
+--------------------+

3、复制的监控和维护

(1) 清理二进制日志:PURGE
PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetime_expr };
使用purge删除二进制日志后,mysql重新启动时不会读取删除的二进制日志文件,这样不会报错
示例

MariaDB [hellodb]> show binary logs;
+----------------+-----------+
| Log_name       | File_size |
+----------------+-----------+
| bin-log.000001 |     30370 |
| bin-log.000002 |   1038814 |
| bin-log.000003 |      1356 |
+----------------+-----------+
3 rows in set (0.00 sec)

MariaDB [hellodb]> purge binary logs to 'bin-log.000003';
Query OK, 0 rows affected (0.01 sec)

MariaDB [hellodb]> show binary logs;
+----------------+-----------+
| Log_name       | File_size |
+----------------+-----------+
| bin-log.000003 |      1356 |
+----------------+-----------+
1 row in set (0.00 sec)
[root@centos7 ~]#cd /var/lib/mysql/
[root@centos7 mysql]#ls
aria_log.00000001  bin-log.000003  hellodb  ib_logfile0  mydb   mysql.sock          test
aria_log_control   bin-log.index   ibdata1  ib_logfile1  mysql  performance_schema
[root@centos7 mysql]#cat bin-log.index   ---发现对应的数据目录下的二进制日志的索引也会被删除
./bin-log.000003

(2) 复制监控
MASTER:
SHOW MASTER STATUS;查看正在使用的二进制日志
SHOW BINLOG EVENTS;查看二进制日志中的事件
SHOW BINARY LOGS;查看二进制日志列表
SLAVE:
SHOW SLAVE STATUS;查看从服务器的状态
判断从服务器是否落后于主服务器:
show slave status \G里面可以看到如下语句
Seconds_Behind_Master: 0
(3) 如何确定主从节点数据是否一致?
通过表的CHECKSUM检查;
使用percona-toolkit中pt-table-checksum;
(4) 主从数据不一致时的修复方法?
备份恢复后重新设置主从复制;

4、实现基于ProxySQL的复制读写分离

11月13日mysql进阶3 mysql半同步复制、读写分离和主节点的高可用_第1张图片
无标题1.png
1、搭建好主从复制集群,在从服务器上设置hellodb数库据不复制
开启主从复制功能
在主服务器上创建两个账号,一个用于前端调度器连接后端数据
库获取数据用,一个用于前端调度器监控后端服务器的健康状态
用,因为事先已经实现了主从复制,所以在主上创建时在从上也
会有这两个账号
MariaDB [(none)]> grant all on *.* to dbadmin@'172.18.%.%' identified by 'centos';   ---此用户也可以用于客户端访问proxysql主机用
MariaDB [(none)]> grant all on *.* to monitor@'172.18.%.%' identified by 'monitor';  ---注意这个账号创不创建都可以,只是用于监控后端主机用的
2、在官方网站上下载proxysql,并安装在前端调度器上
http://www.proxysql.com/
yum install proxysql-1.4.2-1-centos7.x86_64.rpm 
3、在前端调度器上配置proxysql
vim /etc/proxysql.cnf 
datadir="/var/lib/proxysql"
admin_variables=
{
        admin_credentials="admin:admin"
        mysql_ifaces="127.0.0.1:6032;/tmp/proxysql_admin.sock" ---proxysql的一个管理接口,可以连接到这个管理接口上进行管理proxysql
}
mysql_variables=
{
        threads=4
        max_connections=2048
        default_query_delay=0
        default_query_timeout=36000000
        have_compress=true
        poll_timeout=2000
        interfaces="0.0.0.0:3306;/tmp/mysql.sock"  ---将端口改为3306,这样用客户端就可以用mysql连接时不必指定端口号
 # default_schema="information_schema"
        stacksize=1048576
        server_version="5.5.30"
        connect_timeout_server=3000
 monitor_username="monitor"  ---设置一个监测后端主机的用户,设置了这个用户就可连接到后端主机进行监控后端主机的健康状态
        monitor_password="monitor"   ---设置密码
        monitor_history=600000
        monitor_connect_interval=60000
        monitor_ping_interval=10000
        monitor_read_only_interval=1500
        monitor_read_only_timeout=500
        ping_interval_server_msec=120000
        ping_timeout_server=500
        commands_stats=true
        sessions_sort=true
        connect_retries_on_failure=10
}
mysql_servers =
(
        {
                address = "172.18.21.107" # no default, required . If port is 0 , address is interpred as a Unix Socket Domain
                port = 3306           # no default, required . If port is 0 , address is interpred as a Unix Socket Domain
                hostgroup = 0           # no default, required #主数据库服务器为0组
                status = "ONLINE"     # default: ONLINE
              weight = 1            # default: 1
                compression = 0       # default: 0
#   max_replication_lag = 10  # default 0 . If greater than 0 and replication lag passes such threshold, the server is shunned
        },
        {
                address = "172.18.21.7" # no default, required . If port is 0 , address is interpred as a Unix Socket Domain
                port = 3306           # no default, required . If port is 0 , address is interpred as a Unix Socket Domain
                hostgroup = 1           # no default, required #从数据库服务器为1组
                status = "ONLINE"     # default: ONLINE
               weight = 1            # default: 1
                compression = 0       # default: 0
#   max_replication_lag = 10  # default 0 . If greater than 0 and replication lag passes such threshold, the server is shunned
        }
mysql_users:  ---设置一个用户用于proxysql连接到后端主机获取数据用,客户端连接前端调度器获取数据时也用这个用户
(
        {
                username = "dbadmin" # no default , required
                password = "centos" # default: ''
                default_hostgroup = 0 # default: 0
                active = 1            # default: 1
        }
mysql_query_rules:  ---设置路由规则
(
  {
                rule_id=2
                active=1
                match_pattern="^SELECT"   --以查询打头的就调度至1组,也就是从服务器上
                destination_hostgroup=1
                apply=1
        }
)
mysql_replication_hostgroups=
(
    {
                writer_hostgroup=0   ---写调度至0组
                reader_hostgroup=1  ---读调度至1组
                comment="test repl 1"
       }
)
service proxysql start
ss -nlt
mysql -S /tmp/proxysql_admin.sock -uadmin -padmin  ---登录到管理端口上
show databases;
show tables;  ---查看调度器上一些数据库和一些表
MySQL [(none)]> select * from mysql_servers;  ---查看后端服务器的一些信息
+--------------+---------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| hostgroup_id | hostname      | port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment |
+--------------+---------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| 0            | 172.18.21.107 | 3306 | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
| 1            | 172.18.21.7   | 3306 | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
+--------------+---------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
mysql -udbadmin -pcentos  -h172.18.21.200 ---客户端访问此调度器
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.5.30 (ProxySQL)  ---可以看到访问的是proxysql
Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>SELECT * from hellodb.tbl1;    ---发现调度至从服务器上,因为从服务器上不复制hellodb数据库,在这里一定要注意,SELECT要用大写,不然只会往主上调度,识别不了,前面做实验一直失败就是这个原因。
ERROR 1146 (42S02): Table 'hellodb.tbl1' doesn't exist
MySQL [(none)]> insert intohellodb.tbl1values(2,'li'); #发现可以插入数据,因为写操作调度至主服务器上了

5、实现master HA 主数据库服务器的高可用

MHA是一款开源的MySQL高可以用程序,MHA在监控到master节点故障时,会自动提升其中拥有最新数据的slave节点成为新的master节点,在此期间,MHA会获取其他节点的额外信息来避免一致性方面的问题,也就是MHA会获取其他从节点中的数据信息,并将信息发给最接近主节点的从节点,这样主节点故障时会提升此从节点为主节点,而此从节点拥有其他从节点所有的数据信息,MHA还提供了master节点的在线切换功能,即按需切换master/slave节点。
实现过程如下:


11月13日mysql进阶3 mysql半同步复制、读写分离和主节点的高可用_第2张图片
无标题2.png
1、同步各节点的时间,并修改各节点的主机名为如上图所示
2、修改/etc/hosts文件,使各节点能互相解析主机名
vim /etc/hosts    ---各节点的hosts文件都是一样的
172.18.21.200 node1.magedu.com node1
172.18.21.107 node2.magedu.com node2
172.18.21.7 node3.magedu.com node3
172.18.21.100 node4.magedu.com node4
3、使各节点能基于ssh秘钥的验证
在node1节点上操作
ssh-keygen   ---生成公钥私钥对
ssh-copy-id node1:   ---将秘钥文件保存在自己的家目录下,会自动保存到root家目录的.ssh目录中
[root@node1 ~]# ls .ssh  ---可以发现公钥 和私钥对及秘钥文件都已经生成
authorized_keys  id_rsa  id_rsa.pub  known_hosts
scp -r .ssh/ node2:
scp -r .ssh/ node3:
scp -r .ssh/ node4:   ---将此目录传给其他节点,这样各节点就可以基于key的验证互相通讯了
注意:基于ssh的key的验证和能够互相解析主机名是此实验的前提
4、搭建好主从复制的集群环境,并确保复制运行无错误
在node2上的配置
vim /etc/my.cnf.d/server.cnf   ---开启二进制日志和中继日志,因为此节点将来可能变成从,所以也要开启中继日志
[server]
skip_name_resolve = on
innodb_file_per_table = on
max_connections = 20000
log_bin = bin-log
server_id = 1
relay-log = relay-log
在node3和node4上的配置
vim /etc/my.cnf.d/server.cnf 
[server]
skip_name_resolve = on
innodb_file_per_table = on
max_connections = 20000
relay-log = relay-log
server_id = 2  ---id号必须唯一
log-bin = bin-log
relay_log_purge = 0   --不修剪中继日志
read_only = 1   ---只读
5、在主从节点上授权一个用户,用于MHA连接到各主从节点进行管理及各主从节点间通讯用
在node2上操作,因为node2是主,创建后其他从节点也会有这个用户
MariaDB [(none)]> grant all on *.* to mhaadmin@'172.18.%.%' identified by 'centos';
MariaDB [(none)]> flush privileges;
注意:这里授权的用户不是只给MHA使用,其他的主从节点也要使用这个用户进行互相连接通讯,所以授权的时候要保证IP地址段对所有节点都能通过这个账号连接彼此
6、下载MHA软件包并安装
在https://github.com/官方网站上下载,搜索的时候输入mha
或者到如下网站上去下载
https://code.google.com/p/mysql-master-ha/wiki/Downloads?tm=2。
mha4mysql-manager-0.56-0.el6.noarch.rpm
mha4mysql-node-0.56-0.el6.noarch.rpm
在node1节点上安装mha4mysql-manager-0.56-0.el6.noarch.rpm和mha4mysql-node-0.56-0.el6.noarch.rpm两个软件包
在这里要注意,安装mha4mysql-manager-0.56-0.el6.noarch.rpm时会依赖会多的包,所以yum安装之前要把自己的yum仓库配置如下
root@node1 ~]# vim /etc/yum.repos.d/base.repo 
[base]
name=base
baseurl=http://mirrors.sohu.com/centos/7/os/x86_64/
gpgcheck=0
[epel]
name=epel
baseurl=https://mirrors.aliyun.com/epel/7/x86_64/    ---搜狐的epel包不全,安装不成功,只能用aliyun的
gpgcheck=0
安装之前要把网络配置好,保证node1节点能访问互联网
在其他node2、node3、node4节点上只安装mha4mysql-node-0.56-0.el6.noarch.rpm包即可
7、初始化MHA
mkdir /etc/masterha   ---创建一个配置文件
cd /etc/masterha
vim app1.cnf
[server default]
user=mhaadmin   ---用于MHA和各节点互相通讯的管理用户
password=centos
manager_workdir=/data/masterha/app1   ---MHA的工作目录
manager_log=/data/masterha/app1/manager.log  ---MHA的日志目录
remote_workdir=/data/masterha/app1  ---各节点的工作目录
ssh_user=root   ---ssh连接的用户,因为基于key的验证了,所以不用密码
repl_user=rpluser  ---主从复制时的用户,要确保node2、node3、node4节点都有此用户
repl_password=rpluser
ping_interval=1  ---MHA监控各节点的时间间隔

[server1]
hostname=172.18.21.107
candidate_master=1 

[server2]
hostname=172.18.21.7
candidate_master=1  ---是否可以做为候选,也就是主节点挂了,是否可以提升为主节点

[server3]
hostname=172.18.21.100
candidate_master=1
8、检查各节点ssh互相通讯是否ok
masterha_check_ssh --conf=/etc/masterha/app1.cnf 
All SSH connection tests passed successfully.   ---出现此行说明正常
检查管理的mysql复制集群的连接配置参数是否ok
masterha_check_repl --conf=/etc/masterha/app1.cnf
MySQL Replication Health is OK.   ---出现此行说明正常
9、在node1上启动MHA,并关闭node2节点的mariadb服务进行测试
masterha_manager --conf=/etc/masterha/app1.cnf    ---发现启动MHA后为前台运行的
在node2节点上关闭服务
systemctl stop mariadb
在node4上查看
MariaDB [(none)]> show slave status \G  ---发现node3变成了主,切换成功
在node1节点上
masterha_manager --conf=/etc/masterha/app1.cnf 
MySQL Replication Health is NOT OK!    ---发现主从复制集群已经not ok
10、如何恢复,在node2上进行如下配置
vim /etc/my.cnf.d/server.cnf
[server]
skip_name_resolve = on
innodb_file_per_table = on
max_connections = 20000
log_bin = bin-log
server_id = 1
relay-log = relay-log
relay_log_purge = 0   ---不修剪中继日志
read_only = on  --只读,修改这两项就可以
[root@node2 ~]#mysql
MariaDB [(none)]> change master to master_user='rpluser',master_host='172.18.21.7',master_password='centos',master_log_file='bin-log.000003',master_log_pos=245;   ---将自己变成node3的从,如果node2修复时间很长,恢复为从的时候要先将主上的数据进行一次全量备份,在node2上恢复后再进行恢复为从的操作,保证不丢失数据
MariaDB [(none)]> start slave;
MariaDB [(none)]> show slave status \G
11、在node1上检查
masterha_check_repl --conf=/etc/masterha/app1.cnf ---发现ok了
这样我们又可以启动监控了,为了保证监控时在后台执行,并且记录在日志中可以进行如下操作
[root@node1 masterha]# nohup masterha_manager --conf=/etc/masterha/app1.cnf &> /data/masterha/app1/manager.log &
故障转移完成后,manager将会自动停止,此时使用masterha_check_status --conf=/etc/masterha/app1.cnf 
命令将会遇到错误提示
app1 is stopped(2:NOT_RUNNING).
masterha_stop --conf=/etc/masterha/app1.cnf     ---停止MHA

6、mysql基础的优化方式

1、利用索引加快查询速度
2、利用查询缓存或者旁挂式缓存,提高访问速度
缓存:k/v
key:查询语句的hash值
value:查询语句的执行结果
哪些查询可能不会被缓存?
查询语句中包含UDF(User-Defined Functions)
存储函数
用户自定义变量
临时表
mysql系统表或者是包含列级别权限的查询
有着不确定结果值的函数(now());
查询缓存相关的服务器变量:
query_cache_limit:能够缓存的最大查询结果;(单语句结果集大小上限)
有着较大结果集的语句,显式使用SQL_NO_CACHE,以避免先缓存再移出; 也就是查询的时候用select * from students SQL_NO_CACHE
query_cache_min_res_unit:内存块的最小分配单位;缓存过小的查询结果集会浪费内存空间;
较小的值会减少空间浪费,但会导致更频繁地内存分配及回收操作; 较大值的会带来空间浪费;
query_cache_size:查询缓存空间的总共可用的大小;单位是字节,必须是1024的整数倍;
query_cache_strip_comments
query_cache_type:缓存功能启用与否;
ON:启用;
OFF:禁用;
DEMAND:按需缓存,仅缓存SELECT语句中带SQL_CACHE的查询结果;
query_cache_wlock_invalidate:如果某表被其它连接锁定,是否仍然可以从查询缓存中返回查询结果;默认为OFF,表示可以;ON则表示不可以;
状态变量:

mysql> SHOW GLOBAL STATUS LIKE 'Qcache%';
            +-------------------------+----------+
            | Variable_name           | Value    |
            +-------------------------+----------+
            | Qcache_free_blocks      | 1        |
            | Qcache_free_memory      | 16759688 |
            | Qcache_hits             | 0        |   ---查询缓存的命中率
            | Qcache_inserts          | 0        |
            | Qcache_lowmem_prunes    | 0        |
            | Qcache_not_cached       | 0        |
            | Qcache_queries_in_cache | 0        |
            | Qcache_total_blocks     | 1        |
            +-------------------------+----------+      
 mysql> show global status like '%Com_select%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_select    | 12    |    ---表示查询的次数
+---------------+-------+
命中率:
Qcache_hits/Com_select 

3、InnoDB存储引擎相关的参数:
innodb_buffer_pool_size:
索引、数据、插入数据时的缓冲区,数据先保存在内存缓冲区,从内存缓冲区保存到磁盘
做为专用服务器时设置为内存的70-80%;
如果数据集本身较小,可根据数据变化幅度及规划的时长设定合理值,比预估的目标值略大;
innodb_buffer_pool_instances:buffer_pool的区段(实例)数量;内存缓冲区被分成多个区端,这样锁定的时候不会锁定整张表,可能只是锁定表的一部分
4、事务日志:
innodb_log_files_in_group:一组内事物日志文件数量,至少2个;
innodb_log_file_size:日志文件大小,默认为5M;建议调大此值;
innodb_flush_logs_at_trx_commit:
0:log buffer(内存)每秒一次同步到log file中,且同时会进行log file到data file的同步操作;也就是每秒钟一次将内存缓冲区中的数据同步到事物日志中,同时同步到数据文件中。
1:每次提交时,log buffer同步到log file,同时进行log file到data file的同步操作;
2:每次提交时,log buffer同步到log file,但不会同时进行log file到data file的同步操作;
建议:关闭autocommit,而后将此值设置为1或2;
innodb_file_per_table:innodb的诸多高级特性都依赖于此参数;
innodb_read_io_threads:
innodb_write_io_threads
文件读写的io线程数;可根据并发量和CPU核心数适当调整;
innodb_open_files:innodb可打开的文件数量上限;
innodb_thread_concurrency=内核级可以使用的线程数,一般为cpu的2倍
skip_name_resolve:
max_connections:
5、表分区:
表分区可以提高查询和写操作的效率,对表进行分区后表结构文件还是一个,但表空间文件会变成多个,查询或更改数据时只需要在表的分区内进行就可以,而不必查询整张表,大大提高效率,使每个分区单独管理、单独使用

根据范围划分:
MariaDB [mydb]> CREATE TABLE students (id INT, name VARCHAR(100), age TINYINT UNSIGNED NOT NULL, gender ENUM('F','M')) PARTITION BY range(age)(partition youngman values less than (40), partition middleman values less than (70), partition oldman values less than maxvalue);
[root@node2 ~]#for i in {1..1000};do mysql -e "insert into mydb.students values($i,'stu$i',$[$[RANDOM%90]+18],'${gender[$[RANDOM%2]]}')";done
[root@node2 mydb]#ls   ---可以看到表结构文件只有一个,但表空间文件被分成了三个
db.opt  students.frm  students.par  students#P#middleman.ibd  students#P#oldman.ibd  students#P#youngman.ibd
根据hash划分:
MariaDB [mydb]> CREATE TABLE students (id INT, name CHAR(100) NOT NULL, age TINYINT UNSIGNED, gender ENUM('F','M')) PARTITION BY hash(id) PARTITIONS 5;   
[root@node2 mydb]#for i in {1..1000};do mysql -e "insert into mydb.students values($i,'stu$i',$[$[RANDOM%90]+18],'${gender[$[RANDOM%2]]}')";done
[root@node2 mydb]#ls
db.opt  students.frm  students.par  students#P#p0.ibd  students#P#p1.ibd  students#P#p2.ibd  students#P#p3.ibd  students#P#p4.ibd
指明分区的数量; 注意这里不能对名字进行哈希,因为名字的数据类型是char或者是varchar,会补空格,所以不是确定的,就无法进行哈希,哈希的值不是确定的
根据列表划分:
MariaDB [mydb]> CREATE TABLE students (id INT, name CHAR(100) NOT NULL, age TINYINT UNSIGNED, gender ENUM('F','M'), majorid TINYINT UNSIGNED NOT NULL) PARTITION BY list(majorid) (PARTITION p0 VALUES IN (1,4,7), PARTITION p1 VALUES IN (2,5,8), PARTITION p2 VALUES IN (3,6,9));
[root@node2 mydb]#for i in {1..1000};do mysql -e "insert into mydb.students values($i,'stu$i',$[$[RANDOM%90]+18],'${gender[$[RANDOM%2]]}',$[$[RANDOM%9]+1])";done
[root@node2 mydb]#ls
db.opt  students.frm  students.par  students#P#p0.ibd  students#P#p1.ibd  students#P#p2.ibd

7、PXC实现数据库的高可用

1、PXC介绍
Percona XtraDB Cluster(简称PXC集群)提供了MySQL高可用的一种实现方法。
1)集群是有节点组成的,推荐配置至少3个节点,但是也可以运行在2个节点上。
2)每个节点都是普通的mysql/percona服务器,可以将现有的数据库服务器组成集群,反之,也可以将集群拆分成单独的服务器。
3)每个节点都包含完整的数据副本。
PXC集群主要由两部分组成:Percona Server with XtraDB和Write Set Replication patches(使用了Galera library,一个通用的用于事务型应用的同步、多主复制插件)。
2、PXC特性
1)同步复制,事务要么在所有节点提交或不提交。
2)多主复制,可以在任意节点进行写操作。
3)在从服务器上并行应用事件,真正意义上的并行复制。
4)节点自动配置,数据一致性,不再是异步复制。
5)同步时不依赖于事物日志和中继日志,也不依赖于mysql服务本身,是另外的一种同步方式,这种方式无论在哪台服务器上写,都会进行同步,是多主模型。
PXC最大的优势:强一致性、无同步延迟

你可能感兴趣的:(11月13日mysql进阶3 mysql半同步复制、读写分离和主节点的高可用)