zoukankan      html  css  js  c++  java
  • mysql安装

    MySQL日志及主从复制实现

    阅读(558)

    一:MySQL是一个关系型数据库管理系统,最早由瑞典MySQL AB 公司发,后在2008年1月16号被Sun公司用10亿美金收购,但好景不长,2010年4月20日oracle用74亿美金收购了Sun,因此到目前MySQL属于 Oracle旗下产品。MySQL 最流行的关系型数据库管理系统,在 WEB 应用方面MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一,MySQL是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。
    MySQL所使用的 SQL 语言是用于访问数据库的最常用标准化语言。MySQL 软件采用了双授权政策,它分为社区版和商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择 MySQL 作为网站数据库,由于其社区版的性能卓越,搭配 PHP 和 Apache 可组成良好的开发环境。

    1.1:MySQL主从复制过程:

        MySQL主从同步一共需要三个线程的操作,主MySQL有一个IO线程,从MySQL有一个IO线程和一个SQL线程, MySQL主从是实现MySQL高可用、数据备份、读写分离架构的一种最常见的解决方案,在绝大部分公司都有使用,要实现MySQL主从复制,必须要在Master打开binary log(bin-log)功能,因为整个MySQL的复制过程实际就是Slave从Master端获取响应的二进制日志,然后在Slave端顺序的执行日志中所记录的各种操作,二进制日志中几乎记录了出select以外的所有针对数据库的sql操作语句,具体的复制过程如下:

    1.1.1:Slave端的IO线程连接上Master,并向Master请求指定日志文件的指定位置(新部署的Master和Slave从最开始的日志)之后的日志。

    1.1.2:Master接收到来自Slave的IO线程请求,负责IO复制的IO线程根据Slave的请求信息读取相应的日志内容,然后将本地读取的bin-log的文件名、位置及指定位置之后的内容一起返回给Slave的IO线程处理。

    1.1.3:Slave的IO线程将接收到的信息依次添加到Slave端的relay-log文件的最末端,并将读取到的Master端的bin-log的文件名和位置记录到Master-info文件中,以便在下一次读取的时候能够清楚的告诉Master“我需要从哪个bin-log的哪个位置开始往后的日志内容请发给我”。

    1.1.4:Slave的sql线程检查到relay-log中新增了内容后,会马上将relay-log中的内容解析为在Master端真实执行时候的可执行命令,并顺序执行,从而保证对Slave的MySQL进行响应的增加或删除等操作,最终实现和Master数据保持一致。

    1.2:减少主从同步延时的方案:

    1.2.1:从库使用SSD硬盘,这样从库可以用最快的速度从主控同步数据

    1.2.2:尽量在主库使用避免大量的写入,可以使用其他非关系型数据库的尽量使用非关系型数据库

    1.2.3:主库和从库直接使用专用网络高速互联

    1.2.4:对于数据一致性要求比较严格的场景,就不查询从库,因为从库可能有数据未同步到数据

    1.2.5:读场景比较大的场景,可以使用多个从库,将读请求在各个slave服务器分解处理

    1.3:数据库延迟复制,即设置slave故意从master延迟同步一小时或其他指定时间差,用于解决一下三个问题:

    1.3.1:用于在数据库误操作之后快速的恢复数据,比如误删除表,那个这个延迟操作在延迟时间内从库的数据还没有发生变化,可以使用从库的数据进行恢复,然后再把一小时内的bin-log补写到Master即可完成数据的全部恢复。

    1.3.2:用来做延迟测试,比如做好的数据库读写分离,把从库作为读库,即测试主从数据延迟五分钟或指定的时候,业务会发生什么样的问题,即可以模拟数据库延迟指定时间的业务错误。

    1.3.3:用于老数据的查询,比如经常需要查看某天前的一个表或者字段的数值,你可能需要把备份恢复之后才能进行查看,但是如果有延迟从库,比如延迟一周,那么久可以解决这一的类似的业务需求场景。

    1.3.4:设置延迟复制,通过设置SLAVE上的MASTER TO MASTER_DELAY参数来实现:

    CHANGE MASTER TO MASTER_DELAY = N;

    N为多少秒,该语句设置从库延时N秒后再与主数据库进行同步复制

    1.3.5:具体MySQL延迟复制操作,登录到SLAVE之上进行操作:

    mysql> stop slave;
    mysql> CHANGE MASTER TO MASTER_DELAY = 600; 
    mysql> start  slave;
    mysql> SHOW SLAVE STATUS G;

    1.4:生产环境MySQL经验:

    1.4.1:生产应用MySQL用户,不允许执行delete,可以只授权给update、select、insert,可以把delete更改为update,将要删除的数据加一个字段标记为已删除,因此线上的业务可以不需要delete

    1.4.2:在有条件的情况下做一个延迟一小时等制定时间的从库

    1.4.3:所有DML操作之前必须备份

    1.4.4:规范开发在update数据库必须有两个脚本,如下:

    1.4.4.1:数据库修改脚本,修改数据库的脚本

    1.4.4.2:数据库回滚脚本,当数据更新失败的时候用于回滚

    1.5:DML操作备份脚本

    dml_backup.sh  stable_name  #输入表明即可备份表

    1.5.1:开启相关日志:

    [mysqld]
    socket=/var/lib/mysql/mysql.sock
    user=mysql
    symbolic-links=0
    datadir=/data/mysql
    innodb_file_per_table=1
    relay-log = /data/mysql
    server-id=20
    log-error= /data/mysql_error.txt #记录错误日志
    log-bin=/data/mysql/master-log  #MySQL的bin-log即二进制日志,记录二进制形式SQL语句、主从复制和增量备份使用
    general_log=ON #正常查询日志
    general_log_file=/data/general_mysql.log
    
    long_query_time=2 #慢查询日志配置
    slow_query_log=1
    slow_query_log_file= /data/slow_mysql.txt
    
    [client]
    port=3306
    socket=/var/lib/mysql/mysql.sock
    
    [mysqld_safe]
    log-error=/var/log/mysqld.log
    pid-file=/tmp/mysql.sock

    1.5.2:mysqlsla 工具使用:

    使用语法如下:
    # mysqlslap [options]
    常用参数 [options] 详细说明:
    –auto-generate-sql, -a 自动生成测试表和数据,表示用mysqlslap工具自己生成的SQL脚本来测试并发压力。
    –auto-generate-sql-load-type=type 测试语句的类型。代表要测试的环境是读操作还是写操作还是两者混合的。取值包括:read,key,write,update和mixed(默认)。
    –auto-generate-sql-add-auto-increment 代表对生成的表自动添加auto_increment列,从5.1.18版本开始支持。
    –number-char-cols=N, -x N 自动生成的测试表中包含多少个字符类型的列,默认1
    –number-int-cols=N, -y N 自动生成的测试表中包含多少个数字类型的列,默认1
    –number-of-queries=N 总的测试查询次数(并发客户数×每客户查询次数)
    –query=name,-q 使用自定义脚本执行测试,例如可以调用自定义的一个存储过程或者sql语句来执行测试。
    –create-schema 代表自定义的测试库名称,测试的schema,MySQL中schema也就是database。
    –commint=N 多少条DML后提交一次。
    –compress, -C 如果服务器和客户端支持都压缩,则压缩信息传递。
    –concurrency=N, -c N 表示并发量,也就是模拟多少个客户端同时执行select。可指定多个值,以逗号或者–delimiter参数指定的值做为分隔符。例如:–concurrency=100,200,500。
    –engine=engine_name, -e engine_name 代表要测试的引擎,可以有多个,用分隔符隔开。例如:–engines=myisam,innodb。
    –iterations=N, -i N 测试执行的迭代次数,代表要在不同并发环境下,各自运行测试多少次。
    –only-print 只打印测试语句而不实际执行。
    –detach=N 执行N条语句后断开重连。
    –debug-info, -T 打印内存和CPU的相关信息。

    说明:
    测试的过程需要生成测试表,插入测试数据,这个mysqlslap可以自动生成,默认生成一个mysqlslap的schema,如果已经存在则先删除。可以用–only-print来打印实际的测试过程,整个测试完成后不会在数据库中留下痕迹。
    各种测试参数实例(-p后面跟的是mysql的root密码):
    单线程测试。测试做了什么。
    # mysqlslap -a -uroot -p123456
    多线程测试。使用–concurrency来模拟并发连接。
    # mysqlslap -a -c 100 -uroot -p123456
    迭代测试。用于需要多次执行测试得到平均值。
    # mysqlslap -a -i 10 -uroot -p123456
    # mysqlslap —auto-generate-sql-add-autoincrement -a -uroot -p123456
    # mysqlslap -a –auto-generate-sql-load-type=read -uroot -p123456
    # mysqlslap -a –auto-generate-secondary-indexes=3 -uroot -p123456
    # mysqlslap -a –auto-generate-sql-write-number=1000 -uroot -p123456
    # mysqlslap –create-schema world -q “select count(*) from City” -uroot -p123456
    # mysqlslap -a -e innodb -uroot -p123456
    # mysqlslap -a –number-of-queries=10 -uroot -p123456
    测试同时不同的存储引擎的性能进行对比:
    # mysqlslap -a –concurrency=50,100 –number-of-queries 1000 –iterations=5 –engine=myisam,innodb –debug-info -uroot -p123456
    执行一次测试,分别50和100个并发,执行1000次总查询:
    # mysqlslap -a –concurrency=50,100 –number-of-queries 1000 –debug-info -uroot -p123456
    50和100个并发分别得到一次测试结果(Benchmark),并发数越多,执行完所有查询的时间越长。为了准确起见,可以多迭代测试几次:
    # mysqlslap -a –concurrency=50,100 –number-of-queries 1000 –iterations=5 –debug-info -uroot -p123456

    二:数据库主从同步实现:

    2.1:两台服务器分别安装MySQL,提前准备好安装包和my.conf文件,使用以下脚本自动安装:

    [root@sql-master mysql]# cat  mysql-install.sh 
    #!/bin/bash
    DIR=`pwd`
    NAME="mysql-5.6.34-linux-glibc2.5-x86_64.tar.gz"
    FULL_NAME=${DIR}/${NAME}
    DATA_DIR="/data/mysql"
    
    yum install vim gcc gcc-c++ wget autoconf  net-tools lrzsz iotop lsof iotop bash-completion -y
    yum install curl policycoreutils openssh-server openssh-clients postfix -y
    
    if [ -f ${FULL_NAME} ];then
        echo "安装文件存在"
    else
        echo "安装文件不存在"
        exit 3
    fi
    if [ -h /usr/local/mysql ];then
        echo "Mysql 已经安装"
        exit 3 
    else
        tar xvf ${FULL_NAME}   -C /usr/local/src
        ln -sv /usr/local/src/mysql-5.6.34-linux-glibc2.5-x86_64  /usr/local/mysql
        if id  mysql;then
            echo "mysql 用户已经存在,跳过创建用户过程"
        fi
            useradd  mysql  -s /sbin/nologin
        if  id  mysql;then
        	chown  -R mysql.mysql  /usr/local/mysql/* -R
            if [ ! -d  /data/mysql ];then
                mkdir -pv /data/mysql && chown  -R mysql.mysql  /data   -R
                /usr/local/mysql/scripts/mysql_install_db  --user=mysql --datadir=/data/mysql  --basedir=/usr/local/mysql/
    	    cp  /usr/local/src/mysql-5.6.34-linux-glibc2.5-x86_64/support-files/mysql.server /etc/init.d/mysqld
    	    chmod a+x /etc/init.d/mysqld
     	    cp ${DIR}/my.cnf   /etc/my.cnf
    	    ln -sv /usr/local/mysql/bin/mysql  /usr/bin/mysql
    	    /etc/init.d/mysqld start
    	else
                echo "MySQL数据目录已经存在,"
    			exit 3
    	fi
        fi
    fi

    1.2:更改Master和Slave的my.conf文件,主要将id改为不一样:

    1.2.1:Master的配置my.conf文件,更改完成重启MySQL服务:

    [root@sql-master ~]# cat /etc/my.cnf
    [mysqld]
    socket=/var/lib/mysql/mysql.sock
    user=mysql
    symbolic-links=0
    datadir=/data/mysql
    innodb_file_per_table=1
    server-id=10
    log-bin=/data/mysql/master-log
    
    [client]
    port=3306
    socket=/var/lib/mysql/mysql.sock
    
    [mysqld_safe]
    log-error=/var/log/mysqld.log
    pid-file=/tmp/mysql.sock

    1.2.2:Slave的my.cnf配置文件,更改完成重启MySQL服务:

    [root@sql-slave ~]# cat /etc/my.cnf
    [mysqld]
    socket=/var/lib/mysql/mysql.sock
    user=mysql
    symbolic-links=0
    datadir=/data/mysql
    innodb_file_per_table=1
    relay-log = /data/mysql #中级日志的路径
    server-id=20  #server id与Master不能一样
    
    [client]
    port=3306
    socket=/var/lib/mysql/mysql.sock
    
    [mysqld_safe]
    log-error=/var/log/mysqld.log
    pid-file=/tmp/mysql.sock

    1.2.3:在 Master生成简单数据:

    mysql> create database testdatabase; #创建库
    Query OK, 1 row affected (0.00 sec)
     
    mysql> use testdatabase; #切换库
    Database changed
    mysql> CREATE TABLE testtable (Id_P int,Name varchar(255),Address varchar(255),City varchar(255)); #创建表
    Query OK, 0 rows affected (0.47 sec)
    
    mysql> show tables; #查看表
    +------------------------+
    | Tables_in_testdatabase |
    +------------------------+
    | testtable              |
    +------------------------+
    1 row in set (0.01 sec)
    mysql> INSERT INTO testtable VALUES (1,"Jack","China","Beijing"); #插入数据
    Query OK, 1 row affected (0.00 sec)
    mysql> select * from  testtable; #插卡数据并验证
    +------+------+---------+---------+
    | Id_P | Name | Address | City    |
    +------+------+---------+---------+
    |    1 | Jack | China   | Beijing |
    +------+------+---------+---------+
    1 row in set (0.00 sec)

    1.2.4:创建同步账号:

    mysql>  GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'tom'@'192.168.10.%' IDENTIFIED BY '123456'; #授权tom从192.168.10.*使用密码123456同步数据
    Query OK, 0 rows affected (0.30 sec)

    1.2.5:Master导出数据、复制到Slave:

    [root@sql-master ~]# /usr/local/mysql/bin/mysqldump   --all-databases  --single_transaction --flush-logs --master-data=2 --lock-tables > /backup.sql
    [root@sql-master ~]# scp /backup.sql  192.168.10.102:/opt/
    root@192.168.10.102's password: 
    backup.sql                                                       100%  637KB 636.7KB/s   00:00

    1.2.6:Slave将sql文件导入并记录Master的日志文件名称和要同步的位置:

    [root@sql-slave ~]# /usr/local/mysql/bin/mysql < /opt/backup.sql

    1.2.7:在Slave配置从Master同步并设置Slave开启 只读:

    mysql> CHANGE MASTER TO    MASTER_HOST='192.168.10.101',MASTER_USER='tom',MASTER_PASSWORD='123456',MASTER_LOG_FILE='master-log.000006',MASTER_LOG_POS=120;
    Query OK, 0 rows affected, 2 warnings (0.01 sec)
    
    mysql> start slave;
    Query OK, 0 rows affected (0.00 sec)
    mysql> show global variables like "%read_only%";
    +------------------+-------+
    | Variable_name    | Value |
    +------------------+-------+
    | innodb_read_only | OFF   |
    | read_only        | OFF   |
    | tx_read_only     | OFF   |
    +------------------+-------+
    3 rows in set (0.00 sec)
    
    mysql>  set global read_only=1; #开启只读模式,只读模式仅对普通用户生效,对root不生效
    Query OK, 0 rows affected (0.00 sec)
    
    mysql>  show global variables like "%read_only%"; #验证是否生效
    +------------------+-------+
    | Variable_name    | Value |
    +------------------+-------+
    | innodb_read_only | OFF   |
    | read_only        | ON    |
    | tx_read_only     | OFF   |
    +------------------+-------+
    3 rows in set (0.00 sec)

    1.2.8:验证Slave的IO线程与SQL线程是OK的:

    mysql> show slave statusG;
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 192.168.10.101
                      Master_User: tom
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: master-log.000006
              Read_Master_Log_Pos: 120
                   Relay_Log_File: mysql.000002
                    Relay_Log_Pos: 284
            Relay_Master_Log_File: master-log.000006
                 Slave_IO_Running: Yes #这两个线程状态必须为YES才表示同步是成功的
                Slave_SQL_Running: Yes
                  Replicate_Do_DB: 
              Replicate_Ignore_DB: 
               Replicate_Do_Table: 
           Replicate_Ignore_Table: 
          Replicate_Wild_Do_Table: 
      Replicate_Wild_Ignore_Table: 
                       Last_Errno: 0
                       Last_Error: 
                     Skip_Counter: 0
              Exec_Master_Log_Pos: 120
                  Relay_Log_Space: 447
                  Until_Condition: None
                   Until_Log_File: 
                    Until_Log_Pos: 0
               Master_SSL_Allowed: No
               Master_SSL_CA_File: 
               Master_SSL_CA_Path: 
                  Master_SSL_Cert: 
                Master_SSL_Cipher: 
                   Master_SSL_Key: 
            Seconds_Behind_Master: 0 #表示从Master收到的bin-log到当前的同步位置差多少秒,不是严格意义的主从差多少秒,因为Master的bin-log更新以后可能还没有同步到Slave
    Master_SSL_Verify_Server_Cert: No
                    Last_IO_Errno: 0
                    Last_IO_Error: 
                   Last_SQL_Errno: 0
                   Last_SQL_Error: 
      Replicate_Ignore_Server_Ids: 
                 Master_Server_Id: 10
                      Master_UUID: 003e966d-de3e-11e6-bc0f-000c2944baf2
                 Master_Info_File: /data/mysql/master.info
                        SQL_Delay: 0
              SQL_Remaining_Delay: NULL
          Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
               Master_Retry_Count: 86400
                      Master_Bind: 
          Last_IO_Error_Timestamp: 
         Last_SQL_Error_Timestamp: 
                   Master_SSL_Crl: 
               Master_SSL_Crlpath: 
               Retrieved_Gtid_Set: 
                Executed_Gtid_Set: 
                    Auto_Position: 0
    1 row in set (0.00 sec)

    1.2.9:关于Master_Info_File:

    记录了MySQL Master的IP地址、同步使用的用户名和密码、MySQL端口、bin-log日志文件名等信息:

    [root@sql-slave ~]# cat  /data/mysql/master.info
    23
    master-log.000006 #Master bin-log的文件名
    392    #Master的Position位置 
    192.168.10.101 #Master地址
    tom #同步用户
    123456  #密码
    3306 #端口
    60
    0
    
    0
    1800.000
    
    0
    003e966d-de3e-11e6-bc0f-000c2944baf2
    86400
    
    0

    1.2.10:Master信息如下:

    mysql> show master status;
    +-------------------+----------+--------------+------------------+-------------------+
    | File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
    +-------------------+----------+--------------+------------------+-------------------+
    | master-log.000006 |      392 |              |                  |                   |
    +-------------------+----------+--------------+------------------+-------------------+

    1.2.11:

    为了保证主从同步可以一直进行,在slave库上要保证具有super权限的root等用户只能在本地登录,不会发生数据变化,其他远程连接的应用用户只按需分配为select,insert,update,delete等权限,保证没有super权限,则只需要将salve设定“read_only=1”模式,即可保证主从同步,又可以实现从库只读。

    1.3:在Master 新插入数据,验证是否回同步到Slave:

    1.3.1:在Master插入数据:

    mysql> use testdatabase;
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A
    
    Database changed
    mysql> INSERT INTO testtable VALUES (2,"tom","China","Beijing");
    Query OK, 1 row affected (0.00 sec)

    1.3.2:在Slave验证数是否同步完成:

    1.4:MySQL主从同步状态和监控脚本:

    1.4.1:脚本内容:

    [root@sql-slave ~]# cat mysql_monitor.sh 
    #!/bin/bash
    Seconds_Behind_Master(){
    	NUM=`mysql -uroot -hlocalhost   -e "show slave statusG;"  | grep "Seconds_Behind_Master:" | awk -F: '{print $2}'`
    	echo $NUM
    }
    
    master_slave_check(){
    NUM1=`mysql -uroot -hlocalhost   -e "show slave statusG;"  | grep "Slave_IO_Running" | awk -F:  '{print $2}' | sed 's/^[ 	]*//g'`
    #echo $NUM1
    NUM2=`mysql -uroot -hlocalhost   -e "show slave statusG;"  | grep "Slave_SQL_Running:" | awk -F:  '{print $2}' | sed 's/^[ 	]*//g'`
    #echo $NUM2
    if test $NUM1 == "Yes" &&  test $NUM2 == "Yes";then
        echo 50
    else
        echo 100
    fi
    }
    
    main(){
        case $1 in
            Seconds_Behind_Master)
               Seconds_Behind_Master;
               ;;
    	master_slave_check)
    	   master_slave_check
    	   ;;
        esac
    }
    main $1

    1.4.2:执行结果:

    1.4.3:zabbix添加主从同步状态监控并报警:

    1.4.4:zabbix添加主从同步延迟并报警:

  • 相关阅读:
    sql中的不常见查询
    sql中的常见报错;
    wcf_first
    均方值-数学期望-方差
    转:模块度(Modularity)与Fast Newman算法讲解与代码实现
    转:社区发现评估指标-NMI
    转:模块度(Modularity)与Fast Newman算法讲解与代码实现
    转:聚类评价指标
    转:聚类︱python实现 六大 分群质量评估指标(兰德系数、互信息、轮廓系数)
    转:用K-Means聚类分析做客户分群
  • 原文地址:https://www.cnblogs.com/you0329/p/8590859.html
Copyright © 2011-2022 走看看