RDBMS:关系型数据库管理系统

       C/S:通过专有协议

       关系模型:表(行,列),二维关系;

       范式:第一范式、第二范式、第三范式(在之前的博客中已经做过说明)

       关系运算:

              选择      投影

       数据库:表,索引,视图(虚表)

              SQL:Structure Query Language

                     DDL,DML

                     编程接口:

                            存储过程

                            存储函数

                            触发器

                            事件调度器

                            过程式编程:选择、循坏

       三层模型:

              物理层  逻辑层  视图层

       解决方案:

              Oracle, Sybase, Infomix, DB2

              MySQL, MariaDB, PostgreSQL, SQLite

MariaDB

       插件式存储引擎

       单进程多线程

              连接线程

              守护线程

配置文件:集中式的配置,能够为mysql的各应用程序提供配置信息

       [mysqld]

       [mysqld_safe]

       [mysqld_multi]

       [server]

       [mysql]

       [mysqldump]

       [client]

启动查找路径:/etc/my.cnf à /etc/mysql/my.cnf à $MYSQL_HOME/my.cnf à --default-extra-file=/path/to/somedir/my.cnf à ~/.my.cnf

安装方法:

       os vendor:rpm

       MYSQL

              rpm

              展开可用

              源码

安装后的设定:

1)      为所有root用户设定密码;

mysql>SET PASSWORD FOR

mysql> update mysql.user SET password=PASSWORD(‘your_pass’) WHERE clause

#mysqladmin

2)      删除所有匿名用户

Mysql>DROP USER ‘’@’localhost’

上述两步骤可运行命令:mysql_secure_installation

3)      建议关闭主机名反解功能;

skip_name_resolve = ON

 

mysql --> mysqld

客户端程序:

       mysql:交互式的CLI工具;

mysqldump:备份工具,基于mysql协议向mysqld发起查询请求,并将查得的所有数据转换成insert等写操作语句保存文本文件中;

mysqladmin:基于mysql协议管理mysqld;

mysqlimport:数据导入工具;

 

非客户端类的管理工具:

       myisamchk,myisampack

 

如何获取程序默认使用的配置;

       mysql --print-defaults

       mysqld --print-defaults

 

客户端类应用程序的可用选项:

       -u, --user=   

       -h, --host=   

       -p, --passowrd=  

       -P, --port=   

       --protocol=

       -S, --socket=

       -D, --database=

       -C, --compress

 

       mysql -e "SQL"

 

mysql的使用模式:

       交互模式:

              可运行命令有两类:

                     客户端命令:

                            \h,help

                     服务器端命令:

                            SQL,需要语句结束符(冒号;)

       脚本模式:

              # mysql -uUSERNAME -hHOST -pPASSWORD < /path/from/somefile.sql

              mysql> source /path/from/somefile.sql

 

服务器端(msyqld):工作特性有多种定义方式

       命令行选项

       配置文件参数

              获取可用参数列表:

                     mysqld --help –verbose

       获取运行中的mysql进程使用各服务器参数及其值;

              mysql> SHOW GLOBAL VARIABLES;

              mysql> SHOW [SESSION] VARIABLES;

注意:其中有些参数支持运行时修改,会立即生效;有些参数不支持,且只能通过修改配置文件,并重启服务器程序生效;

    有些参数的作用域是全局的,且不可改变;有些可以为每一个用户提供单独的配置;

       修改服务器变量的值:

              mysql> help SET

                                                           

              全局:

                     mysql> SET GLOBAL system_var_name=value

                     mysql> SET @@global.system_var_name=value

              会话:

                     mysql> SET [SESSION] system_var_name=value;

                     mysql> SET @@[session.]system_var_name=value;

       状态变量:用于保存mysqld运行中的统计数据的变量;

              mysql> SHOW GLOBAL STATUS

              mysql> SHOW [SESSION] STATUS

                  

SQL:ANSI SQL

       SQL-86, SQL-89, SQL-92, SQL-99, SQL-03

 

MYSQL数据类型:

       字符型

       数值型

       日期时间型

       內建类型

 

       字符型:

              CHAR, BINARY:定长数据类型;

              VARCHAR, VARBINARY:变长数据类型;需要结束符;

              TEXT:TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT

              BLOB: TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB

              ENUM, SET

       字符型修饰符:

              NOT NULL:非空约束;

              NULL

              DEFAULT ‘STRING’:指明默认值;

              CHARACTER SET ‘’:使用的字符集;

              COLLATION:使用的排序规则;

             

              mysql > SHOW CHARACTER SET

                  

              msyql> SHOW COLLATION;

                  

       数值型:

              精确数值型:

                     整型:TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT

                     十进制型:DECIMAL

              近似数值型

                     浮点型:

                            FLOAT

                            DOUBLE

                     BIT

       整型数据修饰符:

              NOT NULL

              NULL

              DEFAULT NUMBER

              AUTO_INCREMENT:

                     UNSIGNED

                     PRIMARY KEY|UNIQUE KEY

                     NOT NULL

                    mysql> SELECT LAST_INSERT_ID();

                        

       日期时间型:

              DATE

              TIME

              DATETIME

              TIMESTAMP

              YEAR(2), YEAR(4)

       日期时间型修饰符:

              NOT NULL

              NULL

              DEFAULT

       內建类型SET和ENUM的修饰符:

              NOT NULL

              NULL

              DEFAULT

 

SQL MODE:定义mysqld对约束等的响应行为;

       修改方式:

              mysql> SET GLOBAL sql_mode='MODE';

              mysql> SET @@global.sql_mode='MODE';

              需要修改权限:仅对修改后新创建的会话有效;对已经建立的会话无效;

              mysql> SET SESSION sql_mode='MODE';

              mysql> SET @@session.sql_mode='MODE';

       常用MODE:TRADITIONAL, STRICT_TRANS_TABLES, or STRICT_ALL_TABLES

       DDL:数据定义语言;

              CREATE,ALTER,DROP

              DB组件:数据库、表、索引、视图、用户、存储过程、存储函数、触发器、事件调度器等;

              CREATE相关的常用命令:

                     CREATE DATABASE

                       CREATE EVENT

                        CREATE FUNCTION

                        CREATE FUNCTION UDF

                        CREATE INDEX

                        CREATE PROCEDURE

                        CREATE SERVER

                        CREATE TABLE

                        CREATE TABLESPACE

                        CREATE TRIGGER

                        CREATE USER

                        CREATE VIEW

       DML:数据操作语言;

              INSERT,DELETE,UPDATE,SELECT

       数据库:

              CREATE,ALTER,DROP

                     {DATABASE|SCHEMA}

                     [IF EXISTS]

                     [IF NOT EXISTS]

       表:二维关系

              设计表:遵循规范;

              定义:字段,索引

                     字段:字段名,字段数据类型,修改符

                     约束,索引:应该创建在经常用作查询条件的字段上;

                            索引:实现级别在存储引擎;

                                   分类:

                                          稠密索引、稀疏索引;

                                          B+索引、hash索引、R树索引、FULLTEXT索引

                                          聚集索引、非聚集索引

                                          简单索引、组合索引

       创建表:CREATE TABLE

1)      直接创建;

2)      通过查询现存的表创建;新表会被直接插入查询而来的数据;

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name

   [(create_definition,...)]

   [table_options]

   [partition_options]

   select_statement

3)      通过复制现存的表的表结构创建;不复制数据;

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name { LIKE old_tbl_name | (LIKE old_tbl_name) }

       注意:Storage Engine是指表类型,也即在表创建时指明其使用的存储引擎;同一个库中表要使用同一种存储引擎类型;

      

查看表结构:

  DESCRIBE tb1_name

      

查看表状态信息:

  SHOW [FULL] TABLES [{FROM | IN} db_name] [LIKE 'pattern' | WHERE expr] 

修改表:ALTER TABLE

删除表:DROP TABLE

 

MYSQL数据文件类型:

       数据文件、索引文件

       重做日志、撤销日志、二进制日志、错误日志、查询日志、慢查询日志、中继日志;

DDL&&DML

       索引管理:

              按特定数据结构存储的数据;

       索引类型:

              聚集索引、非聚集索引:数据是否与索引存储在一起;

              主键索引、辅助索引

              稠密索引、稀疏索引:是否索引了每一个数据项;

              B+ TREE、HASH、R TREE

              简单索引、组合索引

              左前缀索引;

              覆盖索引;

       管理索引的途径:

              创建索引:创建表时指定:CREATE INDEX

              创建或删除索引:修改表的命令

              删除索引:DROP INDEX

       查看表上的索引:

              SHOW {INDEX | INDEXES | KEYS}

                                       {FROM | IN} tbl_name

                                       [{FROM | IN} db_name]

                                       [WHERE expr]

             

视图:VIEW

       虚表

       创建方法:

              CREATE VIEW view_name [(column_list)] AS select_statement  [WITH [CASCADED | LOCAL] CHECK OPTION]

       删除视图:

              DROP VIEW [IF EXISTS] view_name [, view_name] ...[RESTRICT | CASCADE]

       视图中的数据事实上存储于“基表”中,因此,其修改操作也会针对基表实现;其修改操作受基表限制;

 

DML

       INSERT,DELETE,UPDATE,SELECT

       INSERT

              一次插入一行或多行数据;

              INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]

                         [INTO] tbl_name [(col_name,...)]

                         {VALUES | VALUE} ({expr | DEFAULT},...),(...),...

                         [ ON DUPLICATE KEY UPDATE

                           col_name=expr

                             [, col_name=expr] ... ]

              INSERT tbl_name [(col1,...)] VALUES (val1,...), (val21,...)

             

       UPDATE

              UPDATE [LOW_PRIORITY] [IGNORE] table_reference

                     SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...

                     [WHERE where_condition]

                     [ORDER BY ...]

                     [LIMIT row_count]

              注意:一定要有限制条件,否则将修改所有行的指定字段;

                     限制条件:

                            WHERE

                            LIMIT

       SELECT

              Query Cache

              查询执行路径中的组件:查询缓存、解析器、预处理器、优化器、查询执行引擎、存储引擎;

              SELECT语句的执行流程:

                     FROM Clause --> WHERE Clause --> GROUP BY --> HAVING Clause --> ORDER BY --> SELECT --> LIMIT

              单表查询:

                     SELECT

                                [ALL | DISTINCT | DISTINCTROW ]

                                  [SQL_CACHE | SQL_NO_CACHE]

                                select_expr [, select_expr ...]

                                [FROM table_references

                                [WHERE where_condition]

                                [GROUP BY {col_name | expr | position}

                                  [ASC | DESC], ... [WITH ROLLUP]]

                                [HAVING where_condition]

                                [ORDER BY {col_name | expr | position}

                                  [ASC | DESC], ...]

                                [LIMIT {[offset,] row_count | row_count OFFSET offset}]

                                [FOR UPDATE | LOCK IN SHARE MODE]

                    

                            DISTINCT:数据去重;

                            SQL_CACHE:显示指定存储查询结果于缓存之中;

                            SQL_NO_CACHE:显示查询结果不予缓存;

             

query_cache_type的值为'ON'时,查询缓存功能打开;SELECT的结果符合缓存条件即会缓存,否则,不予缓存;显式指定SQL_NO_CACHE,不予缓存;

query_cache_type的值为'DEMAND'时,查询缓存功能按需进行;显式指定SQL_CACHE的SELECT语句才会缓存;其它均不予缓存;

                     字段显示可以使用别名:

                            col1 AS alias1, col2 AS alias2, ...

                     WHERE子句:指明过滤条件以实现“选择”的功能:

                            过滤条件:布尔型表达式;

                                   算术操作符:+, -, *, /, %

                                   比较操作符:=, !=, <>, <=>, >, >=, <, <=

 

                                   BETWEEN min_num AND max_num

                                   IN (element1, element2, ...)

                                   IS NULL

                                   IS NOT NULL

                                   LIKE:

                                          %: 任意长度的任意字符;

                                          _:任意单个字符;

                                   RLIKE

                                   REGEXP:匹配字符串可用正则表达式书写模式;

                     逻辑操作符:

                            NOT

                            AND

                            OR

                            XOR

                     GROUP:根据指定的条件把查询结果进行“分组”以用于做“聚合”运算:

                            avg(), max(), min(), count(), sum()

                            HAVING: 对分组聚合运算后的结果指定过滤条件;

                     ORDER BY: 根据指定的字段对查询结果进行排序;

                            升序:ASC

                                                降序:DESC 

                                    LIMIT [[offset,]row_count]:对查询的结果进行输出行数数量限制;

                                        对查询结果中的数据请求施加“锁”:

                                                        FOR UPDATE: 写锁,排他锁;

                                                        LOCK IN SHARE MODE: 读锁,共享锁

                        多表查询:

                                    交叉连接,笛卡尔乘积;

                                    内连接:

                                                等值连接:让表之间的字段以“等值”建立连接关系;

                                                不等值连接

                                                自然连接;

                                                    自连接;

                                    外连接:

                                                    左外连接:

                                                            FROM tb1 LEFT JOIN tb2 ON tb1.col=tb2.col

                                                    右外连接:

                                                            FROM tb1 RIGHT JOIN tb2 ON tb1.col=tb2.col

                        子查询:在查询语句嵌套着查询语句

                            基于某语句的查询结果再次进行查询

                            用在WHERE子句中的子查询:

1)      用于比较表达式中的子查询;子查询仅能返回单个值:

SELECT Name,Age FROM students WHERE Age>(SELECT avg(Age) FROM students);

2)      用于IN中的子查询:子查询应该单键查询并返回一个或多个值构成列表;

SELECT Name,Age FROM students WHERE Age IN (SELECT Age FROM teachers);

3)      用于EXISTS;

                            用于FROM子句中的子查询:

                                    使用格式:SELECT tb_alias.col1,... FROM (SELECT clause) AS tb_alias WHERE Clause;

                        联合查询:UNION将两外或多个返回值字段相同的查询的结果合并输出

                            SELECT Name,Age FROM students UNION SELECT Name,Age FROM teachers;

练习1:导入hellodb.sql生成数据库

    1)  在students表中,查询年龄大于25岁,且为男性的同学的名字和年龄;

        

    2)  以ClassID为分组依据,显示每组的平均年龄;

        

    3)  显示第2题中平均年龄大于30的分组及平均年龄;

        

    4)  显示以L开头的名字的同学的信息;

        

    5)  显示TeacherID非空的同学的相关信息;

        

    6)  以年龄排序后,显示年龄最大的前10位同学的信息;

        

    7)  查询年龄大于等于20岁,小于等于25岁的同学的信息,用三种方法;

        方法一:

            

        方法二:

                      

        方法三:

            

            

练习2:导入hellodb.sql,以下在students表上进行;

    1)  以ClassID分组,显示每班的同学的人数;

        

    2)  以Gender分组,显示其年龄之和;  

         

    3)  以ClassID分组,显示其平均年龄大于25的班级; 

            

    4)  以Gender分组,显示各组中年龄大于25的学员的年龄之和;

         

 

Mysql的用户和权限:

创建用户账号:

        CREATE USER 'username'@'host' IDENTIFIED BY 'your_password'

删除用户账号:

        DROP USER 'username'@'host';

查看用户获得的权限:

        SHOW GRANTS FOR 'username'@'host';

Mysql的权限级别:

        库级别

        表级别

        字段级别

        管理类

        程序类

 

管理类:

        CREATE TEMPORARY TABLES

CREATE USER

FILE

SUPER

SHOW DATABASES

RELOAD

SHUTDOWN

REPLICATION SLAVE

REPLICATION CLIENT

LOCK TABLES

PROCESS

 

Storage routine:存储例程

                                storage procedure

                                storage function

库和表级别:

ALTER

ALTER ROUTINE

CREATE

CREATE ROUTINE

CREATE VIEW

DROP

EXECUTE

INDEX

GRANT OPTION: 是否可以转授权限的权限;

SHOW VIEW

数据操作(表级别):

SELECT

INSERT

UPDATE

DELETE

 

字段级别:

SELECT(col1,...)

UPDATE(col1,...)

INSERT(col1,...)

 

所有权限:

ALL [PRIVILEGES]

用户重命名:RENAME USER

            RENAME USER old_user_name TO new_user_name

修改密码:

1)      SET PASSWORD FOR

2)      UPDATE mysql.user SET password=PASSWORD('your_password') WHERE clause;

3)      mysqladmin password

mysqladmin [OPTIONS] command command....

-u, -h, -p

 

忘记管理员密码的解决方法:

1)      启动mysqld进程时,为其使用:--skip-grant-tables --skip-networking

2)      使用UPDATE命令修改管理员密码;

3)      关闭mysqld进程,移除上面两个选项,重启mysqld;

mysql中的授权相关的表:

db、host、user

columns_priv、tables_priv, procs_priv

 

授权与取消授权:GRANT, REVOKE

GRANT priv1, priv2, ... ON [TABLE|FUNCTION|PROCEDURE] db_name.tb_name|routine TO 'username'@'host' [IDENTIFIED BY 'password'] [REQUIRE ssl_option] [WITH with_option]

GRANT OPTION

    | MAX_QUERIES_PER_HOUR count

| MAX_UPDATES_PER_HOUR count

| MAX_CONNECTIONS_PER_HOUR count

    | MAX_USER_CONNECTIONS count

REVOKE priv1,priv2,... ON [TABLE|FUNCTION|PROCEDURE] db_name.tb_name|routine FROM 'username'@'host',...;

 

Mysql cache

         SELECT --> QUERY CACHE --> PARSER --> OPTIMIZER --> EXECUTING ENGINE --> STORAGE ENGINE

         缓存:hit(命中),miss(未命中)

                    Key-value

                    衡量缓存的有效性:命中率,hit/(hit+miss)

                   次数;

       query_cache_type

              ON,OFF,DEMAND

             

       SQL_CACHE | SQL_NO_CACHE

              QUERY CACHE

                     Key:查询语句的hash码;

                     Value:查询语句的执行结果;

       什么样的语句不会缓存?

              查询语句中有不确定数据时不会缓存;

一般来讲,如果查询中包含用户自定义的函数(UDF)、存储函数、用户变量、临时表、mysql库中表、或者任何包含权限信息表,都不会缓存;

       缓存什么场景下比较有效?

              对于存在需要大量资源的查询非常适合启用缓存;

       与缓存功能相关的服务器变量:

             

              Query_cache_limit:mysql能够缓存的最大查询结果;如果某查询的结果大于此值,则不会被缓存;

              Query_cache_min_res_unit:查询缓存中分配内存的最小单位

                     计算公式:(query_cache_size-Qcache_free_memory)/Qcache_queries_in_cache

              Query_cache_size:查询缓存的总体可用空间;其必须是1024的倍数;

              Query_cache_wlock_incalidate:当其他会话锁定此次查询用到的资源时,是否不能再从缓存中返回数据;

      

与缓存相关的状态变量:

             

              Qcache_hits/Com_select

              衡量缓存是否足够有效的另一种思路:Qcache_hits/Qcache_inserts

                     如果此比值大于3:1,说明缓存也是有效的;如果高于10:1,相当理想;

              缓存优化的思路:

1)      批量写入比单次写入对缓存的影响要小很多;

2)      缓存空间不宜过大,大量缓存的同时失效会导致Mysql假死;

3)      必要时,使用SQL_CACHE或SQL_NO_CACHE手动控制缓存;

4)      对写密集型的应用场景,禁用缓存反而能提高性能;

碎片整理:FLUSH QUERY_CACHE

清空缓存:RESET QUERY_CACHE

 

Mysql的存储引擎

       表类型:

              CREATE TABLE ... ENGINE=

       InnoDB

              处理大量的短期事务:

              数据存储于“表空间”中;

1)      所有InnoDB表的数据和索引放置于同一个表空间中;

表空间文件:datadir定义的目录下;

     数据文件:ibddata1,ibddata2,…

2)      每个表单独使用一个表空间存储表的数据和索引;

innodb_file_per_table=ON

数据文件(存储数据和索引):tb1_name.ibd,

表格式定义:tb1_name.frm

              基于MVCC来支持高并发,支持所有的四个隔离级别,默认级别为REPEATABLE READ,间隙锁防止幻读;

              使用聚集索引

              支持“自适应hash索引”

              锁粒度:行级锁

      

              MariaDB(XtraDB (percona))

              数据存储:表空间

              并发:MVCC,间隙锁

              索引:聚集索引、辅助索引

              性能:预计操作、自适应hash、插入缓存区

              备份:支持热备(xtrabaup)

       MyISAM

              支持全文索引(FULLTEXT index)、压缩、空间函数(GIS);但不支持事务,且为表级锁;崩溃后无法恢复;

              适用场景:只读(或者写较少)、表较小(可以接受长时间进行修复操作)

                     Aria:crash-safe

              文件:

                     tb1_name.frm:表格式定义

                     tb1_name.MYD:数据文件

                     tb1_name.MYI:索引文件

              特性:

                     加锁和并发:表级锁

                     修复:手工或自动修复、但可能丢失数据

                     索引:非聚集索引

                     延迟更新索引键:

                     压缩表

              行格式:dynamic,fixed,compressed,compact,redundent

       其它的存储引擎:

              CSV:将普通的CSV(字段通过逗号分隔)作为MySQL表使用;

              MRG_MYISAM:将多个MyISAM表合并称为一个虚拟表;

              BLACKHOLE:类似于/dev/null,不真正存储任何数据;

              MEMORY:所有数据都保存于内存中,内存表;支持hash索引;表级锁;临时表;

              PERFORMANCE_SCHEMA伪存储引擎;

              ARCHIVE:只支持SELECT和INSERT操作;支持行级锁和专用缓存区;

FEDERATED:用于访问其它远程MySQL服务器的一个代理,它通过创建一个到远程MySQL服务器的客户端连接,并将查询传输到远程服务器进行,而后完成数据存取;

    在MariaDB的上实现是FederatedX

MariaDB支持的其它存储引擎:

    OQGraph

    SphinxSE

    TokuDB

    Cassandra

    CONNECT

            SQUENCE        

并发控制:

            锁:

                        读锁:共享锁

                        写锁:独占锁

            锁粒度:

                        表级锁;

                        行级锁

           

                        锁策略:在锁粒度及数据安全性寻求的平衡机制;每种存储引擎都可以自行实现其锁策略和锁粒度;

                                Mysql在服务器级也实现了锁,表级锁,用户可以显示请求;

1)      LOCAK TABLES  tbl_name [[AS] alias] lock_type  [, tbl_name [[AS] alias] lock_type] ...

lock_type

      READ [LOCAL] | [LOW_PRIORITY] WRITE

UNLOCK TABLES

2)      FLUSH TABLES tb_name[,...] [WITH READ LOCK] [FOR UPDATE]

3)      SELECT clase [FOR UPDATE] [WITH READ LOACK]

        分类:

                        隐式锁:由存储引擎自动施加锁;

                        显示锁:

 

Mysql事务:

        事务:一组原子性的SQL查询,或者说一个独立工作单元。

            事务日志:

        ACID测试:

            A:atomicity,原子性;整个事务中的所有操作要么全部成功执行,要么全部失败后回滚;

            C:consistency,一致性;数据库总是从一个一致性状态转换为另一个一致性状态;

            I:Isolation,隔离性;一个事物所做出的操作在提交之前,是不能为其它所见;隔离有多种隔离级别;

            D:durability:持久性,一旦事务提交,其所做的修改会永久保存于数据库中;

       

        事务:

            启动事务:START TRANSACTION

                                …

            结束事务:

1)      COMMIT:提交

2)      ROLLBACK:回滚

            注意:只有事务型存储引擎方能支持此操作;

            建议:显示请求和提交事务,而不要使用自动提交功能:

                        autocommit={1|0}

            事务支持savepoint

                        SAVEPOINT identifier

                        ROLLBACK [WORK] TO [SAVEPOINT] identifier

                        RELEASE SAVEPOINT identifier

            事务隔离级别:

                        READ UNCOMMITTED (读未提交)

                        READ COMMITTED (读提交)

                        REPEATABLE READ (可重读)

                        SERIALIZABILE (可串行化)

                        可能存在问题:

                                    脏读;

                                    不可重复读;

                                    幻读;

                                    加锁读;

                        tx_isolation:服务器变量,默认为REPEATABLE-READ;可在SESSION级进行修改;

                        SET tx_isolation=''

                                                READ-UNCOMMITTED

                                                READ-COMMITTED

                                                REPEATABLE-READ

                                                SERIALIZABLE

                        MVCC: 多版本并发控制

            死锁:

                        两个或多个事务在同一资源相互占用,并请求锁定对方占用的资源的状态;

            事务日志:

                        事务日志的写入类型为追加,因此其操作为“顺序IO”;此日志通常也被称为“预写式日志”;

 

MySQL中的索引:

       

        基本法则:索引应该构建在被用作查询条件的字段上;

 

        索引类型:

            B+ Tree索引:顺序存储,每一个叶子节点到根结点的距离是相同的;左前缀索引,适合查询范围类的数据;

 

                        可以使用B-Tree索引的查询类型:全键值、键值范围或键前缀查找;

                                                全值匹配:精确某个值, "Jinjiao King";

                                                匹配最左前缀:只精确匹配起头部分,"Jin%"

                                                匹配范围值:

                                                精确匹配某一列并范围匹配另一列:

                                                只访问索引的查询

 

                        不适合使用B-Tree索引的场景:

                                                如果不从最左列开始,索引无效; (Age,Name)

                                                不能跳过索引中的列;(StuID,Name,Age)

                                                如果查询中某个列是为范围查询,那么其右侧的列都无法再使用索引优化查询;(StuID,Name)

 

            Hash索引:基于哈希表实现,特别适用于精确匹配索引中的所有列;

                        注意:只有Memory存储引擎支持显式hash索引;

 

                        适用场景:

                                                只支持等值比较查询,包括=, IN(), <=>;

 

                        不适合使用hash索引的场景:

                                                存储的非为值的顺序,因此,不适用于顺序查询;

                                                不支持模糊匹配;

 

            空间索引(R-Tree):

                        MyISAM支持空间索引;

 

            全文索引(FULLTEXT):

                        在文本中查找关键词;

 

            索引优点:

                        索引可以降低服务需要扫描的数据量,减少了IO次数;

                        索引可以帮助服务器避免排序和使用临时表;

                        索引可以帮助将随机I/O转为顺序I/O;

 

            高性能索引策略:

                        独立使用列,尽量避免其参与运算;

                        左前缀索引:索引构建于字段的左侧的多少个字符,要通过索引选择性来评估

                                                索引选择性:不重复的索引值和数据表的记录总数的比值;

                        多列索引:

                                                AND操作时更适合使用多列索引;

                        选择合适的索引列次序:将选择性最高放左侧;

 

            冗余和重复索引:

                        不好的索引使用策略

 

通过EXPLAIN来分析索引的有效性:

        EXPLAIN SELECT clause

            获取查询执行计划信息,用来查看查询优化器如何执行查询

           

            输出:

                        id:当前查询语句中,每个SELECT语句的编号;

                                复杂类型的查询有三种:

                                        简单子查询;

                                        用于FROM中的子查询;

                                        联合查询:UNION;

                                注意:UNION查询的分析结果会出现一额外匿名临时表;

                        select_type:简单查询为SIMPLE;

                                复杂查询:

                                        SUBQUERY:简单子查询;

                                        DERIVED:用于FROM中的子查询;

                                        UNION:UNION语句的第一个之后的SELECT语句;

                                        UNION RESULT:匿名临时表;

                        table:SELECT语句关联到的表;

                        type:关联类型,或访问类型,即Mysql决定的如何去查询表中的行的方式;

                                ALL:全表扫描;

index:根据索引的次序进行全表扫描;如果在Extra列出现“using index”表示了是欧阳覆盖索引,而非全表扫描;

                                range:有范围限制的根据索引实现范围扫描,扫描位置始于索引中的某一点,结束于另一点;

                                ref:根据索引返回表中匹配某单个值的所有行;

                                eq_ref:仅返回一个行,但与需要额外与某个参考值做比较;

                                const, system: 直接返回单个行;

                        possible_keys:查询可能会用到的索引;

                        key: 查询中使用了的索引;

                        key_len: 在索引使用的字节数;

                        ref: 在利用key字段所表示的索引完成查询时所有的列或某常量值;

                        rows:MySQL估计为找所有的目标行而需要读取的行数;

                        Extra:额外信息

                                Using index:MySQL将会使用覆盖索引,以避免访问表;

                                Using where:MySQL服务器将在存储引擎检索后,再进行一次过滤;

                                Using temporary:MySQL对结果排序时会使用临时表

                                Using filesort:对结果使用一个外部索引排序;

 

Mysql日志                                  

1.      查询日志:

log_output = {TABLE|FILE|NONE}

  log_output = TABLE,FILE

  FILE: gerenal_log

general_log = {ON|OFF}:是否启用查询日志;

general_log_file=www.log:当log_output有file类型时,日志信息的记录位置;

2.      慢查询日志;

    

slow_query_log={ON|OFF}:是否启用慢查询日志;

slow_query_log=/path/to/somefile:日志文件路径;

log_slow_filter=admin,filesort,filesort_on_disk,full_join,full_scan,query_cache,query_cache_miss,tmp_table,tmp_table_on_disk

log_slow_rate_limit =

log_slow_verbosity =

3.      错误日志;

Mysqld启动和关闭过程中输出的信息;

Mysqld运行中产生的错误信息;

Event scheduler运行一个event时产生的日志信息;

在主从复制架构中的从服务器上启动从服务器线程时产生的日志信息;

log_error = /path/to/somefile

log_warings={ON|OFF}:是否记录警告信息于错误日志中;

4.      二进制日志;

SHOW {BINARY|MASTER} LOGS:查看主服务器端处于由mysqld维护状态中的二进制日志文件;

SHOW BINLOG EVENTS [IN ‘log_name’] [FROM pos] [LIMIT [offset,] row_count]:显示指定的二进制日志文件中的相关事件;

日志记录格式:

      基于“语句”记录:statement

      基于“行”记录:row

      “混合”:mixed

二进制日志文件的构成:

      日志文件:文件名前缀.文件名后缀;

      索引文件:文件名前缀.index

服务器变量:

      log_bin=/path/to/somefile

      binlog_format =MIXED

      sql_log_bin=ON

      max_binlog_size=1073741824

              二进制日志文件的单文件上限;

      Max_binlog_cache_size=18446744073709547520

      max_binlog_stmt_cache_size = 18446744073709547520

      sync_binlog=0:设定多久同步一次二进制日志文件;0表示不同步;任何正值都表示记录多少个语句后同步一次;

二进制日志的格式:

      # at 19364

      #140829 15:50:07 server id 1  end_log_pos 19486   Query    thread_id=13      exec_time=0      error_code=0

      SET TIMESTAMP=1409298607/*!*/;

      GRANT SELECT ON tdb.* TO tuser@localhost/*!*/;

      # at 19486

     

      事件发生的日期和时间:(140829 15:50:07)

      事件发生在服务器的标识(server id)

      事件的结束位置:(end_log_pos 19486)

      事件的类型:(Query)

      事件发生时所在的服务器执行此事件的线程的id:(thread_id=13)

      语句的时间戳与将其写入二进制文件中的时间差:(exec_time=0)

      错误代码:(error_code=0)

      事件内容:(SET TIMESTAMP=1409298607/*!*/;GRANT SELECT ON tdb.* TO tuser@localhost)

      GTID事件专属:事件所属的全局事务的GTID:(GTID 0-1-2)

二进制日志的查看命令:

      Mysqlbinlog

              -j, --start-position=#:从指定的事件位置查看

              --stop-position=#:只显示到指定的时间位置;

 

              --start-datetime=name

              --stop-datetime=name

                      YYYY-MM-DD hh:mm:ss

5.      中继日志:

6.      事务日志(innodb存储引擎)

 

Mysql的备份和恢复

为什么要备份?

            灾难恢复:硬件故障、软件故障、自然灾害、******;误操作;测试;

要注意的要点:

            可容忍丢失多少数据;

            恢复需要在多长时间内完成;

            需要恢复什么;

备份类型:

            完全备份,部分备份;

                            部分备份:仅备份其中一张表或多张表;

            完全备份,增量备份,差异备份

                            增量备份:仅备份从上次完全备份或增量备份之后变化的数据部分;

            热备份、温度备份和冷备份;

                            热备份:在线备份,读写操作不受影响;

                            温备份:在线备份,读操作可继续进行,但写操作不允许;

                            冷备份:离线备份,数据库服务器离线,备份期间不能为业务提供读写服务;

 

                            MyISAM: 温备

                            InnoDB:热备

            物理备份和逻辑备份:

                            物理备份:直接复制数据文件进行的备份;

                            逻辑备份:从数据库中“导出”数据另存而进行的备份;

                            逻辑备份:

                                    与存储引擎无关;

规则备份时需要考虑的因素:

        持锁的时长;

        备份过程时长;

        备份负载

        恢复过程时长;

备份什么?

    数据、额外的数据(二进制日志和InnoDB的事务日志)、代码(存储过程和存储函数、触发器、时间调度器等)、服务器配置文件;

设计备份方案:

        完全备份+增量备份

备份工具:

            mysqldump:逻辑备份工具,适用于所有存储引擎,温备;完全备份,部分备份;对InnoDB存储引擎支持热备;

            cp,tar等文件系统工具:物理备份工具,适用于所有存储引擎;冷备:完全备份,部分备份;

            lvm2的快照:几乎热备;借助于文件系统工具实现物理备份;

            mysqlhotcopy:几乎冷备;仅适用于MyISAM存储引擎;

备份方案之备份工具的选择:

            mysqldump+binlog:

                mysqldump:完全备份,通过备份二进制日志实现增量备份;

            lvm2快照+binlog:几乎热备,物理备份;

            xtrabakup

                    对InnoDB:热备,支持完全备份

                    对MyISAM引擎:温备,只支持完全备份;

mysqldump工具介绍:

mysqldump:客户端,通过mysql协议连接至msyqld;

            -A,--all-databases

            MyISAM,InnoDB:温备

                    -x,--lock-all-tables:锁定所有表;

                    -l,--lock-tables:锁定备份的表;

            InnoDB

                    --single-transaction:启动一个大的单一事务实现备份;

            -B,--databases db_name1 db_name2 …:备份指定的数据库

            -C,--compress:压缩传输;

命令的语法格式:

            mysqldump [OPTIONS] database [tables]:备份单个库,或库指定的一个或多个表

            mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3…]:备份一个或多个库;

            mysqldump [OPTIONS] --all-databases [OPTIONS]:备份所有库

        其它选项:

                    -E,--events:备份指定库的时间调度器;

                    -R,--routines:备份存储过程和存储函数;

                    --triggers:备份触发器

 

                    --master-data[=#]

                            1:记录CHANGE MASTER TO 语句;此语句未被注释;

                            2:记录为注释语句;

                    --flush-logs,-F:锁定表之后执行flush logs命令;

        注意:二进制日志文件与数据文件不应该放置于同一磁盘;

 

几乎热备:lvm2快照,流程:

1.      请求锁定所有表;

mysql> FLUSH TABLES WITH READ LOCK;

2.      记录二进制日志文件及事件位置;

mysql> SHOW MASTER STATUS;

3.      创建快照;

lvcreate -L SIZE -s -p r -n NAME /dev/VG_NAME/LV_NAME

4.      释放锁;

mysql> UNLOCK TABLES

5.      挂载快照卷,复制数据进行备份;

cp, rsync, tar等命令复制数据;

6.      备份完成之后,删除快照卷;

 

演示:利用mysqldump工具备份;

1.      创建备份目录,存放备份文件;

    

2.      使用mysqldump工具,备份到备分目录;

    

Note:用--databases指明数据库时,备份的语句中有创建数据库的语句,如果不用--databases指明,则要手动创建;

3.      我们的策略是完全+增量+binlog备份方式,如果要使用binlog二进制日志重读,就要确定从备份的那一刻开始,binlog的起始文件位置,这是就哟啊使用--master-data=[#]选项;(确保二进制日志是开启的)

        1)      首先开启二进制日志;

            

        2)      备份;

            

        3)      查看二进制文件;

            

4.      修改数据库内容;

    

5.      删除hellodb数据库,模拟数据库崩溃,

    

6.      数据库恢复;

        1)      准备好要做时间点恢复的二进制文件;

            

        2)      查看二进制日志,把最后数据库删除操作的position截取掉,重定向一个新的文件中;

            

        3)      将二进制文件重定向新的文件;

            

        4)      恢复数据会执行大量的写操作,可以先关闭二进制日志文件;

        复制备份文件为.sql结尾;

            

        导入数据库;

          

        可以看出数据库恢复到了备份时的状态;

          

        5)      利用二进制文件,恢复到数据库崩溃之前的时间点;

          

        查看表中数据;

          

 

演示2:基于lvm2快照备份;

1.      创建分区;

    

2.      创建lvm

    

3.      创建mysql数据库目录,并将逻辑卷挂载至此目录;

    

4.      更改此目录的属组属主;

    

5.      修改mysql配置文件/etc/my.cnf,修改数据目录;

    

6.      开启服务,查看数据目录文件;

    

7.      先关闭数据库二进制日志进行数据写入;

    

查看导入的数据库;

    

8.      开启二进制日志,创建备份;

        1)      开启二进制日志;

            

        2)      请求锁定所有表,FLUSH TABLES为将所有内存的数据写入磁盘中;

            

        3)      记录二进制时间位置;

            

        4)      创建快照;

          

        5)      释放锁;

          

        6)      挂载快照卷并进行拷贝操作,文件属性需要保留;

            

        7)      备份完成后,删除快照;

          

9.      快照备份完成,对数据库进行一些修改,方便后面时间点还原;

    

10.  恢复;

        1)      手动模拟宕机并模拟数据库丢失;

         

        2)      复制备份文件到数据目录,登录数据库,还原到备份的状态;

         

        3)      利用二进制日志回滚还原;

过程跟上面利用mysqldump工具一样。

 

备份还原工具:Xtrabackup

        Percona,www.percona.com

        Innobackupex:客户端工具,以mysql协议连入mysqld,不支持离线备份

                --user=

                --password=

大概流程:

备份

        完全备份策略:完整备份+增量备份+二进制日志

        全量备份:# innobackupex --user=USER --password=PASSWORD  BACKUPDIR(生成的备份目录为BASEDIR)

        第一次增量备份:# innobackupex –user=USER –password=PASSWORD --incremental BACKUPDIR --incremental-basedir=BASEDIR(基于上一次 全量备份,生成的备份目录basedir为BASEDIR1)

        第二次增量备份:# innobackupex --user=root --password=taoxiu --incremental BACKUPDIR --incremental-basedir= BASEDIR1

准备:# innobackupex --apply-log --redo-only BASEDIR

# innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-1

# innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-2

恢复:

        # innobackupex –copy-back BASEDIR

改变属主属组:

        # cd /datadir

        # chown –R mysql.mysql ./*

NOTE:查看备份目录中的xtrabackup-binlog-info,可以查看最后一次增量备份的end-points;最后可通过二进制日志还原到机器崩溃时的状态;

注意:

1)      将数据和二进制文件放置于不同的设备;二进制日志也应该周期性地备份;

2)      将数据和备份分开存放,建议不在同一设备、同一主机、同一机房、同一地域;

3)      每次灾难恢复后都应该立即做一次完全备份;

4)      备份后的数据应该周期性地做还原测试;

从备份中恢复应该遵循的步骤:

1)      停止mysql服务器;

2)      记录服务器配置和文件权限;

3)      将备份恢复到mysql数据目录;此步骤依赖具体的备份工具;

4)      改变配置和文件权限;

5)      以限制方式启动mysql服务器;比如通过网络访问;

[mysqld]

skip-networking

socket=/tmp/mysql-recovery.sock

6)      载入额外的逻辑备份;而检查和重放二进制日志;

7)      检查已经还原的数据;

8)      以完全访问模式重启服务器;

 

mysql的复制架构:

系统扩展的方式:

        Scale up:向上扩展,垂直扩展;

        Scale out:向外扩展,水平扩展

        复制:水平扩展;

复制的功用:

         负载均衡

          数据分布

          备份

          高可用性

           MYSQL升级测试

复制架构的问题:

1.      主节点是单点;

2.      写操作无法有效均衡;

数据库扩展的思路;

     复制、切片

复制有三个步骤:

1.      在主库上启用二进制日志;

2.      备库从主库复制二进制日志,并保存至本地的中继日志中;

3.      备库从中继日志中读取事件并于本地执行一次;

复制总结:

Master:启用二进制日志,有唯一的server-id

      Binlog dump:将从服务的io thread发出读取二进制日志事件的请求对应的数据发送给对方;

Slave:启用中继日志,并关闭二进制日志(建议),有唯一的server-id

      Io-thread:想master请求二进制日志中的事件;

      SQL thread:从中继日志中读取事件并在本地执行;

复制工作架构:

从服务器:有且只能有一个主服务器;

       MariaDB 10:支持多源复制,即支持多个主服务器;

主服务器:可以有多从;

异步:从服务器的数据可能会落后于主服务器;

主从复制:

        版本:双版本一致,从节点版本低于主节点版本可能引起错误;

        复制起点:从哪儿复制?

1.      从0开始:适用于主从均为新建立的服务器;

2.      主服务已经运行一段时间且存不小的数据量;

完全备份主服务上的数据,并将数据恢复至从服务器;从服务器从备份时主服务器二进制日志所在位置;

         配置过程:

               Master

1.      启用二进制日志

2.      定义server-id

3.      创建有复制权限的账号;REPLICATION SLAVE, REPLICATION CLIENT

MariaDB [(none)]> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO repluser@'192.168.19.%' IDENTIFIED BY 'replp@ss';

               Slave

1.      启动中继日志;

2.      定义server-id

3.      使用有复制权限的账号连接master

4.      启动io  thread以及sql thread

               连接master:

                    

               查看从节点的状态信息

                     MariaDB [(none)]> SHOW SLAVE STATUS\G

主主:

互为主从:

1、数据不一致;

2、自动增长id

定义一个节点使用奇数id

auto_increment_offset=1

auto_increment_increment=2

定义另一个节点使用偶数id

auto_increment_offset=2

auto_increment_increment=2

                                                                                          

1) 各自使用不同的server id

2) 都启用binlog和relay log

3) 定义自动增长的id字段的增长方式

4) 都授权有复制权限的用户账号

5) 各自把对方指定为主服务器

GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'repluser'@'172.16.%.%' IDENTIFIED BY 'replpass';

 

复制中应该注意的问题:

1.      如何限制从服务器只读?

更改slave的全局服务器变量read-only为YES;

注意:此限制对于拥有super权限用户无效;

MariaDB [mysql]> SET GLOBAL read_only = 1;

或者更改配置文件:

   [mysqld]

read_only = 1

       阻止所有用户执行写操作:

              MariaDB [mysql]> flush tables with read lock;

2.      如何保证主从复制时的事务安全?

前提:mysql对二进制日志事件数据会有缓冲;

在master上设置参数:

Sync_binlog = 1

如果用到的为InnoDB存储引擎:

        Innodb_flush_logs_at_trx_commit

        Innodb_support-xa=on

        在slave节点:

                Skip_slave_start

         主节点:

                Sync_master_info = 1

          从节点:

                 Sync_relay_log = 1

                 Sync_relay_log_info = 1

3.      半同步复制:

半同步:master要等待一个从节点把数据完整复制过去;

由google贡献的补丁:以插件的方式存在;

Master

       MariaDB [testdb]> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';

       MariaDB [testdb]> SHOW GLOBAL VARIABLES LIKE '%semi%';

       MariaDB [testdb]> SET GLOBAL rpl_semi_sync_master_enabled=1;

       MariaDB [testdb]> SET GLOBAL rpl_semi_sync_master_timeout=1000;

Slave

       MariaDB [mysql]> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';

       MariaDB [mysql]> SHOW GLOBAL VARIABLES LIKE 'rpl_semi%';

       MariaDB [mysql]> SET GLOBAL rpl_semi_sync_slave_enabled = 1;

注意:只需要关闭并启动IO_THREAD即可;

主节点在联系从节点超时后,会自动降低为异步模式;

在主节点验证正是是否已经工作于半同步模式:

      SHOW GLOBAL STATUS LIKE '%semi%';

4.      复制过滤器

让slave仅复制有限的几个数据库,甚至于仅复制某数据库内有限的几张表的机制;

有两种方案:

1)      在主节点上过滤;

                在向二进制日志记录事件时,仅记录指定数据库的相关操作;

                binlog_do_db =     # 数据库白名单

                binlog_ignore_db =   # 数据库黑名单

2)      在从节点过滤;

                仅从中继日志中读取指定的数据库或表的相关事件并应用于本地:

                 问题:会造成网络带宽和磁盘IO的浪费;

                Replicate_Do_DB=

                Replicate_Ignore_DB=

                Replicate_Do_Table=

                Replicate_Ignore_Table=

                Replicate_Wild_Do_Table=

                Replicate_Wild_Ignore_Table=

5.      基于SSL的复制

前提:支持SSL

        1)      主服务器端配置证书和私钥,并创建一个要求必须使用SSL连接的复制账号(REQUIRE SSL);

        2)      SLAVE端连接master时,使用MASTER_SSL相关的选项来配置证书等信息;

6.      跟复制功能相关的文件;

Master.info:用于保存slave连接至master时的相关信息;

Relay_log.info:保存了当前slave节点上已经复制的当前二进制日志和本地relay log日志对应关系;

7.      复制的监控和维护

        1)      清理日志:PURGE

        2)      复制监控

            SHOW MASTER STATUS

            SHOW BINLOG EVENTS

            SHOW BINARY LOGS;

 

            SHOW SLAVE STATUS

        3)      如何判断slave是否落后于master

            Seconds_Behind_Master:0

        4)      如何确定主从节点数据是否一致?

            通过表自身的CHECKSUM检查;

            使用percona-tools中的pt_table-checksum

        5)      数据不一致的修复方法;

            重复复制;

 

演示:配置主从复制

实验环境:主节点为node1,从节点为node2;

1.      编辑主节点服务器mysql配置文件启用二进制日志,并启动mariadb服务;

    

2.      编辑从节点的配置文件启动中继日志,并启动mariadb服务;

    

3.      在主节点上创建并授权一个拥有复制权限的账号,并记录此时的二进制结束位置;

    

4.      在从节点上设置连接服务器的相关信息,并启动复制;

    

5.      开启复制线程,并查看slave状态;

    

    


6.      测试,在主节点庄创建数据库并查看二进制日志,观察从节点状态是否有延迟;

主节点上:

    

从节点上:

  

7.      如果从服务器需要只能读不能写,所有要设置其全局参数为只读;

    

 

演示:主主复制;

两个主节点分别为node1,node2;

1.      编辑node1配置文件,启动二进制日志和中继日志;

    

2.      配置node2配置文件,启动二进制日志和中继日志;

    

3.      分别启动两个节点的mariadb服务,并各自创建并授权一个有复制权限的账号;

Node1

Node2

4.      分别记录两个节点的二进制日志位置;

Node1

Node2

5.      分别在两个主节点上把另一个节点指定为主节点;

Node1

Node2

6.      测试,看看两节点能否相互复制;

        1)      在node1上创建数据库和表;

        

        2)      在node2上查看;

        

        3)      在node2上向表中插入数据;

        

        4)      在node1上查看,并在node1上插入数据;

        

        Node2上查看:

        

 

演示:半同步复制;

实验环境:主节点:node1,从节点:node2。主从复制模型;

1.      编辑主节点配置文件;

    

2.      编辑从节点配置文件;

    

3.      启动主节点mariadb服务,授权一个有复制权限的账号,并查看二进制文件位置;

    

4.      指定从节点的的连接主节点复制的相关信息,并启动复制功能;

    

5.      主从复制安装完之后,为了实现半同步复制,在主节点上安装支持同步复制的插件semisync_master.so,并启动该插件;

    

查看器状态为关闭状态,需要手动启动;

    

6.      在node2节点上安装插件;

    

查看其运行状态并手动开启;

    

7.      查看同步复制的状态;

    

在从节点上关闭复制进程,再重新打开;

    

再次打开主节点查看同步复制状态;

    

MHA集群配置:

       MHA(master ha)是一款开源的mysql开可用程序,它为mysql主从复制架构提供了autom ating master failover功能。MHA在监控到master节点故障时,会提升其中拥有最新数据的slave节点成为新的master节点,在此期间,MHA会通过其它从节点获取额外信息来避免一致性方面的问题。MHA还提供了master节点的在线切换功能,即按需切换master/slave节点。

MHA服务有两种特色,MHA|Manager(管理节点)和MHA Node(数据节点);

       MHA Manager:通常单独部署在一台独立机器上管理多个master/slave集群,每个master/slave集群称作一个application;

MHA node:运行在每台mysql服务器上(master/slave/manager),它通过监控具备解析和清理logs功能的脚本来加快故障转移。

MHA架构图:

                                                     

MHA组件:

       Manager节点:

          -masterha_check_ssh:MHA依赖的SSH环境监测工具;

          -masterha_check_repl:mysql复制环境检测工具;

           -masterha_manager:MHA服务主程序;

           -masterha_check_status:MHA运行状态探测工具;

           -masterha_master_monitor:mysql master节点可用性检测工具;

           -masterha_master_switch:master节点切换工具;

-masterha_conf_host:添加或删除配置的节点;

-masterha_stop:关闭MHA服务的工具;

       Node节点:

-save_binary_logs:保存和复制master的二进制日志;

-apply_diff_relay_logs:识别差异的中继日志事件并应用于其它slave;

-filter_mysqlbinlog:去除不必要的ROLLBACK事件(MHA已不再使用这个工具);

-purge_relay_logs:清除中继日志(不会阻塞SQL线程)

      自定义扩展:

-secondary_check_script:通过多条网络路由检测master的可用性;

-master_ip_failover_script:更新application使用的masterip

-shutdown_script:强制关闭master节点;

-report_script:发送报告;

-init_conf_load_script:加载初始配置参数;

-master_ip_online_change_script:更新master节点的ip地址;

 

演示:MHA集群

1.      实验环境准备;

1)      各节点信息;

Node1:192.168.19.141                 MHA Manager

Node2:192.168.19.200                 Mariadb master

Node3:192.168.19.134                 Mysql slave

Node4:192.168.19.143                 Mysql slave

其中node2与node3作半同步复制,node2与node4作主从复制;

2)      在各节点的/etc/hosts文件配置内容中添加以下内容:

    

3)      各节点的mysql配置;

Master节点node2:

    

Slave节点node3配置;

    

Slave节点node4配置:

    

2.      配置主从复制

        1)      在node2节点上创建创建并授权一个拥有复制权限的账号,并记录此时二进制结束位置;

        

        2)      在node3节点上设置连接主服务器的相关信息,并启动复制;

        

        3)      在node3上开启复制线程,并查看状态;

        

        4)      在ndoe4节点上设置连接主节点node2相关信息,并启动复制线程;

        

3.      在所有mysql节点授权拥有管理权限的用户可在本地网络中有其他节点上远程访问,此时,我们只需要在主节点上运行即可,命令便可复制到其它节点;

    

Note:顺便增加主机名的权限,否则后期测试时可能会出错;

    

同时,在node3和node4上创建复制权限的账号;

    

4.      安装配置MHA;

        1)      准备基于ssh互相通信环境;

        MHA集群中的各节点彼此之间需要基于ssh互信通信,以实现远程控制及数据管理功能。简单起见,可在manager节点生成密钥对,并设置其可远程连接本地主机后,将死要文件及authorized_keys文件复制给余下的所有节点;

 

    以下操作在manager节点node1上操作:

        

        Node2上操作:

        

        Node3上操作:同node2一样将自己的公钥文件发给node2和node4;

        Node4上操作:将自己的公钥文件发给node2和node3;

 

        2)      安装MHA

        Manager节点:

        

        其它节点:

        

        3)      初始化MHA

        Manager节点需要为每一个监控的master/slave集群提供一个专用的配置文件,而所有的master/slave集群也可共享全局配置。全局配置文件默认为/etc/masterha_default.cnf,其为可选配置。这里我们自定一个集群配置文件/etc/masterha/mha1.cnf,配置内容如下:

        

        创建相关文件夹目录:

        

        检测各节点间ssh互信通信配置是否ok,最后一行出现All SSH connection tests passed successfully表示成功;

        

        检查管理的mysql复制集群的连接配置参数是否ok;

        

        启动MHA,并查看master节点状态:

        

        如果要听孩子MHA,需要使用masterha_stop命令;

        #masterha_stop --conf=/etc/masterha/mha1.cnf

        4)      测试故障转移;

a.       在master节点关闭mariadb服务;

#killall  -9 mysqld mysqld_safe

b.      在manager节点查看日志;

Note:故障转移完成后,manger将会自动停止,此时使用masterha_check_status命令检测将会遇到错误;

c.       提供新的从节点以修复集群;

原有master节点故障后,需要重新准备一个新的mysql节点,基于来自于master节点的备份恢复数据后,将其配置为新的master的从节点即可。注意,新加入的节点如果为新增节点,其ip地址要配置为原来master节点的IP,否则,还需要修改mha1.cnf中的响应server的ip;

5.      进一步工作;

        1)      提供额外检测机制,以免对master的监控做出误判;

        2)      在master节点上提供虚拟ip地址向外提供服务,以免master节点转换时,客户端请求无法正确送达;

        3)      进行故障转移时对原有master节点执行STONITH操作以避免脑裂;可通过指定shutdon_script实现;

        4)      必要时,进行在线master节点转换;